diff options
| -rw-r--r-- | arch/x86/lguest/boot.c | 10 | ||||
| -rw-r--r-- | drivers/char/virtio_console.c | 27 | ||||
| -rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 10 | ||||
| -rw-r--r-- | drivers/lguest/page_tables.c | 4 | ||||
| -rw-r--r-- | drivers/virtio/virtio_pci.c | 4 | ||||
| -rw-r--r-- | tools/lguest/lguest.c | 6 | ||||
| -rw-r--r-- | tools/virtio/.gitignore | 3 |
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. */ |
| 1059 | static unsigned long lguest_get_debugreg(int regno) | ||
| 1060 | { | ||
| 1061 | /* FIXME: Implement */ | ||
| 1062 | return 0; | ||
| 1063 | } | ||
| 1064 | |||
| 1060 | static void lguest_set_debugreg(int regno, unsigned long value) | 1065 | static 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 | |||
