Skip to content

Commit

Permalink
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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
  • Loading branch information
Linus Torvalds committed Sep 9, 2013
2 parents d75671e + 9e266ec commit d8cacd3
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 16 deletions.
10 changes: 8 additions & 2 deletions arch/x86/lguest/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1057,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 */
Expand Down Expand Up @@ -1304,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;
Expand Down
27 changes: 16 additions & 11 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1529,18 +1529,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);
}

/*
Expand All @@ -1554,6 +1558,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) {
/* Let the app know the port is going down. */
send_sigio_to_port(port);
Expand All @@ -1564,6 +1569,7 @@ static void unplug_port(struct port *port)

wake_up_interruptible(&port->waitqueue);
}
spin_unlock_irq(&port->inbuf_lock);

if (is_console_port(port)) {
spin_lock_irq(&pdrvdata_lock);
Expand All @@ -1585,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
Expand Down Expand Up @@ -1681,7 +1686,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:
/*
Expand Down Expand Up @@ -1801,13 +1808,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();
}
Expand Down Expand Up @@ -2241,10 +2248,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);

Expand Down
10 changes: 10 additions & 0 deletions drivers/lguest/interrupts_and_traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi,
cpu->regs->cs = (__KERNEL_CS|GUEST_PL);
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.
Expand Down
4 changes: 3 additions & 1 deletion drivers/lguest/page_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/virtio/virtio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
};
Expand Down
6 changes: 6 additions & 0 deletions tools/lguest/lguest.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
#include <pwd.h>
#include <grp.h>

#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.
Expand Down Expand Up @@ -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. */
Expand Down
3 changes: 3 additions & 0 deletions tools/virtio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.d
virtio_test
vringh_test

0 comments on commit d8cacd3

Please sign in to comment.