aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 13:20:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 13:20:54 -0400
commitd8cacd3a259bf522ea5e6c4c60eba67ba22f599c (patch)
tree24af775fc95240a5be8fdc7bbdb4c25d44ed644c
parentd75671e36e14b73d7c0d3cec49328dcd984af699 (diff)
parent9e266ece2178784a1027e04a56c8547dc51b15ce (diff)
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio update from Rusty Russell: "More console fixes; these are the theoretical ones which didn't get CC:stable. But for that reason, I did a merge with master partway through to avoid an unnecessary conflict. Also: a fun lguest bug turns out if you don't clear the TF flag when trapping Bad Things happen to the guest kernel as the stack overflows..." * tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: virtio_pci: pm: Use CONFIG_PM_SLEEP instead of CONFIG_PM lguest: fix GPF in guest when using gdb. lguest: fix guest kernel stack overflow when TF bit set. lguest: fix BUG_ON() in invalid guest page table. virtio: console: prevent use-after-free of port name in port unplug virtio: console: cleanup an error message virtio: console: fix locking around send_sigio_to_port() virtio: console: add locking in port unplug path virtio: console: add locks around buffer removal in port unplug path tools/lguest: offer VIRTIO_F_ANY_LAYOUT for net device. virtio tools: add .gitignore lguest: Point to the right directory for the lguest launcher
-rw-r--r--arch/x86/lguest/boot.c10
-rw-r--r--drivers/char/virtio_console.c27
-rw-r--r--drivers/lguest/interrupts_and_traps.c10
-rw-r--r--drivers/lguest/page_tables.c4
-rw-r--r--drivers/virtio/virtio_pci.c4
-rw-r--r--tools/lguest/lguest.c6
-rw-r--r--tools/virtio/.gitignore3
7 files changed, 48 insertions, 16 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 6a22c19da663..bdf8532494fe 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -7,8 +7,7 @@
7 * kernel and insert a module (lg.ko) which allows us to run other Linux 7 * kernel and insert a module (lg.ko) which allows us to run other Linux
8 * kernels the same way we'd run processes. We call the first kernel the Host, 8 * kernels the same way we'd run processes. We call the first kernel the Host,
9 * and the others the Guests. The program which sets up and configures Guests 9 * and the others the Guests. The program which sets up and configures Guests
10 * (such as the example in Documentation/virtual/lguest/lguest.c) is called the 10 * (such as the example in tools/lguest/lguest.c) is called the Launcher.
11 * Launcher.
12 * 11 *
13 * Secondly, we only run specially modified Guests, not normal kernels: setting 12 * Secondly, we only run specially modified Guests, not normal kernels: setting
14 * CONFIG_LGUEST_GUEST to "y" compiles this file into the kernel so it knows 13 * CONFIG_LGUEST_GUEST to "y" compiles this file into the kernel so it knows
@@ -1057,6 +1056,12 @@ static void lguest_load_sp0(struct tss_struct *tss,
1057} 1056}
1058 1057
1059/* Let's just say, I wouldn't do debugging under a Guest. */ 1058/* Let's just say, I wouldn't do debugging under a Guest. */
1059static unsigned long lguest_get_debugreg(int regno)
1060{
1061 /* FIXME: Implement */
1062 return 0;
1063}
1064
1060static void lguest_set_debugreg(int regno, unsigned long value) 1065static void lguest_set_debugreg(int regno, unsigned long value)
1061{ 1066{
1062 /* FIXME: Implement */ 1067 /* FIXME: Implement */
@@ -1304,6 +1309,7 @@ __init void lguest_init(void)
1304 pv_cpu_ops.load_tr_desc = lguest_load_tr_desc; 1309 pv_cpu_ops.load_tr_desc = lguest_load_tr_desc;
1305 pv_cpu_ops.set_ldt = lguest_set_ldt; 1310 pv_cpu_ops.set_ldt = lguest_set_ldt;
1306 pv_cpu_ops.load_tls = lguest_load_tls; 1311 pv_cpu_ops.load_tls = lguest_load_tls;
1312 pv_cpu_ops.get_debugreg = lguest_get_debugreg;
1307 pv_cpu_ops.set_debugreg = lguest_set_debugreg; 1313 pv_cpu_ops.set_debugreg = lguest_set_debugreg;
1308 pv_cpu_ops.clts = lguest_clts; 1314 pv_cpu_ops.clts = lguest_clts;
1309 pv_cpu_ops.read_cr0 = lguest_read_cr0; 1315 pv_cpu_ops.read_cr0 = lguest_read_cr0;
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index fc45567ad3ac..b79cf3e1b793 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1529,18 +1529,22 @@ static void remove_port_data(struct port *port)
1529{ 1529{
1530 struct port_buffer *buf; 1530 struct port_buffer *buf;
1531 1531
1532 spin_lock_irq(&port->inbuf_lock);
1532 /* Remove unused data this port might have received. */ 1533 /* Remove unused data this port might have received. */
1533 discard_port_data(port); 1534 discard_port_data(port);
1534 1535
1535 reclaim_consumed_buffers(port);
1536
1537 /* Remove buffers we queued up for the Host to send us data in. */ 1536 /* Remove buffers we queued up for the Host to send us data in. */
1538 while ((buf = virtqueue_detach_unused_buf(port->in_vq))) 1537 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
1539 free_buf(buf, true); 1538 free_buf(buf, true);
1539 spin_unlock_irq(&port->inbuf_lock);
1540
1541 spin_lock_irq(&port->outvq_lock);
1542 reclaim_consumed_buffers(port);
1540 1543
1541 /* Free pending buffers from the out-queue. */ 1544 /* Free pending buffers from the out-queue. */
1542 while ((buf = virtqueue_detach_unused_buf(port->out_vq))) 1545 while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
1543 free_buf(buf, true); 1546 free_buf(buf, true);
1547 spin_unlock_irq(&port->outvq_lock);
1544} 1548}
1545 1549
1546/* 1550/*
@@ -1554,6 +1558,7 @@ static void unplug_port(struct port *port)
1554 list_del(&port->list); 1558 list_del(&port->list);
1555 spin_unlock_irq(&port->portdev->ports_lock); 1559 spin_unlock_irq(&port->portdev->ports_lock);
1556 1560
1561 spin_lock_irq(&port->inbuf_lock);
1557 if (port->guest_connected) { 1562 if (port->guest_connected) {
1558 /* Let the app know the port is going down. */ 1563 /* Let the app know the port is going down. */
1559 send_sigio_to_port(port); 1564 send_sigio_to_port(port);
@@ -1564,6 +1569,7 @@ static void unplug_port(struct port *port)
1564 1569
1565 wake_up_interruptible(&port->waitqueue); 1570 wake_up_interruptible(&port->waitqueue);
1566 } 1571 }
1572 spin_unlock_irq(&port->inbuf_lock);
1567 1573
1568 if (is_console_port(port)) { 1574 if (is_console_port(port)) {
1569 spin_lock_irq(&pdrvdata_lock); 1575 spin_lock_irq(&pdrvdata_lock);
@@ -1585,9 +1591,8 @@ static void unplug_port(struct port *port)
1585 device_destroy(pdrvdata.class, port->dev->devt); 1591 device_destroy(pdrvdata.class, port->dev->devt);
1586 cdev_del(port->cdev); 1592 cdev_del(port->cdev);
1587 1593
1588 kfree(port->name);
1589
1590 debugfs_remove(port->debugfs_file); 1594 debugfs_remove(port->debugfs_file);
1595 kfree(port->name);
1591 1596
1592 /* 1597 /*
1593 * Locks around here are not necessary - a port can't be 1598 * Locks around here are not necessary - a port can't be
@@ -1681,7 +1686,9 @@ static void handle_control_message(struct ports_device *portdev,
1681 * If the guest is connected, it'll be interested in 1686 * If the guest is connected, it'll be interested in
1682 * knowing the host connection state changed. 1687 * knowing the host connection state changed.
1683 */ 1688 */
1689 spin_lock_irq(&port->inbuf_lock);
1684 send_sigio_to_port(port); 1690 send_sigio_to_port(port);
1691 spin_unlock_irq(&port->inbuf_lock);
1685 break; 1692 break;
1686 case VIRTIO_CONSOLE_PORT_NAME: 1693 case VIRTIO_CONSOLE_PORT_NAME:
1687 /* 1694 /*
@@ -1801,13 +1808,13 @@ static void in_intr(struct virtqueue *vq)
1801 if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) 1808 if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev))
1802 discard_port_data(port); 1809 discard_port_data(port);
1803 1810
1811 /* Send a SIGIO indicating new data in case the process asked for it */
1812 send_sigio_to_port(port);
1813
1804 spin_unlock_irqrestore(&port->inbuf_lock, flags); 1814 spin_unlock_irqrestore(&port->inbuf_lock, flags);
1805 1815
1806 wake_up_interruptible(&port->waitqueue); 1816 wake_up_interruptible(&port->waitqueue);
1807 1817
1808 /* Send a SIGIO indicating new data in case the process asked for it */
1809 send_sigio_to_port(port);
1810
1811 if (is_console_port(port) && hvc_poll(port->cons.hvc)) 1818 if (is_console_port(port) && hvc_poll(port->cons.hvc))
1812 hvc_kick(); 1819 hvc_kick();
1813} 1820}
@@ -2241,10 +2248,8 @@ static int __init init(void)
2241 } 2248 }
2242 2249
2243 pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL); 2250 pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
2244 if (!pdrvdata.debugfs_dir) { 2251 if (!pdrvdata.debugfs_dir)
2245 pr_warning("Error %ld creating debugfs dir for virtio-ports\n", 2252 pr_warning("Error creating debugfs dir for virtio-ports\n");
2246 PTR_ERR(pdrvdata.debugfs_dir));
2247 }
2248 INIT_LIST_HEAD(&pdrvdata.consoles); 2253 INIT_LIST_HEAD(&pdrvdata.consoles);
2249 INIT_LIST_HEAD(&pdrvdata.portdevs); 2254 INIT_LIST_HEAD(&pdrvdata.portdevs);
2250 2255
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 28433a155d67..70dfcdc29f1f 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,
140 cpu->regs->eip = idt_address(lo, hi); 140 cpu->regs->eip = idt_address(lo, hi);
141 141
142 /* 142 /*
143 * Trapping always clears these flags:
144 * TF: Trap flag
145 * VM: Virtual 8086 mode
146 * RF: Resume
147 * NT: Nested task.
148 */
149 cpu->regs->eflags &=
150 ~(X86_EFLAGS_TF|X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT);
151
152 /*
143 * There are two kinds of interrupt handlers: 0xE is an "interrupt 153 * There are two kinds of interrupt handlers: 0xE is an "interrupt
144 * gate" which expects interrupts to be disabled on entry. 154 * gate" which expects interrupts to be disabled on entry.
145 */ 155 */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index a35d8d100165..bfb39bb56ef1 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)
669 669
670#ifdef CONFIG_X86_PAE 670#ifdef CONFIG_X86_PAE
671 gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); 671 gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
672 if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) 672 if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) {
673 kill_guest(cpu, "Bad address %#lx", vaddr); 673 kill_guest(cpu, "Bad address %#lx", vaddr);
674 return -1UL;
675 }
674 gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t); 676 gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t);
675#else 677#else
676 gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t); 678 gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 1aba255b5879..98917fc872a4 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)
766 kfree(vp_dev); 766 kfree(vp_dev);
767} 767}
768 768
769#ifdef CONFIG_PM 769#ifdef CONFIG_PM_SLEEP
770static int virtio_pci_freeze(struct device *dev) 770static int virtio_pci_freeze(struct device *dev)
771{ 771{
772 struct pci_dev *pci_dev = to_pci_dev(dev); 772 struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -824,7 +824,7 @@ static struct pci_driver virtio_pci_driver = {
824 .id_table = virtio_pci_id_table, 824 .id_table = virtio_pci_id_table,
825 .probe = virtio_pci_probe, 825 .probe = virtio_pci_probe,
826 .remove = virtio_pci_remove, 826 .remove = virtio_pci_remove,
827#ifdef CONFIG_PM 827#ifdef CONFIG_PM_SLEEP
828 .driver.pm = &virtio_pci_pm_ops, 828 .driver.pm = &virtio_pci_pm_ops,
829#endif 829#endif
830}; 830};
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 68f67cf3d318..32cf2ce15d69 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -42,6 +42,10 @@
42#include <pwd.h> 42#include <pwd.h>
43#include <grp.h> 43#include <grp.h>
44 44
45#ifndef VIRTIO_F_ANY_LAYOUT
46#define VIRTIO_F_ANY_LAYOUT 27
47#endif
48
45/*L:110 49/*L:110
46 * We can ignore the 43 include files we need for this program, but I do want 50 * We can ignore the 43 include files we need for this program, but I do want
47 * to draw attention to the use of kernel-style types. 51 * to draw attention to the use of kernel-style types.
@@ -1544,6 +1548,8 @@ static void setup_tun_net(char *arg)
1544 add_feature(dev, VIRTIO_NET_F_HOST_ECN); 1548 add_feature(dev, VIRTIO_NET_F_HOST_ECN);
1545 /* We handle indirect ring entries */ 1549 /* We handle indirect ring entries */
1546 add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC); 1550 add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
1551 /* We're compliant with the damn spec. */
1552 add_feature(dev, VIRTIO_F_ANY_LAYOUT);
1547 set_config(dev, sizeof(conf), &conf); 1553 set_config(dev, sizeof(conf), &conf);
1548 1554
1549 /* We don't need the socket any more; setup is done. */ 1555 /* We don't need the socket any more; setup is done. */
diff --git a/tools/virtio/.gitignore b/tools/virtio/.gitignore
new file mode 100644
index 000000000000..1cfbb0157a46
--- /dev/null
+++ b/tools/virtio/.gitignore
@@ -0,0 +1,3 @@
1*.d
2virtio_test
3vringh_test