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

Commit b9bb6fb7 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 updates from Rusty Russell:
 "Some virtio internal cleanups, a new virtio device "virtio input", and
  a change to allow the legacy virtio balloon.

  Most excitingly, some lguest work! No seriously, I got some cleanup
  patches"

* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  virtio: drop virtio_device_is_legacy_only
  virtio_pci: support non-legacy balloon devices
  virtio_mmio: support non-legacy balloon devices
  virtio_ccw: support non-legacy balloon devices
  virtio: balloon might not be a legacy device
  virtio_balloon: transitional interface
  virtio_ring: Update weak barriers to use dma_wmb/rmb
  virtio_pci_modern: switch to type-safe io accessors
  virtio_pci_modern: type-safe io accessors
  lguest: handle traps on the "interrupt suppressed" iret instruction.
  virtio: drop a useless config read
  virtio_config: reorder functions
  Add virtio-input driver.
  lguest: suppress interrupts for single insn, not range.
  lguest: simplify lguest_iret
  lguest: rename i386_head.S in the comments
  lguest: explicitly set miscdevice's private_data NULL
  lguest: fix pending interrupt test.
parents 15ce2658 9abbfb48
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -10517,6 +10517,12 @@ S: Maintained
F:	drivers/vhost/
F:	include/uapi/linux/vhost.h

VIRTIO INPUT DRIVER
M:	Gerd Hoffmann <kraxel@redhat.com>
S:	Maintained
F:	drivers/virtio/virtio_input.c
F:	include/uapi/linux/virtio_input.h

VIA RHINE NETWORK DRIVER
M:	Roger Luethi <rl@hellgate.ch>
S:	Maintained
+2 −5
Original line number Diff line number Diff line
@@ -20,13 +20,10 @@ extern unsigned long switcher_addr;
/* Found in switcher.S */
extern unsigned long default_idt_entries[];

/* Declarations for definitions in lguest_guest.S */
extern char lguest_noirq_start[], lguest_noirq_end[];
/* Declarations for definitions in arch/x86/lguest/head_32.S */
extern char lguest_noirq_iret[];
extern const char lgstart_cli[], lgend_cli[];
extern const char lgstart_sti[], lgend_sti[];
extern const char lgstart_popf[], lgend_popf[];
extern const char lgstart_pushf[], lgend_pushf[];
extern const char lgstart_iret[], lgend_iret[];

extern void lguest_iret(void);
extern void lguest_init(void);
+3 −4
Original line number Diff line number Diff line
@@ -87,8 +87,7 @@

struct lguest_data lguest_data = {
	.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
	.noirq_start = (u32)lguest_noirq_start,
	.noirq_end = (u32)lguest_noirq_end,
	.noirq_iret = (u32)lguest_noirq_iret,
	.kernel_address = PAGE_OFFSET,
	.blocked_interrupts = { 1 }, /* Block timer interrupts */
	.syscall_vec = SYSCALL_VECTOR,
@@ -262,7 +261,7 @@ PV_CALLEE_SAVE_REGS_THUNK(lguest_save_fl);
PV_CALLEE_SAVE_REGS_THUNK(lguest_irq_disable);
/*:*/

/* These are in i386_head.S */
/* These are in head_32.S */
extern void lg_irq_enable(void);
extern void lg_restore_fl(unsigned long flags);

@@ -1368,7 +1367,7 @@ static void lguest_restart(char *reason)
 * fit comfortably.
 *
 * First we need assembly templates of each of the patchable Guest operations,
 * and these are in i386_head.S.
 * and these are in head_32.S.
 */

/*G:060 We construct a table from the assembler templates: */
+13 −17
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ ENTRY(lg_irq_enable)
	 * set lguest_data.irq_pending to X86_EFLAGS_IF.  If it's not zero, we
	 * jump to send_interrupts, otherwise we're done.
	 */
	testl $0, lguest_data+LGUEST_DATA_irq_pending
	cmpl $0, lguest_data+LGUEST_DATA_irq_pending
	jnz send_interrupts
	/*
	 * One cool thing about x86 is that you can do many things without using
@@ -133,9 +133,8 @@ ENTRY(lg_restore_fl)
	ret
/*:*/

/* These demark the EIP range where host should never deliver interrupts. */
.global lguest_noirq_start
.global lguest_noirq_end
/* These demark the EIP where host should never deliver interrupts. */
.global lguest_noirq_iret

/*M:004
 * When the Host reflects a trap or injects an interrupt into the Guest, it
@@ -168,29 +167,26 @@ ENTRY(lg_restore_fl)
 * So we have to copy eflags from the stack to lguest_data.irq_enabled before
 * we do the "iret".
 *
 * There are two problems with this: firstly, we need to use a register to do
 * the copy and secondly, the whole thing needs to be atomic.  The first
 * problem is easy to solve: push %eax on the stack so we can use it, and then
 * restore it at the end just before the real "iret".
 * There are two problems with this: firstly, we can't clobber any registers
 * and secondly, the whole thing needs to be atomic.  The first problem
 * is solved by using "push memory"/"pop memory" instruction pair for copying.
 *
 * The second is harder: copying eflags to lguest_data.irq_enabled will turn
 * interrupts on before we're finished, so we could be interrupted before we
 * return to userspace or wherever.  Our solution to this is to surround the
 * code with lguest_noirq_start: and lguest_noirq_end: labels.  We tell the
 * return to userspace or wherever.  Our solution to this is to tell the
 * Host that it is *never* to interrupt us there, even if interrupts seem to be
 * enabled.
 * enabled. (It's not necessary to protect pop instruction, since
 * data gets updated only after it completes, so we only need to protect
 * one instruction, iret).
 */
ENTRY(lguest_iret)
	pushl	%eax
	movl	12(%esp), %eax
lguest_noirq_start:
	pushl	2*4(%esp)
	/*
	 * Note the %ss: segment prefix here.  Normal data accesses use the
	 * "ds" segment, but that will have already been restored for whatever
	 * we're returning to (such as userspace): we can't trust it.  The %ss:
	 * prefix makes sure we use the stack segment, which is still valid.
	 */
	movl	%eax,%ss:lguest_data+LGUEST_DATA_irq_enabled
	popl	%eax
	popl	%ss:lguest_data+LGUEST_DATA_irq_enabled
lguest_noirq_iret:
	iret
lguest_noirq_end:
+2 −3
Original line number Diff line number Diff line
@@ -211,10 +211,9 @@ static void initialize(struct lg_cpu *cpu)

	/*
	 * The Guest tells us where we're not to deliver interrupts by putting
	 * the range of addresses into "struct lguest_data".
	 * the instruction address into "struct lguest_data".
	 */
	if (get_user(cpu->lg->noirq_start, &cpu->lg->lguest_data->noirq_start)
	    || get_user(cpu->lg->noirq_end, &cpu->lg->lguest_data->noirq_end))
	if (get_user(cpu->lg->noirq_iret, &cpu->lg->lguest_data->noirq_iret))
		kill_guest(cpu, "bad guest page %p", cpu->lg->lguest_data);

	/*
Loading