paravirt patches - the non-integration part
Subsystems (2)
cover paravirt patches - the non-integration part
Hi,
This series corresponds do older patches in the paravirt series that was neither already applied, nor I will touch again. In general, they do not touch code that can be unified (at least, without being the unification a big problem on its own).
They passed through this list a lot of times, so I feel them ready for inclusion, unless someone opposes.
As with the other patches, they apply to the top of linux-2.6-x86:mm
PATCH 1/6 export math_state_restore
Export math_state_restore symbol, so it can be used for hypervisors. They are commonly loaded as modules (lguest being an example).
--- arch/x86/kernel/traps_64.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/x86/kernel/traps_64.c +1 -0
@@ -1073,6 +1073,7 @@ asmlinkage void math_state_restore(void)task_thread_info (me)->status |=TS_USEDFPU ; me->fpu_counter++; } +EXPORT_SYMBOL_GPL (math_state_restore);void __init trap_init (void ) {
Signature · 1 line
1.4.4.2
PATCH 1/6 export math_state_restore
In reply to Glauber de Oliveira CostaExport math_state_restore symbol, so it can be used for hypervisors. They are commonly loaded as modules (lguest being an example).
--- arch/x86/kernel/traps_64.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/x86/kernel/traps_64.c +1 -0
@@ -1073,6 +1073,7 @@ asmlinkage void math_state_restore(void)task_thread_info (me)->status |=TS_USEDFPU ; me->fpu_counter++; } +EXPORT_SYMBOL_GPL (math_state_restore);void __init trap_init (void ) {
Signature · 1 line
1.4.4.2
PATCH 2/6 export cpu_gdt_descr
With paravirualization, hypervisors needs to handle the gdt, that was right to this point only used at very early inialization code. Hypervisors (lguest being the current case) are commonly modules, so make it an export
--- arch/x86/kernel/x8664_ksyms_64.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
arch/x86/kernel/x8664_ksyms_64.c +6 -0
@@ -8,6 +8,7 @@#include <asm/processor.h> #include <asm/uaccess.h> #include <asm/pgtable.h> +#include <asm/desc.h> EXPORT_SYMBOL (kernel_thread);
@@ -53,3 +54,8 @@ EXPORT_SYMBOL(init_level4_pgt);EXPORT_SYMBOL (load_gs_index);EXPORT_SYMBOL (_proxy_pda); + +#ifdef CONFIG_PARAVIRT +/* Virtualized guests may want to use it */ +EXPORT_SYMBOL_GPL (cpu_gdt_descr); +#endif
Signature · 1 line
1.4.4.2
PATCH 2/6 export cpu_gdt_descr
In reply to Glauber de Oliveira CostaWith paravirualization, hypervisors needs to handle the gdt, that was right to this point only used at very early inialization code. Hypervisors (lguest being the current case) are commonly modules, so make it an export
--- arch/x86/kernel/x8664_ksyms_64.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
arch/x86/kernel/x8664_ksyms_64.c +6 -0
@@ -8,6 +8,7 @@#include <asm/processor.h> #include <asm/uaccess.h> #include <asm/pgtable.h> +#include <asm/desc.h> EXPORT_SYMBOL (kernel_thread);
@@ -53,3 +54,8 @@ EXPORT_SYMBOL(init_level4_pgt);EXPORT_SYMBOL (load_gs_index);EXPORT_SYMBOL (_proxy_pda); + +#ifdef CONFIG_PARAVIRT +/* Virtualized guests may want to use it */ +EXPORT_SYMBOL_GPL (cpu_gdt_descr); +#endif
Signature · 1 line
1.4.4.2
PATCH 3/6 turn priviled operation into a macro in head_64.S
under paravirt, read cr2 cannot be issued directly anymore. So wrap it in a macro, defined to the operation itself in case paravirt is off, but to something else if we have paravirt in the game
--- arch/x86/kernel/head_64.S | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
arch/x86/kernel/head_64.S +8 -1
@@ -19,6 +19,13 @@ #include <asm/msr.h> #include <asm/cache.h> +#ifdef CONFIG_PARAVIRT +#include <asm/asm-offsets.h> +#include <asm/paravirt.h> +#else +#define GET_CR2_INTO_RCX movq %cr2, %rcx +#endif + /* we are not able to switch in one step to the final KERNEL ADRESS SPACE * because we need identity-mapped pages. *
@@ -267,7 +274,7 @@ ENTRY(early_idt_handler) xorl %eax,%eax movq 8(%rsp),%rsi # get rip movq (%rsp),%rdx - movq %cr2,%rcx + GET_CR2_INTO_RCX leaq early_idt_msg(%rip),%rdi call early_printk cmpl $2,early_recursion_flag(%rip)
Signature · 1 line
1.4.4.2
PATCH 3/6 turn priviled operation into a macro in head_64.S
In reply to Glauber de Oliveira Costaunder paravirt, read cr2 cannot be issued directly anymore. So wrap it in a macro, defined to the operation itself in case paravirt is off, but to something else if we have paravirt in the game
--- arch/x86/kernel/head_64.S | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
arch/x86/kernel/head_64.S +8 -1
@@ -19,6 +19,13 @@ #include <asm/msr.h> #include <asm/cache.h> +#ifdef CONFIG_PARAVIRT +#include <asm/asm-offsets.h> +#include <asm/paravirt.h> +#else +#define GET_CR2_INTO_RCX movq %cr2, %rcx +#endif + /* we are not able to switch in one step to the final KERNEL ADRESS SPACE * because we need identity-mapped pages. *
@@ -267,7 +274,7 @@ ENTRY(early_idt_handler) xorl %eax,%eax movq 8(%rsp),%rsi # get rip movq (%rsp),%rdx - movq %cr2,%rcx + GET_CR2_INTO_RCX leaq early_idt_msg(%rip),%rdi call early_printk cmpl $2,early_recursion_flag(%rip)
Signature · 1 line
1.4.4.2
PATCH 4/6 prepare time related functions for paravirt
This patch add provisions for time related functions so they can be later replaced by paravirt versions.
it basically encloses {g,s}et_wallclock inside the already existent functions update_persistent_clock and read_persistent_clock, and defines {s,g}et_wallclock to the core of such functions.
it also allow for a later-on-game time initialization, as done by i386. Paravirt guests can set a function to do their own initialization this way.
--- arch/x86/kernel/time_64.c | 12 +++++++++--- include/asm-x86/time.h | 26 +++++++++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-)
arch/x86/kernel/time_64.c +9 -3
@@ -21,6 +21,8 @@#include <asm/hpet.h> #include <asm/nmi.h> #include <asm/vgtod.h> +#include <asm/time.h> +#include <asm/timer.h> volatile unsigned long __jiffies __section_jiffies =INITIAL_JIFFIES ;
@@ -54,7 +56,7 @@ static irqreturn_t timer_event_interrupt(int irq, void *dev_id)/* calibrate_cpu is used on systems with fixed rate TSCs to determine * processor frequency */ #define TICK_COUNT 100000000 -static unsigned int __init tsc_calibrate_cpu_khz (void ) +unsigned long __init native_calculate_cpu_khz (void ) {int tsc_start, tsc_now;int i, no_ctr_free;
@@ -104,20 +106,23 @@ static struct irqaction irq0 = { .name = "timer" }; -void __init time_init (void ) +void __init hpet_time_init (void ) {if (!hpet_enable ())setup_pit_timer ();setup_irq (0 , &irq0); +} +void __init time_init (void ) +{tsc_calibrate (); cpu_khz = tsc_khz;if (cpu_has (&boot_cpu_data,X86_FEATURE_CONSTANT_TSC ) && boot_cpu_data.x86_vendor ==X86_VENDOR_AMD && boot_cpu_data.x86 ==16 ) - cpu_khz =tsc_calibrate_cpu_khz (); + cpu_khz =calculate_cpu_khz ();if (unsynchronized_tsc ())mark_tsc_unstable ("TSCs unsynchronized" );
@@ -130,4 +135,5 @@ void __init time_init(void)printk (KERN_INFO "time.c: Detected %d.%03d MHz processor.\n" , cpu_khz /1000 , cpu_khz %1000 );init_tsc_clocksource (); + late_time_init =choose_time_init (); }
include/asm-x86/time.h +21 -5
@@ -1,8 +1,12 @@ -#ifndef _ASMi386_TIME_H -#define _ASMi386_TIME_H +#ifndef _ASMX86_TIME_H +#define _ASMX86_TIME_H + +extern void (*late_time_init)(void); +extern void hpet_time_init(void); -#include <linux/efi.h> #include <asm/mc146818rtc.h> +#ifdef CONFIG_X86_32 +#include <linux/efi.h> static inline unsigned long native_get_wallclock(void) {
@@ -28,8 +32,20 @@ static inline int native_set_wallclock(unsigned long nowtime) return retval; } -extern void (*late_time_init)(void ); -extern void hpet_time_init (void ); +#else +extern void native_time_init_hook (void ); + +static inline unsigned long native_get_wallclock (void ) +{ +return mach_get_cmos_time (); +} + +static inline int native_set_wallclock (unsigned long nowtime) +{ +return mach_set_rtc_mmss (nowtime); +} + +#endif #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h>
Signature · 1 line
1.4.4.2
PATCH 4/6 prepare time related functions for paravirt
In reply to Glauber de Oliveira CostaThis patch add provisions for time related functions so they can be later replaced by paravirt versions.
it basically encloses {g,s}et_wallclock inside the already existent functions update_persistent_clock and read_persistent_clock, and defines {s,g}et_wallclock to the core of such functions.
it also allow for a later-on-game time initialization, as done by i386. Paravirt guests can set a function to do their own initialization this way.
--- arch/x86/kernel/time_64.c | 12 +++++++++--- include/asm-x86/time.h | 26 +++++++++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-)
arch/x86/kernel/time_64.c +9 -3
@@ -21,6 +21,8 @@#include <asm/hpet.h> #include <asm/nmi.h> #include <asm/vgtod.h> +#include <asm/time.h> +#include <asm/timer.h> volatile unsigned long __jiffies __section_jiffies =INITIAL_JIFFIES ;
@@ -54,7 +56,7 @@ static irqreturn_t timer_event_interrupt(int irq, void *dev_id)/* calibrate_cpu is used on systems with fixed rate TSCs to determine * processor frequency */ #define TICK_COUNT 100000000 -static unsigned int __init tsc_calibrate_cpu_khz (void ) +unsigned long __init native_calculate_cpu_khz (void ) {int tsc_start, tsc_now;int i, no_ctr_free;
@@ -104,20 +106,23 @@ static struct irqaction irq0 = { .name = "timer" }; -void __init time_init (void ) +void __init hpet_time_init (void ) {if (!hpet_enable ())setup_pit_timer ();setup_irq (0 , &irq0); +} +void __init time_init (void ) +{tsc_calibrate (); cpu_khz = tsc_khz;if (cpu_has (&boot_cpu_data,X86_FEATURE_CONSTANT_TSC ) && boot_cpu_data.x86_vendor ==X86_VENDOR_AMD && boot_cpu_data.x86 ==16 ) - cpu_khz =tsc_calibrate_cpu_khz (); + cpu_khz =calculate_cpu_khz ();if (unsynchronized_tsc ())mark_tsc_unstable ("TSCs unsynchronized" );
@@ -130,4 +135,5 @@ void __init time_init(void)printk (KERN_INFO "time.c: Detected %d.%03d MHz processor.\n" , cpu_khz /1000 , cpu_khz %1000 );init_tsc_clocksource (); + late_time_init =choose_time_init (); }
include/asm-x86/time.h +21 -5
@@ -1,8 +1,12 @@ -#ifndef _ASMi386_TIME_H -#define _ASMi386_TIME_H +#ifndef _ASMX86_TIME_H +#define _ASMX86_TIME_H + +extern void (*late_time_init)(void); +extern void hpet_time_init(void); -#include <linux/efi.h> #include <asm/mc146818rtc.h> +#ifdef CONFIG_X86_32 +#include <linux/efi.h> static inline unsigned long native_get_wallclock(void) {
@@ -28,8 +32,20 @@ static inline int native_set_wallclock(unsigned long nowtime) return retval; } -extern void (*late_time_init)(void ); -extern void hpet_time_init (void ); +#else +extern void native_time_init_hook (void ); + +static inline unsigned long native_get_wallclock (void ) +{ +return mach_get_cmos_time (); +} + +static inline int native_set_wallclock (unsigned long nowtime) +{ +return mach_set_rtc_mmss (nowtime); +} + +#endif #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h>
Signature · 1 line
1.4.4.2
PATCH 5/6 tweak io_64.h for paravirt.
We need something here because we can't call in and out instructions directly. However, we have to be careful, because no indirections are allowed in misc_64.c , and paravirt_ops is a kind of one. So just call it directly there
--- arch/x86/boot/compressed/misc_64.c | 6 +++++ include/asm-x86/io_64.h | 37 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-)
arch/x86/boot/compressed/misc_64.c +6 -0
@@ -9,6 +9,12 @@* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ +/* +* we have to be careful, because no indirections are allowed here, and +* paravirt_ops is a kind of one. As it will only run in baremetal anyway, +* we just keep it from happening +*/ +#undef CONFIG_PARAVIRT#define _LINUX_STRING_H_ 1#define __LINUX_BITMAP_H 1
include/asm-x86/io_64.h +30 -7
@@ -35,12 +35,24 @@* - Arnaldo Carvalho de Melo <[email protected]> */ -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +static inline void native_io_delay (void ) +{ + asmvolatile ("outb %%al,$0x80" : : :"memory" ); +} -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#if defined(CONFIG_PARAVIRT ) +#include <asm/paravirt.h> #else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO + +static inline void slow_down_io (void ) +{ +native_io_delay (); +#ifdef REALLY_SLOW_IO +native_io_delay (); +native_io_delay (); +native_io_delay (); +#endif +}#endif /*
@@ -52,9 +64,15 @@ static inline void out##s(unsigned x value, unsigned short port) {#define __OUT2 (s,s1,s2) \ __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" +#ifndef REALLY_SLOW_IO +#define REALLY_SLOW_IO +#define UNSET_REALLY_SLOW_IO +#endif +#define __OUT (s,s1,x) \ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ -__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ +__OUT1(s##_p, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port)); \ + slow_down_io(); }#define __IN1 (s) \ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
@@ -63,8 +81,13 @@ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" #define __IN(s,s1,i...) \ -__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ -__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); return _v; } \ +__IN1(s##_p) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); \ + slow_down_io(); return _v; } + +#ifdef UNSET_REALLY_SLOW_IO +#undef REALLY_SLOW_IO +#endif #define __INS (s) \ static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
Signature · 1 line
1.4.4.2
PATCH 5/6 tweak io_64.h for paravirt.
In reply to Glauber de Oliveira CostaWe need something here because we can't call in and out instructions directly. However, we have to be careful, because no indirections are allowed in misc_64.c , and paravirt_ops is a kind of one. So just call it directly there
--- arch/x86/boot/compressed/misc_64.c | 6 +++++ include/asm-x86/io_64.h | 37 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-)
arch/x86/boot/compressed/misc_64.c +6 -0
@@ -9,6 +9,12 @@* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ +/* +* we have to be careful, because no indirections are allowed here, and +* paravirt_ops is a kind of one. As it will only run in baremetal anyway, +* we just keep it from happening +*/ +#undef CONFIG_PARAVIRT#define _LINUX_STRING_H_ 1#define __LINUX_BITMAP_H 1
include/asm-x86/io_64.h +30 -7
@@ -35,12 +35,24 @@* - Arnaldo Carvalho de Melo <[email protected]> */ -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +static inline void native_io_delay (void ) +{ + asmvolatile ("outb %%al,$0x80" : : :"memory" ); +} -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#if defined(CONFIG_PARAVIRT ) +#include <asm/paravirt.h> #else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO + +static inline void slow_down_io (void ) +{ +native_io_delay (); +#ifdef REALLY_SLOW_IO +native_io_delay (); +native_io_delay (); +native_io_delay (); +#endif +}#endif /*
@@ -52,9 +64,15 @@ static inline void out##s(unsigned x value, unsigned short port) {#define __OUT2 (s,s1,s2) \ __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" +#ifndef REALLY_SLOW_IO +#define REALLY_SLOW_IO +#define UNSET_REALLY_SLOW_IO +#endif +#define __OUT (s,s1,x) \ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ -__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ +__OUT1(s##_p, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port)); \ + slow_down_io(); }#define __IN1 (s) \ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
@@ -63,8 +81,13 @@ static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" #define __IN(s,s1,i...) \ -__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ -__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); return _v; } \ +__IN1(s##_p) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); \ + slow_down_io(); return _v; } + +#ifdef UNSET_REALLY_SLOW_IO +#undef REALLY_SLOW_IO +#endif #define __INS (s) \ static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
Signature · 1 line
1.4.4.2
PATCH 6/6 prepare x86_64 architecture initialization for paravirt
This patch prepares the x86_64 architecture initialization for paravirt. It requires a memory initialization step, which is done by implementing 64-bit version for machine_specific_memory_setup, and putting an ARCH_SETUP hook, for guest-dependent initialization. This last step is done akin to i386
--- arch/x86/kernel/e820_64.c | 9 +++++++-- arch/x86/kernel/setup_64.c | 28 +++++++++++++++++++++++++++- arch/x86/kernel/smpboot_64.c | 4 ++-- include/asm-x86/setup.h | 11 ++++++++--- 4 files changed, 44 insertions(+), 8 deletions(-)
arch/x86/kernel/e820_64.c +7 -2
@@ -638,8 +638,10 @@ static void early_panic(char *msg)panic (msg); } -void __init setup_memory_region (void ) +/* We're not void only for x86 32-bit compat */ +char *__init machine_specific_memory_setup (void ) { +char *who ="BIOS-e820" ;/* * Try to copy the BIOS-supplied E820-map. *
@@ -650,7 +652,10 @@ void __init setup_memory_region(void)if (copy_e820_map (boot_params.e820_map, boot_params.e820_entries) <0 )early_panic ("Cannot find a valid memory map" );printk (KERN_INFO "BIOS-provided physical RAM map:\n" ); -e820_print_map ("BIOS-e820" ); +e820_print_map (who); + +/* In case someone cares... */ +return who; }static int __init parse_memopt (char *p)
arch/x86/kernel/setup_64.c +27 -1
@@ -39,6 +39,7 @@#include <linux/dmi.h> #include <linux/dma-mapping.h> #include <linux/ctype.h> +#include <linux/uaccess.h> #include <asm/mtrr.h> #include <asm/uaccess.h>
@@ -62,6 +63,12 @@#include <asm/mce.h> #include <asm/ds.h> +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt.h> +#else +#define ARCH_SETUP +#endif +/* * Machine setup.. */
@@ -246,6 +253,16 @@ static void discover_ebda(void)* 4K EBDA area at 0x40E */ ebda_addr = *(unsigned short *)__va (EBDA_ADDR_POINTER ); +/* +* There can be some situations, like paravirtualized guests, +* in which there is no available ebda information. In such +* case, just skip it +*/ +if (!ebda_addr) { + ebda_size =0 ; +return ; + } + ebda_addr <<=4 ; ebda_size = *(unsigned short *)__va (ebda_addr);
@@ -259,6 +276,12 @@ static void discover_ebda(void) ebda_size =64 *1024 ; } +/* Overridden in paravirt.c if CONFIG_PARAVIRT */ +void __attribute__((weak))memory_setup (void ) +{ +machine_specific_memory_setup (); +} +void __init setup_arch (char **cmdline_p) {unsigned i;
@@ -276,7 +299,10 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((boot_params.hdr.ram_size &RAMDISK_PROMPT_FLAG ) !=0 ); rd_doload = ((boot_params.hdr.ram_size &RAMDISK_LOAD_FLAG ) !=0 );#endif -setup_memory_region (); + +ARCH_SETUP + +memory_setup ();copy_edd ();if (!boot_params.hdr.root_flags)
arch/x86/kernel/smpboot_64.c +2 -2
@@ -369,7 +369,7 @@ void __cpuinit start_secondary(void)unlock_ipi_call_lock (); -setup_secondary_APIC_clock (); +setup_secondary_clock ();cpu_idle (); }
@@ -923,7 +923,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)* Set up local APIC timer on boot CPU. */ -setup_boot_APIC_clock (); +setup_boot_clock (); }/*
include/asm-x86/setup.h +8 -3
@@ -3,6 +3,13 @@#define COMMAND_LINE_SIZE 2048 +#ifndef __ASSEMBLY__ +char *machine_specific_memory_setup (void ); +#ifndef CONFIG_PARAVIRT +#define paravirt_post_allocator_init () do {} while (0) +#endif +#endif /* __ASSEMBLY__ */ +#ifdef __KERNEL__#ifdef __i386__
@@ -51,9 +58,7 @@ void __init add_memory_region(unsigned long long start,extern unsigned long init_pg_tables_end; -#ifndef CONFIG_PARAVIRT -#define paravirt_post_allocator_init () do {} while (0) -#endif +#endif /* __i386__ */ #endif /* _SETUP */
Signature · 1 line
1.4.4.2
PATCH 6/6 prepare x86_64 architecture initialization for paravirt
In reply to Glauber de Oliveira CostaThis patch prepares the x86_64 architecture initialization for paravirt. It requires a memory initialization step, which is done by implementing 64-bit version for machine_specific_memory_setup, and putting an ARCH_SETUP hook, for guest-dependent initialization. This last step is done akin to i386
--- arch/x86/kernel/e820_64.c | 9 +++++++-- arch/x86/kernel/setup_64.c | 28 +++++++++++++++++++++++++++- arch/x86/kernel/smpboot_64.c | 4 ++-- include/asm-x86/setup.h | 11 ++++++++--- 4 files changed, 44 insertions(+), 8 deletions(-)
arch/x86/kernel/e820_64.c +7 -2
@@ -638,8 +638,10 @@ static void early_panic(char *msg)panic (msg); } -void __init setup_memory_region (void ) +/* We're not void only for x86 32-bit compat */ +char *__init machine_specific_memory_setup (void ) { +char *who ="BIOS-e820" ;/* * Try to copy the BIOS-supplied E820-map. *
@@ -650,7 +652,10 @@ void __init setup_memory_region(void)if (copy_e820_map (boot_params.e820_map, boot_params.e820_entries) <0 )early_panic ("Cannot find a valid memory map" );printk (KERN_INFO "BIOS-provided physical RAM map:\n" ); -e820_print_map ("BIOS-e820" ); +e820_print_map (who); + +/* In case someone cares... */ +return who; }static int __init parse_memopt (char *p)
arch/x86/kernel/setup_64.c +27 -1
@@ -39,6 +39,7 @@#include <linux/dmi.h> #include <linux/dma-mapping.h> #include <linux/ctype.h> +#include <linux/uaccess.h> #include <asm/mtrr.h> #include <asm/uaccess.h>
@@ -62,6 +63,12 @@#include <asm/mce.h> #include <asm/ds.h> +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt.h> +#else +#define ARCH_SETUP +#endif +/* * Machine setup.. */
@@ -246,6 +253,16 @@ static void discover_ebda(void)* 4K EBDA area at 0x40E */ ebda_addr = *(unsigned short *)__va (EBDA_ADDR_POINTER ); +/* +* There can be some situations, like paravirtualized guests, +* in which there is no available ebda information. In such +* case, just skip it +*/ +if (!ebda_addr) { + ebda_size =0 ; +return ; + } + ebda_addr <<=4 ; ebda_size = *(unsigned short *)__va (ebda_addr);
@@ -259,6 +276,12 @@ static void discover_ebda(void) ebda_size =64 *1024 ; } +/* Overridden in paravirt.c if CONFIG_PARAVIRT */ +void __attribute__((weak))memory_setup (void ) +{ +machine_specific_memory_setup (); +} +void __init setup_arch (char **cmdline_p) {unsigned i;
@@ -276,7 +299,10 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((boot_params.hdr.ram_size &RAMDISK_PROMPT_FLAG ) !=0 ); rd_doload = ((boot_params.hdr.ram_size &RAMDISK_LOAD_FLAG ) !=0 );#endif -setup_memory_region (); + +ARCH_SETUP + +memory_setup ();copy_edd ();if (!boot_params.hdr.root_flags)
arch/x86/kernel/smpboot_64.c +2 -2
@@ -369,7 +369,7 @@ void __cpuinit start_secondary(void)unlock_ipi_call_lock (); -setup_secondary_APIC_clock (); +setup_secondary_clock ();cpu_idle (); }
@@ -923,7 +923,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)* Set up local APIC timer on boot CPU. */ -setup_boot_APIC_clock (); +setup_boot_clock (); }/*
include/asm-x86/setup.h +8 -3
@@ -3,6 +3,13 @@#define COMMAND_LINE_SIZE 2048 +#ifndef __ASSEMBLY__ +char *machine_specific_memory_setup (void ); +#ifndef CONFIG_PARAVIRT +#define paravirt_post_allocator_init () do {} while (0) +#endif +#endif /* __ASSEMBLY__ */ +#ifdef __KERNEL__#ifdef __i386__
@@ -51,9 +58,7 @@ void __init add_memory_region(unsigned long long start,extern unsigned long init_pg_tables_end; -#ifndef CONFIG_PARAVIRT -#define paravirt_post_allocator_init () do {} while (0) -#endif +#endif /* __i386__ */ #endif /* _SETUP */
Signature · 1 line
1.4.4.2
Quoted 11 lines · Glauber de Oliveira Costa
Hi,
This series corresponds do older patches in the paravirt series that was neither already applied, nor I will touch again. In general, they do not touch code that can be unified (at least, without being the unification a big problem on its own).
They passed through this list a lot of times, so I feel them ready for inclusion, unless someone opposes.
As with the other patches, they apply to the top of linux-2.6-x86:mm
thanks, i've picked them up into x86.git, they look certainly very clean.
Ingo
Quoted 11 lines · Glauber de Oliveira Costa
Hi,
This series corresponds do older patches in the paravirt series that was neither already applied, nor I will touch again. In general, they do not touch code that can be unified (at least, without being the unification a big problem on its own).
They passed through this list a lot of times, so I feel them ready for inclusion, unless someone opposes.
As with the other patches, they apply to the top of linux-2.6-x86:mm
thanks, i've picked them up into x86.git, they look certainly very clean.
Ingo