From b21e332d24f91b0a401a2871aadbfec00e8ed9bc Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 15 Jul 2013 09:26:07 +0930 Subject: lguest: Point to the right directory for the lguest launcher The code was moved in 07fe9977b6234ede1bd29e10e0323e478860c871 but the comment was not updated. The reference in drivers/vhost/vhost.c is left alone as it is historic. Signed-off-by: Holger Hans Peter Freyther Signed-off-by: Rusty Russell diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 6a22c19..7c1fde5 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -7,8 +7,7 @@ * kernel and insert a module (lg.ko) which allows us to run other Linux * kernels the same way we'd run processes. We call the first kernel the Host, * and the others the Guests. The program which sets up and configures Guests - * (such as the example in Documentation/virtual/lguest/lguest.c) is called the - * Launcher. + * (such as the example in tools/lguest/lguest.c) is called the Launcher. * * Secondly, we only run specially modified Guests, not normal kernels: setting * CONFIG_LGUEST_GUEST to "y" compiles this file into the kernel so it knows -- cgit v0.10.2 From 504ce60f458b62fc00b44735704c5b77ec87ed5a Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 15 Jul 2013 09:27:07 +0930 Subject: virtio tools: add .gitignore Signed-off-by: Ramkumar Ramachandra Acked-by: Michael S. Tsirkin Signed-off-by: Rusty Russell diff --git a/tools/virtio/.gitignore b/tools/virtio/.gitignore new file mode 100644 index 0000000..1cfbb01 --- /dev/null +++ b/tools/virtio/.gitignore @@ -0,0 +1,3 @@ +*.d +virtio_test +vringh_test -- cgit v0.10.2 From 927cfb9788475abd5cf5e6566bb1cf46d29b0694 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 15 Jul 2013 10:50:13 +0930 Subject: tools/lguest: offer VIRTIO_F_ANY_LAYOUT for net device. We don't care about layout, so advertise that fact. Signed-off-by: Rusty Russell diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 68f67cf..32cf2ce 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c @@ -42,6 +42,10 @@ #include #include +#ifndef VIRTIO_F_ANY_LAYOUT +#define VIRTIO_F_ANY_LAYOUT 27 +#endif + /*L:110 * We can ignore the 43 include files we need for this program, but I do want * to draw attention to the use of kernel-style types. @@ -1544,6 +1548,8 @@ static void setup_tun_net(char *arg) add_feature(dev, VIRTIO_NET_F_HOST_ECN); /* We handle indirect ring entries */ add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC); + /* We're compliant with the damn spec. */ + add_feature(dev, VIRTIO_F_ANY_LAYOUT); set_config(dev, sizeof(conf), &conf); /* We don't need the socket any more; setup is done. */ -- cgit v0.10.2 From c6017e793b932e84b1c998f9b4c08d74ff0ea9c0 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:23:46 +0930 Subject: virtio: console: add locks around buffer removal in port unplug path The removal functions act on the vqs, and the vq operations need to be locked. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 1b456fe..601962b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1513,18 +1513,22 @@ static void remove_port_data(struct port *port) { struct port_buffer *buf; + spin_lock_irq(&port->inbuf_lock); /* Remove unused data this port might have received. */ discard_port_data(port); - reclaim_consumed_buffers(port); - /* Remove buffers we queued up for the Host to send us data in. */ while ((buf = virtqueue_detach_unused_buf(port->in_vq))) free_buf(buf, true); + spin_unlock_irq(&port->inbuf_lock); + + spin_lock_irq(&port->outvq_lock); + reclaim_consumed_buffers(port); /* Free pending buffers from the out-queue. */ while ((buf = virtqueue_detach_unused_buf(port->out_vq))) free_buf(buf, true); + spin_unlock_irq(&port->outvq_lock); } /* -- cgit v0.10.2 From 5549fb25811710585d5ec77a0e6a1fbc8808df93 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:24:15 +0930 Subject: virtio: console: add locking in port unplug path Port unplug can race with close() in port_fops_release(). port_fops_release() already takes the necessary locks, ensure unplug_port() does that too. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 601962b..3572c5a 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1542,6 +1542,7 @@ static void unplug_port(struct port *port) list_del(&port->list); spin_unlock_irq(&port->portdev->ports_lock); + spin_lock_irq(&port->inbuf_lock); if (port->guest_connected) { port->guest_connected = false; port->host_connected = false; @@ -1550,6 +1551,7 @@ static void unplug_port(struct port *port) /* Let the app know the port is going down. */ send_sigio_to_port(port); } + spin_unlock_irq(&port->inbuf_lock); if (is_console_port(port)) { spin_lock_irq(&pdrvdata_lock); -- cgit v0.10.2 From 314081f1025e9ea77b69261f21183e9be18a6f91 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:25:38 +0930 Subject: virtio: console: fix locking around send_sigio_to_port() send_sigio_to_port() checks the value of guest_connected, which we always modify under the inbuf_lock; make sure invocations of send_sigio_to_port() have take the inbuf_lock around the call. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 3572c5a..d5e2c70 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1661,7 +1661,9 @@ static void handle_control_message(struct ports_device *portdev, * If the guest is connected, it'll be interested in * knowing the host connection state changed. */ + spin_lock_irq(&port->inbuf_lock); send_sigio_to_port(port); + spin_unlock_irq(&port->inbuf_lock); break; case VIRTIO_CONSOLE_PORT_NAME: /* @@ -1781,13 +1783,13 @@ static void in_intr(struct virtqueue *vq) if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) discard_port_data(port); + /* Send a SIGIO indicating new data in case the process asked for it */ + send_sigio_to_port(port); + spin_unlock_irqrestore(&port->inbuf_lock, flags); wake_up_interruptible(&port->waitqueue); - /* Send a SIGIO indicating new data in case the process asked for it */ - send_sigio_to_port(port); - if (is_console_port(port) && hvc_poll(port->cons.hvc)) hvc_kick(); } -- cgit v0.10.2 From 3f0d0c9b47e09d47fcb755fed786a1ee88e110b5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Jul 2013 15:54:07 +0930 Subject: virtio: console: cleanup an error message The PTR_ERR(NULL) here is not useful. Signed-off-by: Dan Carpenter Reviewed-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d5e2c70..5b60956 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -2223,10 +2223,8 @@ static int __init init(void) } pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL); - if (!pdrvdata.debugfs_dir) { - pr_warning("Error %ld creating debugfs dir for virtio-ports\n", - PTR_ERR(pdrvdata.debugfs_dir)); - } + if (!pdrvdata.debugfs_dir) + pr_warning("Error creating debugfs dir for virtio-ports\n"); INIT_LIST_HEAD(&pdrvdata.consoles); INIT_LIST_HEAD(&pdrvdata.portdevs); -- cgit v0.10.2 From 3b868a4073cdedf395f26d843874414e0e0e9cfd Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 7 Aug 2013 15:54:17 +0930 Subject: virtio: console: prevent use-after-free of port name in port unplug Remove the debugfs path before freeing port->name, to prevent a possible use-after-free. Reported-by: Jason Wang Signed-off-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d0e75aa..b79cf3e 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1591,9 +1591,8 @@ static void unplug_port(struct port *port) device_destroy(pdrvdata.class, port->dev->devt); cdev_del(port->cdev); - kfree(port->name); - debugfs_remove(port->debugfs_file); + kfree(port->name); /* * Locks around here are not necessary - a port can't be -- cgit v0.10.2 From 4623c28e222d82f87537ef66db61ebcfbd8306db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Sep 2013 17:45:39 +0930 Subject: lguest: fix BUG_ON() in invalid guest page table. If we discover the entry is invalid, we kill the guest, but we must avoid calling gpte_addr() on the invalid pmd, otherwise: kernel BUG at drivers/lguest/page_tables.c:157! Signed-off-by: Rusty Russell diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index a35d8d1..bfb39bb 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c @@ -669,8 +669,10 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr) #ifdef CONFIG_X86_PAE gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); - if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) + if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) { kill_guest(cpu, "Bad address %#lx", vaddr); + return -1UL; + } gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t); #else gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t); -- cgit v0.10.2 From 98fb4e5e6b100a247ce2dbf2d1699726fdcdef20 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Sep 2013 17:45:53 +0930 Subject: lguest: fix guest kernel stack overflow when TF bit set. The symptoms are that running gdb on a binary causes the guest to overflow the kernels stack (after some period of time), resulting in it finally being killed with a "Bad address" message. Reported-by: Sakari Ailus Signed-off-by: Rusty Russell diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index 28433a1..70dfcdc 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c @@ -140,6 +140,16 @@ static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, cpu->regs->eip = idt_address(lo, hi); /* + * Trapping always clears these flags: + * TF: Trap flag + * VM: Virtual 8086 mode + * RF: Resume + * NT: Nested task. + */ + cpu->regs->eflags &= + ~(X86_EFLAGS_TF|X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT); + + /* * There are two kinds of interrupt handlers: 0xE is an "interrupt * gate" which expects interrupts to be disabled on entry. */ -- cgit v0.10.2 From aa96a3c686b001a651c86dcb5b0b73d1a9b1d1ca Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Sep 2013 17:45:54 +0930 Subject: lguest: fix GPF in guest when using gdb. Since the Guest is in ring 1, it can't read the debug registers: doing so gives a number of nasty messages: (gdb) run Starting program: /bin/sleep [ 31.170230] general protection fault: 0000 [#1] SMP [ 31.170230] Modules linked in: [ 31.170230] CPU: 0 PID: 2678 Comm: sleep Not tainted 3.11.0+ #64 [ 31.170230] task: cc5c09b0 ti: cc79c000 task.ti: cc79c000 [ 31.170230] EIP: 0061:[] EFLAGS: 00000097 CPU: 0 [ 31.170230] EIP is at native_get_debugreg+0x58/0x70 [ 31.170230] EAX: 00000006 EBX: cc79dfb4 ECX: b7fff918 EDX: 00000000 [ 31.170230] ESI: cc5c09b0 EDI: 00000000 EBP: cc79df84 ESP: cc79df84 [ 31.170230] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0069 [ 31.170230] CR0: 00000008 CR2: 081ba69a CR3: 0e2f2000 CR4: 00000000 Signed-off-by: Rusty Russell diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 7c1fde5..bdf8532 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -1056,6 +1056,12 @@ static void lguest_load_sp0(struct tss_struct *tss, } /* Let's just say, I wouldn't do debugging under a Guest. */ +static unsigned long lguest_get_debugreg(int regno) +{ + /* FIXME: Implement */ + return 0; +} + static void lguest_set_debugreg(int regno, unsigned long value) { /* FIXME: Implement */ @@ -1303,6 +1309,7 @@ __init void lguest_init(void) pv_cpu_ops.load_tr_desc = lguest_load_tr_desc; pv_cpu_ops.set_ldt = lguest_set_ldt; pv_cpu_ops.load_tls = lguest_load_tls; + pv_cpu_ops.get_debugreg = lguest_get_debugreg; pv_cpu_ops.set_debugreg = lguest_set_debugreg; pv_cpu_ops.clts = lguest_clts; pv_cpu_ops.read_cr0 = lguest_read_cr0; -- cgit v0.10.2 From 9e266ece2178784a1027e04a56c8547dc51b15ce Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Mon, 9 Sep 2013 09:57:12 +0930 Subject: virtio_pci: pm: Use CONFIG_PM_SLEEP instead of CONFIG_PM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The virtio_pci_freeze/restore are defined under CONFIG_PM but is used by SET_SYSTEM_SLEEP_PM_OPS macro, which is defined under CONFIG_PM_SLEEP. So if CONFIG_PM_SLEEP is not cofigured but CONFIG_PM_RUNTIME is, the following warning message appeared: drivers/virtio/virtio_pci.c:770:12: warning: ‘virtio_pci_freeze’ defined but not used [-Wunused-function] static int virtio_pci_freeze(struct device *dev) ^ drivers/virtio/virtio_pci.c:790:12: warning: ‘virtio_pci_restore’ defined but not used [-Wunused-function] static int virtio_pci_restore(struct device *dev) ^ Fix it by changing CONFIG_PM to CONFIG_PM_SLEEP. Signed-off-by: Aaron Lu Reviewed-by: Amit Shah Signed-off-by: Rusty Russell diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 1aba255..98917fc 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -766,7 +766,7 @@ static void virtio_pci_remove(struct pci_dev *pci_dev) kfree(vp_dev); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int virtio_pci_freeze(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); @@ -824,7 +824,7 @@ static struct pci_driver virtio_pci_driver = { .id_table = virtio_pci_id_table, .probe = virtio_pci_probe, .remove = virtio_pci_remove, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .driver.pm = &virtio_pci_pm_ops, #endif }; -- cgit v0.10.2