Commit d8cacd3a authored by Linus Torvalds's avatar Linus Torvalds

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
parents d75671e3 9e266ece
......@@ -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
......@@ -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 */
......@@ -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;
......
......@@ -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);
}
/*
......@@ -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);
......@@ -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);
......@@ -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
......@@ -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:
/*
......@@ -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();
}
......@@ -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);
......
......@@ -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.
......
......@@ -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);
......
......@@ -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
};
......
......@@ -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.
......@@ -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. */
......
*.d
virtio_test
vringh_test
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment