Commit 4e583ff9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - Various cleanups and fixes: xterm, serial line, time travel

 - Set ARCH_HAS_GCOV_PROFILE_ALL

* tag 'for-linus-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
  um: Fix out-of-bounds read in LDT setup
  um: chan_user: Fix winch_tramp() return value
  um: virtio_uml: Fix broken device handling in time-travel
  um: line: Use separate IRQs per line
  um: Enable ARCH_HAS_GCOV_PROFILE_ALL
  um: Use asm-generic/dma-mapping.h
  um: daemon: Make default socket configurable
  um: xterm: Make default terminal emulator configurable
parents a01fe7ec 2a4a62a1
...@@ -6,6 +6,7 @@ config UML ...@@ -6,6 +6,7 @@ config UML
bool bool
default y default y
select ARCH_EPHEMERAL_INODES select ARCH_EPHEMERAL_INODES
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV select ARCH_HAS_KCOV
select ARCH_HAS_STRNCPY_FROM_USER select ARCH_HAS_STRNCPY_FROM_USER
select ARCH_HAS_STRNLEN_USER select ARCH_HAS_STRNLEN_USER
......
...@@ -64,6 +64,13 @@ config XTERM_CHAN ...@@ -64,6 +64,13 @@ config XTERM_CHAN
its own xterm. its own xterm.
It is safe to say 'Y' here. It is safe to say 'Y' here.
config XTERM_CHAN_DEFAULT_EMULATOR
string "xterm channel default terminal emulator"
depends on XTERM_CHAN
default "xterm"
help
This option allows changing the default terminal emulator.
config NOCONFIG_CHAN config NOCONFIG_CHAN
bool bool
default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && NULL_CHAN) default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && NULL_CHAN)
...@@ -231,6 +238,14 @@ config UML_NET_DAEMON ...@@ -231,6 +238,14 @@ config UML_NET_DAEMON
If unsure, say N. If unsure, say N.
config UML_NET_DAEMON_DEFAULT_SOCK
string "Default socket for daemon transport"
default "/tmp/uml.ctl"
depends on UML_NET_DAEMON
help
This option allows setting the default socket for the daemon
transport, normally it defaults to /tmp/uml.ctl.
config UML_NET_VECTOR config UML_NET_VECTOR
bool "Vector I/O high performance network devices" bool "Vector I/O high performance network devices"
depends on UML_NET depends on UML_NET
......
...@@ -70,4 +70,6 @@ obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virt-pci.o ...@@ -70,4 +70,6 @@ obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virt-pci.o
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o vector_user.o USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o vector_user.o
CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH) CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH)
CFLAGS_xterm.o += '-DCONFIG_XTERM_CHAN_DEFAULT_EMULATOR="$(CONFIG_XTERM_CHAN_DEFAULT_EMULATOR)"'
include arch/um/scripts/Makefile.rules include arch/um/scripts/Makefile.rules
...@@ -133,7 +133,7 @@ static void line_timer_cb(struct work_struct *work) ...@@ -133,7 +133,7 @@ static void line_timer_cb(struct work_struct *work)
struct line *line = container_of(work, struct line, task.work); struct line *line = container_of(work, struct line, task.work);
if (!line->throttled) if (!line->throttled)
chan_interrupt(line, line->driver->read_irq); chan_interrupt(line, line->read_irq);
} }
int enable_chan(struct line *line) int enable_chan(struct line *line)
...@@ -195,9 +195,9 @@ void free_irqs(void) ...@@ -195,9 +195,9 @@ void free_irqs(void)
chan = list_entry(ele, struct chan, free_list); chan = list_entry(ele, struct chan, free_list);
if (chan->input && chan->enabled) if (chan->input && chan->enabled)
um_free_irq(chan->line->driver->read_irq, chan); um_free_irq(chan->line->read_irq, chan);
if (chan->output && chan->enabled) if (chan->output && chan->enabled)
um_free_irq(chan->line->driver->write_irq, chan); um_free_irq(chan->line->write_irq, chan);
chan->enabled = 0; chan->enabled = 0;
} }
} }
...@@ -215,9 +215,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq) ...@@ -215,9 +215,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
spin_unlock_irqrestore(&irqs_to_free_lock, flags); spin_unlock_irqrestore(&irqs_to_free_lock, flags);
} else { } else {
if (chan->input && chan->enabled) if (chan->input && chan->enabled)
um_free_irq(chan->line->driver->read_irq, chan); um_free_irq(chan->line->read_irq, chan);
if (chan->output && chan->enabled) if (chan->output && chan->enabled)
um_free_irq(chan->line->driver->write_irq, chan); um_free_irq(chan->line->write_irq, chan);
chan->enabled = 0; chan->enabled = 0;
} }
if (chan->ops->close != NULL) if (chan->ops->close != NULL)
......
...@@ -220,7 +220,7 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, ...@@ -220,7 +220,7 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
unsigned long *stack_out) unsigned long *stack_out)
{ {
struct winch_data data; struct winch_data data;
int fds[2], n, err; int fds[2], n, err, pid;
char c; char c;
err = os_pipe(fds, 1, 1); err = os_pipe(fds, 1, 1);
...@@ -238,8 +238,9 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, ...@@ -238,8 +238,9 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
* problem with /dev/net/tun, which if held open by this * problem with /dev/net/tun, which if held open by this
* thread, prevents the TUN/TAP device from being reused. * thread, prevents the TUN/TAP device from being reused.
*/ */
err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); pid = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out);
if (err < 0) { if (pid < 0) {
err = pid;
printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n", printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n",
-err); -err);
goto out_close; goto out_close;
...@@ -263,7 +264,7 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, ...@@ -263,7 +264,7 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
goto out_close; goto out_close;
} }
return err; return pid;
out_close: out_close:
close(fds[1]); close(fds[1]);
......
...@@ -65,7 +65,7 @@ static int daemon_setup(char *str, char **mac_out, void *data) ...@@ -65,7 +65,7 @@ static int daemon_setup(char *str, char **mac_out, void *data)
*init = ((struct daemon_init) *init = ((struct daemon_init)
{ .sock_type = "unix", { .sock_type = "unix",
.ctl_sock = "/tmp/uml.ctl" }); .ctl_sock = CONFIG_UML_NET_DAEMON_DEFAULT_SOCK });
remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
NULL); NULL);
......
...@@ -139,7 +139,7 @@ static int flush_buffer(struct line *line) ...@@ -139,7 +139,7 @@ static int flush_buffer(struct line *line)
count = line->buffer + LINE_BUFSIZE - line->head; count = line->buffer + LINE_BUFSIZE - line->head;
n = write_chan(line->chan_out, line->head, count, n = write_chan(line->chan_out, line->head, count,
line->driver->write_irq); line->write_irq);
if (n < 0) if (n < 0)
return n; return n;
if (n == count) { if (n == count) {
...@@ -156,7 +156,7 @@ static int flush_buffer(struct line *line) ...@@ -156,7 +156,7 @@ static int flush_buffer(struct line *line)
count = line->tail - line->head; count = line->tail - line->head;
n = write_chan(line->chan_out, line->head, count, n = write_chan(line->chan_out, line->head, count,
line->driver->write_irq); line->write_irq);
if (n < 0) if (n < 0)
return n; return n;
...@@ -195,7 +195,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) ...@@ -195,7 +195,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
ret = buffer_data(line, buf, len); ret = buffer_data(line, buf, len);
else { else {
n = write_chan(line->chan_out, buf, len, n = write_chan(line->chan_out, buf, len,
line->driver->write_irq); line->write_irq);
if (n < 0) { if (n < 0) {
ret = n; ret = n;
goto out_up; goto out_up;
...@@ -215,7 +215,7 @@ void line_throttle(struct tty_struct *tty) ...@@ -215,7 +215,7 @@ void line_throttle(struct tty_struct *tty)
{ {
struct line *line = tty->driver_data; struct line *line = tty->driver_data;
deactivate_chan(line->chan_in, line->driver->read_irq); deactivate_chan(line->chan_in, line->read_irq);
line->throttled = 1; line->throttled = 1;
} }
...@@ -224,7 +224,7 @@ void line_unthrottle(struct tty_struct *tty) ...@@ -224,7 +224,7 @@ void line_unthrottle(struct tty_struct *tty)
struct line *line = tty->driver_data; struct line *line = tty->driver_data;
line->throttled = 0; line->throttled = 0;
chan_interrupt(line, line->driver->read_irq); chan_interrupt(line, line->read_irq);
} }
static irqreturn_t line_write_interrupt(int irq, void *data) static irqreturn_t line_write_interrupt(int irq, void *data)
...@@ -260,19 +260,23 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) ...@@ -260,19 +260,23 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
int err; int err;
if (input) { if (input) {
err = um_request_irq(driver->read_irq, fd, IRQ_READ, err = um_request_irq(UM_IRQ_ALLOC, fd, IRQ_READ,
line_interrupt, IRQF_SHARED, line_interrupt, 0,
driver->read_irq_name, data); driver->read_irq_name, data);
if (err < 0) if (err < 0)
return err; return err;
line->read_irq = err;
} }
if (output) { if (output) {
err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, err = um_request_irq(UM_IRQ_ALLOC, fd, IRQ_WRITE,
line_write_interrupt, IRQF_SHARED, line_write_interrupt, 0,
driver->write_irq_name, data); driver->write_irq_name, data);
if (err < 0) if (err < 0)
return err; return err;
line->write_irq = err;
} }
return 0; return 0;
......
...@@ -23,9 +23,7 @@ struct line_driver { ...@@ -23,9 +23,7 @@ struct line_driver {
const short minor_start; const short minor_start;
const short type; const short type;
const short subtype; const short subtype;
const int read_irq;
const char *read_irq_name; const char *read_irq_name;
const int write_irq;
const char *write_irq_name; const char *write_irq_name;
struct mc_device mc; struct mc_device mc;
struct tty_driver *driver; struct tty_driver *driver;
...@@ -35,6 +33,8 @@ struct line { ...@@ -35,6 +33,8 @@ struct line {
struct tty_port port; struct tty_port port;
int valid; int valid;
int read_irq, write_irq;
char *init_str; char *init_str;
struct list_head chan_list; struct list_head chan_list;
struct chan *chan_in, *chan_out; struct chan *chan_in, *chan_out;
......
...@@ -47,9 +47,7 @@ static struct line_driver driver = { ...@@ -47,9 +47,7 @@ static struct line_driver driver = {
.minor_start = 64, .minor_start = 64,
.type = TTY_DRIVER_TYPE_SERIAL, .type = TTY_DRIVER_TYPE_SERIAL,
.subtype = 0, .subtype = 0,
.read_irq = SSL_IRQ,
.read_irq_name = "ssl", .read_irq_name = "ssl",
.write_irq = SSL_WRITE_IRQ,
.write_irq_name = "ssl-write", .write_irq_name = "ssl-write",
.mc = { .mc = {
.list = LIST_HEAD_INIT(driver.mc.list), .list = LIST_HEAD_INIT(driver.mc.list),
......
...@@ -53,9 +53,7 @@ static struct line_driver driver = { ...@@ -53,9 +53,7 @@ static struct line_driver driver = {
.minor_start = 0, .minor_start = 0,
.type = TTY_DRIVER_TYPE_CONSOLE, .type = TTY_DRIVER_TYPE_CONSOLE,
.subtype = SYSTEM_TYPE_CONSOLE, .subtype = SYSTEM_TYPE_CONSOLE,
.read_irq = CONSOLE_IRQ,
.read_irq_name = "console", .read_irq_name = "console",
.write_irq = CONSOLE_WRITE_IRQ,
.write_irq_name = "console-write", .write_irq_name = "console-write",
.mc = { .mc = {
.list = LIST_HEAD_INIT(driver.mc.list), .list = LIST_HEAD_INIT(driver.mc.list),
......
...@@ -63,6 +63,7 @@ struct virtio_uml_device { ...@@ -63,6 +63,7 @@ struct virtio_uml_device {
u8 config_changed_irq:1; u8 config_changed_irq:1;
uint64_t vq_irq_vq_map; uint64_t vq_irq_vq_map;
int recv_rc;
}; };
struct virtio_uml_vq_info { struct virtio_uml_vq_info {
...@@ -148,14 +149,6 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev, ...@@ -148,14 +149,6 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev,
rc = vhost_user_recv_header(fd, msg); rc = vhost_user_recv_header(fd, msg);
if (rc == -ECONNRESET && vu_dev->registered) {
struct virtio_uml_platform_data *pdata;
pdata = vu_dev->pdata;
virtio_break_device(&vu_dev->vdev);
schedule_work(&pdata->conn_broken_wk);
}
if (rc) if (rc)
return rc; return rc;
size = msg->header.size; size = msg->header.size;
...@@ -164,6 +157,21 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev, ...@@ -164,6 +157,21 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev,
return full_read(fd, &msg->payload, size, false); return full_read(fd, &msg->payload, size, false);
} }
static void vhost_user_check_reset(struct virtio_uml_device *vu_dev,
int rc)
{
struct virtio_uml_platform_data *pdata = vu_dev->pdata;
if (rc != -ECONNRESET)
return;
if (!vu_dev->registered)
return;
virtio_break_device(&vu_dev->vdev);
schedule_work(&pdata->conn_broken_wk);
}
static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev,
struct vhost_user_msg *msg, struct vhost_user_msg *msg,
size_t max_payload_size) size_t max_payload_size)
...@@ -171,8 +179,10 @@ static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, ...@@ -171,8 +179,10 @@ static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev,
int rc = vhost_user_recv(vu_dev, vu_dev->sock, msg, int rc = vhost_user_recv(vu_dev, vu_dev->sock, msg,
max_payload_size, true); max_payload_size, true);
if (rc) if (rc) {
vhost_user_check_reset(vu_dev, rc);
return rc; return rc;
}
if (msg->header.flags != (VHOST_USER_FLAG_REPLY | VHOST_USER_VERSION)) if (msg->header.flags != (VHOST_USER_FLAG_REPLY | VHOST_USER_VERSION))
return -EPROTO; return -EPROTO;
...@@ -369,6 +379,7 @@ static irqreturn_t vu_req_read_message(struct virtio_uml_device *vu_dev, ...@@ -369,6 +379,7 @@ static irqreturn_t vu_req_read_message(struct virtio_uml_device *vu_dev,
sizeof(msg.msg.payload) + sizeof(msg.msg.payload) +
sizeof(msg.extra_payload)); sizeof(msg.extra_payload));
vu_dev->recv_rc = rc;
if (rc) if (rc)
return IRQ_NONE; return IRQ_NONE;
...@@ -412,7 +423,9 @@ static irqreturn_t vu_req_interrupt(int irq, void *data) ...@@ -412,7 +423,9 @@ static irqreturn_t vu_req_interrupt(int irq, void *data)
if (!um_irq_timetravel_handler_used()) if (!um_irq_timetravel_handler_used())
ret = vu_req_read_message(vu_dev, NULL); ret = vu_req_read_message(vu_dev, NULL);
if (vu_dev->vq_irq_vq_map) { if (vu_dev->recv_rc) {
vhost_user_check_reset(vu_dev, vu_dev->recv_rc);
} else if (vu_dev->vq_irq_vq_map) {
struct virtqueue *vq; struct virtqueue *vq;
virtio_device_for_each_vq((&vu_dev->vdev), vq) { virtio_device_for_each_vq((&vu_dev->vdev), vq) {
......
...@@ -42,7 +42,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts) ...@@ -42,7 +42,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
} }
/* Only changed by xterm_setup, which is a setup */ /* Only changed by xterm_setup, which is a setup */
static char *terminal_emulator = "xterm"; static char *terminal_emulator = CONFIG_XTERM_CHAN_DEFAULT_EMULATOR;
static char *title_switch = "-T"; static char *title_switch = "-T";
static char *exec_switch = "-e"; static char *exec_switch = "-e";
...@@ -79,8 +79,9 @@ __uml_setup("xterm=", xterm_setup, ...@@ -79,8 +79,9 @@ __uml_setup("xterm=", xterm_setup,
" respectively. The title switch must have the form '<switch> title',\n" " respectively. The title switch must have the form '<switch> title',\n"
" not '<switch>=title'. Similarly, the exec switch must have the form\n" " not '<switch>=title'. Similarly, the exec switch must have the form\n"
" '<switch> command arg1 arg2 ...'.\n" " '<switch> command arg1 arg2 ...'.\n"
" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n" " The default values are 'xterm=" CONFIG_XTERM_CHAN_DEFAULT_EMULATOR
" are 'xterm=gnome-terminal,-t,-x'.\n\n" ",-T,-e'.\n"
" Values for gnome-terminal are 'xterm=gnome-terminal,-t,-x'.\n\n"
); );
static int xterm_open(int input, int output, int primary, void *d, static int xterm_open(int input, int output, int primary, void *d,
......
...@@ -4,6 +4,7 @@ generic-y += bug.h ...@@ -4,6 +4,7 @@ generic-y += bug.h
generic-y += compat.h generic-y += compat.h
generic-y += current.h generic-y += current.h
generic-y += device.h generic-y += device.h
generic-y += dma-mapping.h
generic-y += emergency-restart.h generic-y += emergency-restart.h
generic-y += exec.h generic-y += exec.h
generic-y += extable.h generic-y += extable.h
......
...@@ -4,19 +4,15 @@ ...@@ -4,19 +4,15 @@
#define TIMER_IRQ 0 #define TIMER_IRQ 0
#define UMN_IRQ 1 #define UMN_IRQ 1
#define CONSOLE_IRQ 2 #define UBD_IRQ 2
#define CONSOLE_WRITE_IRQ 3 #define UM_ETH_IRQ 3
#define UBD_IRQ 4 #define ACCEPT_IRQ 4
#define UM_ETH_IRQ 5 #define MCONSOLE_IRQ 5
#define SSL_IRQ 6 #define WINCH_IRQ 6
#define SSL_WRITE_IRQ 7 #define SIGIO_WRITE_IRQ 7
#define ACCEPT_IRQ 8 #define TELNETD_IRQ 8
#define MCONSOLE_IRQ 9 #define XTERM_IRQ 9
#define WINCH_IRQ 10 #define RANDOM_IRQ 10
#define SIGIO_WRITE_IRQ 11
#define TELNETD_IRQ 12
#define XTERM_IRQ 13
#define RANDOM_IRQ 14
#ifdef CONFIG_UML_NET_VECTOR #ifdef CONFIG_UML_NET_VECTOR
......
...@@ -23,9 +23,11 @@ static long write_ldt_entry(struct mm_id *mm_idp, int func, ...@@ -23,9 +23,11 @@ static long write_ldt_entry(struct mm_id *mm_idp, int func,
{ {
long res; long res;
void *stub_addr; void *stub_addr;
BUILD_BUG_ON(sizeof(*desc) % sizeof(long));
res = syscall_stub_data(mm_idp, (unsigned long *)desc, res = syscall_stub_data(mm_idp, (unsigned long *)desc,
(sizeof(*desc) + sizeof(long) - 1) & sizeof(*desc) / sizeof(long),
~(sizeof(long) - 1),
addr, &stub_addr); addr, &stub_addr);
if (!res) { if (!res) {
unsigned long args[] = { func, unsigned long args[] = { func,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment