Skip to content

Commit d8cacd3

Browse files
committed
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
2 parents d75671e + 9e266ec commit d8cacd3

File tree

7 files changed

+48
-16
lines changed

7 files changed

+48
-16
lines changed

arch/x86/lguest/boot.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
* kernel and insert a module (lg.ko) which allows us to run other Linux
88
* kernels the same way we'd run processes. We call the first kernel the Host,
99
* 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
11-
* Launcher.
10+
* (such as the example in tools/lguest/lguest.c) is called the Launcher.
1211
*
1312
* Secondly, we only run specially modified Guests, not normal kernels: setting
1413
* 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,
10571056
}
10581057

10591058
/* 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+
10601065
static void lguest_set_debugreg(int regno, unsigned long value)
10611066
{
10621067
/* FIXME: Implement */
@@ -1304,6 +1309,7 @@ __init void lguest_init(void)
13041309
pv_cpu_ops.load_tr_desc = lguest_load_tr_desc;
13051310
pv_cpu_ops.set_ldt = lguest_set_ldt;
13061311
pv_cpu_ops.load_tls = lguest_load_tls;
1312+
pv_cpu_ops.get_debugreg = lguest_get_debugreg;
13071313
pv_cpu_ops.set_debugreg = lguest_set_debugreg;
13081314
pv_cpu_ops.clts = lguest_clts;
13091315
pv_cpu_ops.read_cr0 = lguest_read_cr0;

drivers/char/virtio_console.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,18 +1529,22 @@ static void remove_port_data(struct port *port)
15291529
{
15301530
struct port_buffer *buf;
15311531

1532+
spin_lock_irq(&port->inbuf_lock);
15321533
/* Remove unused data this port might have received. */
15331534
discard_port_data(port);
15341535

1535-
reclaim_consumed_buffers(port);
1536-
15371536
/* Remove buffers we queued up for the Host to send us data in. */
15381537
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
15391538
free_buf(buf, true);
1539+
spin_unlock_irq(&port->inbuf_lock);
1540+
1541+
spin_lock_irq(&port->outvq_lock);
1542+
reclaim_consumed_buffers(port);
15401543

15411544
/* Free pending buffers from the out-queue. */
15421545
while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
15431546
free_buf(buf, true);
1547+
spin_unlock_irq(&port->outvq_lock);
15441548
}
15451549

15461550
/*
@@ -1554,6 +1558,7 @@ static void unplug_port(struct port *port)
15541558
list_del(&port->list);
15551559
spin_unlock_irq(&port->portdev->ports_lock);
15561560

1561+
spin_lock_irq(&port->inbuf_lock);
15571562
if (port->guest_connected) {
15581563
/* Let the app know the port is going down. */
15591564
send_sigio_to_port(port);
@@ -1564,6 +1569,7 @@ static void unplug_port(struct port *port)
15641569

15651570
wake_up_interruptible(&port->waitqueue);
15661571
}
1572+
spin_unlock_irq(&port->inbuf_lock);
15671573

15681574
if (is_console_port(port)) {
15691575
spin_lock_irq(&pdrvdata_lock);
@@ -1585,9 +1591,8 @@ static void unplug_port(struct port *port)
15851591
device_destroy(pdrvdata.class, port->dev->devt);
15861592
cdev_del(port->cdev);
15871593

1588-
kfree(port->name);
1589-
15901594
debugfs_remove(port->debugfs_file);
1595+
kfree(port->name);
15911596

15921597
/*
15931598
* Locks around here are not necessary - a port can't be
@@ -1681,7 +1686,9 @@ static void handle_control_message(struct ports_device *portdev,
16811686
* If the guest is connected, it'll be interested in
16821687
* knowing the host connection state changed.
16831688
*/
1689+
spin_lock_irq(&port->inbuf_lock);
16841690
send_sigio_to_port(port);
1691+
spin_unlock_irq(&port->inbuf_lock);
16851692
break;
16861693
case VIRTIO_CONSOLE_PORT_NAME:
16871694
/*
@@ -1801,13 +1808,13 @@ static void in_intr(struct virtqueue *vq)
18011808
if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev))
18021809
discard_port_data(port);
18031810

1811+
/* Send a SIGIO indicating new data in case the process asked for it */
1812+
send_sigio_to_port(port);
1813+
18041814
spin_unlock_irqrestore(&port->inbuf_lock, flags);
18051815

18061816
wake_up_interruptible(&port->waitqueue);
18071817

1808-
/* Send a SIGIO indicating new data in case the process asked for it */
1809-
send_sigio_to_port(port);
1810-
18111818
if (is_console_port(port) && hvc_poll(port->cons.hvc))
18121819
hvc_kick();
18131820
}
@@ -2241,10 +2248,8 @@ static int __init init(void)
22412248
}
22422249

