Skip to content

Commit

Permalink
[PATCH] paravirt: header and stubs for paravirtualisation
Browse files Browse the repository at this point in the history
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: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Zachary Amsden <zach@vmware.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
  • Loading branch information
Rusty Russell authored and Andi Kleen committed Dec 7, 2006
1 parent db91b88 commit d3561b7
Show file tree
Hide file tree
Showing 27 changed files with 890 additions and 58 deletions.
11 changes: 11 additions & 0 deletions arch/i386/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ config X86_ES7000

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
bool
default y
Expand Down
1 change: 1 addition & 0 deletions arch/i386/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/

#undef CONFIG_PARAVIRT
#include <linux/linkage.h>
#include <linux/vmalloc.h>
#include <linux/screen_info.h>
Expand Down
1 change: 1 addition & 0 deletions arch/i386/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ obj-$(CONFIG_VM86) += vm86.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_PARAVIRT) += paravirt.o

EXTRA_AFLAGS := -traditional

Expand Down
10 changes: 10 additions & 0 deletions arch/i386/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,14 @@ void foo(void)
BLANK();
OFFSET(PDA_cpu, i386_pda, cpu_number);
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
}
34 changes: 27 additions & 7 deletions arch/i386/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ DF_MASK = 0x00000400
NT_MASK = 0x00004000
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
#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF
#else
Expand Down Expand Up @@ -416,6 +409,20 @@ ldt_ss:
jnz restore_nocheck
testl $0x00400000, %eax # returning to 32bit stack?
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,
* try to fix the higher word of ESP, as the CPU
* won't restore it.
Expand Down Expand Up @@ -833,6 +840,19 @@ nmi_espfix_stack:
.previous
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)
RING0_INT_FRAME
pushl $-1 # mark this as an int
Expand Down
5 changes: 4 additions & 1 deletion arch/i386/kernel/i8259.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,10 @@ void __init init_ISA_irqs (void)
}
}

void __init init_IRQ(void)
/* Overridden in paravirt.c */
void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));

void __init native_init_IRQ(void)
{
int i;

Expand Down
Loading

0 comments on commit d3561b7

Please sign in to comment.