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

Commit d3561b7f authored by Rusty Russell's avatar Rusty Russell Committed by Andi Kleen
Browse files

[PATCH] paravirt: header and stubs for paravirtualisation



Create a paravirt.h header for all the critical operations which need to be
replaced with hypervisor calls, and include that instead of defining native
operations, when CONFIG_PARAVIRT.

This patch does the dumbest possible replacement of paravirtualized
instructions: calls through a "paravirt_ops" structure.  Currently these are
function implementations of native hardware: hypervisors will override the ops
structure with their own variants.

All the pv-ops functions are declared "fastcall" so that a specific
register-based ABI is used, to make inlining assember easier.

And:

+From: Andy Whitcroft <apw@shadowen.org>

The paravirt ops introduce a 'weak' attribute onto memory_setup().
Code ordering leads to the following warnings on x86:

    arch/i386/kernel/setup.c:651: warning: weak declaration of
                `memory_setup' after first use results in unspecified behavior

Move memory_setup() to avoid this.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarChris Wright <chrisw@sous-sol.org>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Zachary Amsden <zach@vmware.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarAndy Whitcroft <apw@shadowen.org>
parent db91b882
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -182,6 +182,17 @@ config X86_ES7000


endchoice
endchoice


config PARAVIRT
	bool "Paravirtualization support (EXPERIMENTAL)"
	depends on EXPERIMENTAL
	help
	  Paravirtualization is a way of running multiple instances of
	  Linux on the same machine, under a hypervisor.  This option
	  changes the kernel so it can modify itself when it is run
	  under a hypervisor, improving performance significantly.
	  However, when run without a hypervisor the kernel is
	  theoretically slower.  If in doubt, say N.

config ACPI_SRAT
config ACPI_SRAT
	bool
	bool
	default y
	default y
+1 −0
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@
 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
 */
 */


#undef CONFIG_PARAVIRT
#include <linux/linkage.h>
#include <linux/linkage.h>
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/screen_info.h>
#include <linux/screen_info.h>
+1 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ obj-$(CONFIG_VM86) += vm86.o
obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
obj-$(CONFIG_K8_NB)		+= k8.o
obj-$(CONFIG_K8_NB)		+= k8.o
obj-$(CONFIG_PARAVIRT)		+= paravirt.o


EXTRA_AFLAGS   := -traditional
EXTRA_AFLAGS   := -traditional


+10 −0
Original line number Original line Diff line number Diff line
@@ -101,4 +101,14 @@ void foo(void)
	BLANK();
	BLANK();
 	OFFSET(PDA_cpu, i386_pda, cpu_number);
 	OFFSET(PDA_cpu, i386_pda, cpu_number);
	OFFSET(PDA_pcurrent, i386_pda, pcurrent);
	OFFSET(PDA_pcurrent, i386_pda, pcurrent);

#ifdef CONFIG_PARAVIRT
	BLANK();
	OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled);
	OFFSET(PARAVIRT_irq_disable, paravirt_ops, irq_disable);
	OFFSET(PARAVIRT_irq_enable, paravirt_ops, irq_enable);
	OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
	OFFSET(PARAVIRT_iret, paravirt_ops, iret);
	OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
#endif
}
}
+27 −7
Original line number Original line Diff line number Diff line
@@ -62,13 +62,6 @@ DF_MASK = 0x00000400
NT_MASK		= 0x00004000
NT_MASK		= 0x00004000
VM_MASK		= 0x00020000
VM_MASK		= 0x00020000


/* These are replaces for paravirtualization */
#define DISABLE_INTERRUPTS		cli
#define ENABLE_INTERRUPTS		sti
#define ENABLE_INTERRUPTS_SYSEXIT	sti; sysexit
#define INTERRUPT_RETURN		iret
#define GET_CR0_INTO_EAX		movl %cr0, %eax

#ifdef CONFIG_PREEMPT
#ifdef CONFIG_PREEMPT
#define preempt_stop		DISABLE_INTERRUPTS; TRACE_IRQS_OFF
#define preempt_stop		DISABLE_INTERRUPTS; TRACE_IRQS_OFF
#else
#else
@@ -416,6 +409,20 @@ ldt_ss:
	jnz restore_nocheck
	jnz restore_nocheck
	testl $0x00400000, %eax		# returning to 32bit stack?
	testl $0x00400000, %eax		# returning to 32bit stack?
	jnz restore_nocheck		# allright, normal return
	jnz restore_nocheck		# allright, normal return

#ifdef CONFIG_PARAVIRT
	/*
	 * The kernel can't run on a non-flat stack if paravirt mode
	 * is active.  Rather than try to fixup the high bits of
	 * ESP, bypass this code entirely.  This may break DOSemu
	 * and/or Wine support in a paravirt VM, although the option
	 * is still available to implement the setting of the high
	 * 16-bits in the INTERRUPT_RETURN paravirt-op.
	 */
	cmpl $0, paravirt_ops+PARAVIRT_enabled
	jne restore_nocheck
#endif

	/* If returning to userspace with 16bit stack,
	/* If returning to userspace with 16bit stack,
	 * try to fix the higher word of ESP, as the CPU
	 * try to fix the higher word of ESP, as the CPU
	 * won't restore it.
	 * won't restore it.
@@ -833,6 +840,19 @@ nmi_espfix_stack:
.previous
.previous
KPROBE_END(nmi)
KPROBE_END(nmi)


#ifdef CONFIG_PARAVIRT
ENTRY(native_iret)
1:	iret
.section __ex_table,"a"
	.align 4
	.long 1b,iret_exc
.previous

ENTRY(native_irq_enable_sysexit)
	sti
	sysexit
#endif

KPROBE_ENTRY(int3)
KPROBE_ENTRY(int3)
	RING0_INT_FRAME
	RING0_INT_FRAME
	pushl $-1			# mark this as an int
	pushl $-1			# mark this as an int
Loading