22432250
pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
2244-
if (!pdrvdata.debugfs_dir) {
2245-
pr_warning("Error %ld creating debugfs dir for virtio-ports\n",
2246-
PTR_ERR(pdrvdata.debugfs_dir));
2247-
}
2251+
if (!pdrvdata.debugfs_dir)
2252+
pr_warning("Error creating debugfs dir for virtio-ports\n");
22482253
INIT_LIST_HEAD(&pdrvdata.consoles);
22492254
INIT_LIST_HEAD(&pdrvdata.portdevs);
22502255

drivers/lguest/interrupts_and_traps.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi,
139139
cpu->regs->cs = (__KERNEL_CS|GUEST_PL);
140140
cpu->regs->eip = idt_address(lo, hi);
141141

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+
142152
/*
143153
* There are two kinds of interrupt handlers: 0xE is an "interrupt
144154
* gate" which expects interrupts to be disabled on entry.

drivers/lguest/page_tables.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,10 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
669669

670670
#ifdef CONFIG_X86_PAE
671671
gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
672-
if (!(pmd_flags(gpmd) & _PAGE_PRESENT))
672+
if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) {
673673
kill_guest(cpu, "Bad address %#lx", vaddr);
674+
return -1UL;
675+
}
674676
gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t);
675677
#else
676678
gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);

drivers/virtio/virtio_pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
766766
kfree(vp_dev);
767767
}
768768

769-
#ifdef CONFIG_PM
769+
#ifdef CONFIG_PM_SLEEP
770770
static int virtio_pci_freeze(struct device *dev)
771771
{
772772
struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -824,7 +824,7 @@ static struct pci_driver virtio_pci_driver = {
824824
.id_table = virtio_pci_id_table,
825825
.probe = virtio_pci_probe,
826826
.remove = virtio_pci_remove,
827-
#ifdef CONFIG_PM
827+
#ifdef CONFIG_PM_SLEEP
828828
.driver.pm = &virtio_pci_pm_ops,
829829
#endif
830830
};

tools/lguest/lguest.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
#include <pwd.h>
4343
#include <grp.h>
4444

45+
#ifndef VIRTIO_F_ANY_LAYOUT
46+
#define VIRTIO_F_ANY_LAYOUT 27
47+
#endif
48+
4549
/*L:110
4650
* We can ignore the 43 include files we need for this program, but I do want
4751
* to draw attention to the use of kernel-style types.
@@ -1544,6 +1548,8 @@ static void setup_tun_net(char *arg)
15441548
add_feature(dev, VIRTIO_NET_F_HOST_ECN);
15451549
/* We handle indirect ring entries */
15461550
add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
1551+
/* We're compliant with the damn spec. */
1552+
add_feature(dev, VIRTIO_F_ANY_LAYOUT);
15471553
set_config(dev, sizeof(conf), &conf);
15481554

15491555
/* We don't need the socket any more; setup is done. */

tools/virtio/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.d
2+
virtio_test
3+
vringh_test

0 commit comments

Comments
 (0)