Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8cacd3a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -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;
+16 −11
Original line number Diff line number Diff line
@@ -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);

+10 −0
Original line number Diff line number Diff line
@@ -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.
+3 −1
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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
};
Loading