Skip to contentSkip to conversation

x86_64 paravirt_ops port

PATCH In review Glauber de Oliveira Costa 3 participants 4 messages Jan 8, 2007 – Jan 9, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86_64 paravirt_ops port

Hi all,

I've been working on a port of paravirt_ops for the x86_64 architectures for a couple of days. Here's the result so far. I'm posting it soon for early cooments. The more, the better.

It's obviously based on the previous work for i386, with the needed modifications. By now, I'm able to boot a bare metal kernel, but there are still some known issues, that are in my TODO list for the next days. Highlighting,

* There are still some hardcoded references to lidt instructions spread over, that need to be replaced
* Code to init guests, as in 32-bit's startup_32
* patching works (sometimes). Still work needed to stabilize it.

So, here it goes.
Comments welcome

Signature · 3 lines
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
arch/x86_64/Kconfig +12 -0
Index: linux-2.6.19-quilt/arch/x86_64/Kconfig
===================================================================
@@ -336,6 +336,18 @@ config NODES_SHIFT
 
 # Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig.
 
+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 X86_64_ACPI_NUMA
        bool "ACPI NUMA detection"
        depends on NUMA
arch/x86_64/Kconfig.debug +11 -0
Index: linux-2.6.19-quilt/arch/x86_64/Kconfig.debug
===================================================================
@@ -55,6 +55,17 @@ config DEBUG_STACK_USAGE
 
 	  This option will slow down process creation somewhat.
 
+config DEBUG_PARAVIRT
+       bool "Enable some paravirtualization debugging"
+       default y
+       depends on PARAVIRT && DEBUG_KERNEL
+       help
+         Currently deliberately clobbers regs which are allowed to be
+         clobbered in inlined paravirt hooks, even in native mode.
+         If turning this off solves a problem, then DISABLE_INTERRUPTS() or
+         ENABLE_INTERRUPTS() is lying about what registers can be clobbered.
+
+
 #config X86_REMOTE_DEBUG
 #       bool "kgdb debugging stub"
 
arch/x86_64/kernel/asm-offsets.c +13 -0
Index: linux-2.6.19-quilt/arch/x86_64/kernel/asm-offsets.c
===================================================================
@@ -15,6 +15,7 @@
 #include <asm/segment.h>
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
+#include <asm/paravirt.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -71,5 +72,17 @@ int main(void)
 	DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
 	BLANK();
 	DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
+
+#ifdef CONFIG_PARAVIRT
+#define ENTRY(entry) DEFINE(PARAVIRT_ ## entry, offsetof(struct paravirt_ops, entry))
+	BLANK();
+	ENTRY(paravirt_enabled);
+	ENTRY(irq_disable);
+	ENTRY(irq_enable);
+	ENTRY(irq_enable_sysexit);
+	ENTRY(iret);
+	ENTRY(read_cr0);
+#endif
+
 	return 0;
 }
arch/x86_64/kernel/entry.S +16 -0
Index: linux-2.6.19-quilt/arch/x86_64/kernel/entry.S
===================================================================
@@ -1064,6 +1064,22 @@ KPROBE_ENTRY(int3)
  	CFI_ENDPROC
 KPROBE_END(int3)
 
+#ifdef CONFIG_PARAVIRT
+ENTRY(native_iret)
+1:	iretq
+.section __ex_table,"a"
+	.align 8
+	.quad 1b, bad_iret
+.previous
+ENDPROC(native_iret)
+
+ENTRY(native_irq_enable_sysexit)
+	sti
+	sysretq
+ENDPROC(native_irq_enable_sysexit)
+
+#endif /* CONFIG_PARAVIRT */
+
 ENTRY(overflow)
 	zeroentry do_overflow
 END(overflow)
arch/x86_64/kernel/head64.c +1 -1
Index: linux-2.6.19-quilt/arch/x86_64/kernel/head64.c
===================================================================
@@ -70,7 +70,7 @@ void __init x86_64_start_kernel(char * r
 	 * switch to init_level4_pgt from boot_level4_pgt
 	 */
 	memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t));
-	asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
+	write_cr3(__pa_symbol(&init_level4_pgt));
 
  	for (i = 0; i < NR_CPUS; i++)
  		cpu_pda(i) = &boot_cpu_pda[i];
arch/x86_64/kernel/i8259.c +4 -1
Index: linux-2.6.19-quilt/arch/x86_64/kernel/i8259.c
===================================================================
@@ -501,7 +501,10 @@ static int __init init_timer_sysfs(void)
 
 device_initcall(init_timer_sysfs);
 
-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;
 
arch/x86_64/kernel/Makefile +2 -0
Index: linux-2.6.19-quilt/arch/x86_64/kernel/Makefile
===================================================================
@@ -41,6 +41,8 @@ obj-$(CONFIG_AUDIT)		+= audit.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_PCI)		+= early-quirks.o
 
+obj-$(CONFIG_PARAVIRT)		+= paravirt.o
+
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
 
arch/x86_64/kernel/process.c +5 -5
Index: linux-2.6.19-quilt/arch/x86_64/kernel/process.c
===================================================================
@@ -334,10 +334,10 @@ void __show_regs(struct pt_regs * regs)
 	rdmsrl(MSR_GS_BASE, gs); 
 	rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 
 
-	asm("movq %%cr0, %0": "=r" (cr0));
-	asm("movq %%cr2, %0": "=r" (cr2));
-	asm("movq %%cr3, %0": "=r" (cr3));
-	asm("movq %%cr4, %0": "=r" (cr4));
+	cr0 = read_cr0();
+	cr2 = read_cr2();
+	cr3 = read_cr3();
+	cr4 = read_cr4();
 
 	printk("FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 
 	       fs,fsindex,gs,gsindex,shadowgs); 
@@ -574,7 +574,7 @@ __switch_to(struct task_struct *prev_p, 
 	/*
 	 * Reload esp0, LDT and the page table pointer:
 	 */
-	tss->rsp0 = next->rsp0;
+	load_rsp0(tss,next);
 
 	/* 
 	 * Switch DS and ES.
arch/x86_64/kernel/setup.c +6 -1
Index: linux-2.6.19-quilt/arch/x86_64/kernel/setup.c
===================================================================
@@ -356,7 +356,7 @@ void __init setup_arch(char **cmdline_p)
 	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 #endif
-	setup_memory_region();
+	memory_setup();
 	copy_edd();
 
 	if (!MOUNT_ROOT_RDONLY)
@@ -561,6 +561,11 @@ static int __cpuinit get_model_name(stru
 	return 1;
 }
 
+/* Overridden in paravirt.c if CONFIG_PARAVIRT */
+void __attribute__((weak)) memory_setup(void)
+{
+       return setup_memory_region();
+}
 
 static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
arch/x86_64/kernel/smpboot.c +1 -1
Index: linux-2.6.19-quilt/arch/x86_64/kernel/smpboot.c
===================================================================
@@ -848,7 +848,7 @@ do_rest:
 	start_rip = setup_trampoline();
 
 	init_rsp = c_idle.idle->thread.rsp;
-	per_cpu(init_tss,cpu).rsp0 = init_rsp;
+	load_rsp0(&per_cpu(init_tss,cpu), &c_idle.idle->thread);
 	initial_code = start_secondary;
 	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
 
arch/x86_64/kernel/time.c +28 -13

99 lines not on this page · raw message

arch/x86_64/kernel/reboot.c +1 -1
Index: linux-2.6.19-quilt/arch/x86_64/kernel/reboot.c
===================================================================
@@ -131,7 +131,7 @@ void machine_emergency_restart(void)
 		}
 
 		case BOOT_TRIPLE: 
-			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			load_idt((const struct desc_struct *)&no_idt);
 			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
arch/x86_64/kernel/vmlinux.lds.S +14 -2
Index: linux-2.6.19-quilt/arch/x86_64/kernel/vmlinux.lds.S
===================================================================
@@ -58,6 +58,12 @@ SECTIONS
 	CONSTRUCTORS
 	} :data
 
+  .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
+	__start_paravirtprobe = .;
+	*(.paravirtprobe)
+	__stop_paravirtprobe = .;
+  }
+
   _edata = .;			/* End of data section */
 
   . = ALIGN(PAGE_SIZE);
@@ -177,14 +183,20 @@ SECTIONS
   __con_initcall_end = .;
   SECURITY_INIT
   . = ALIGN(8);
-  __alt_instructions = .;
   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+	__alt_instructions = .;
 	*(.altinstructions)
+  	__alt_instructions_end = .;
   }
-  __alt_instructions_end = .; 
   .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
 	*(.altinstr_replacement)
   }
+  . = ALIGN(8);
+  .parainstructions : AT(ADDR(.parainstructions)  - LOAD_OFFSET) {
+	__start_parainstructions = .;
+	*(.parainstructions)
+	__stop_parainstructions = .;
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
   .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
arch/x86_64/mm/fault.c +2 -2
Index: linux-2.6.19-quilt/arch/x86_64/mm/fault.c
===================================================================
@@ -180,7 +180,7 @@ void dump_pagetable(unsigned long addres
 	pmd_t *pmd;
 	pte_t *pte;
 
-	asm("movq %%cr3,%0" : "=r" (pgd));
+	pgd = (pgd_t *)read_cr3();
 
 	pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); 
 	pgd += pgd_index(address);
@@ -347,7 +347,7 @@ asmlinkage void __kprobes do_page_fault(
 	prefetchw(&mm->mmap_sem);
 
 	/* get the address */
-	__asm__("movq %%cr2,%0":"=r" (address));
+	address = read_cr2();
 
 	info.si_code = SEGV_MAPERR;
 
arch/x86_64/mm/init.c +2 -2
Index: linux-2.6.19-quilt/arch/x86_64/mm/init.c
===================================================================
@@ -384,7 +384,7 @@ void __meminit init_memory_mapping(unsig
 	} 
 
 	if (!after_bootmem)
-		asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
+		mmu_cr4_features = read_cr4();
 	__flush_tlb_all();
 }
 
@@ -398,7 +398,7 @@ void __cpuinit zap_low_mappings(int cpu)
 		 * For AP's, zap the low identity mappings by changing the cr3
 		 * to init_level4_pgt and doing local flush tlb all
 		 */
-		asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
+		write_cr3(__pa_symbol(&init_level4_pgt));
 	}
 	__flush_tlb_all();
 }
include/asm-x86_64/apic.h +10 -2
Index: linux-2.6.19-quilt/include/asm-x86_64/apic.h
===================================================================
@@ -37,16 +37,24 @@ struct pt_regs;
  * Basic functions accessing APICs.
  */
 
-static __inline void apic_write(unsigned long reg, unsigned int v)
+static __inline void native_apic_write(unsigned long reg, unsigned int v)
 {
 	*((volatile unsigned int *)(APIC_BASE+reg)) = v;
 }
 
-static __inline unsigned int apic_read(unsigned long reg)
+static __inline unsigned int native_apic_read(unsigned long reg)
 {
 	return *((volatile unsigned int *)(APIC_BASE+reg));
 }
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+#define apic_write native_apic_write
+#define apic_read native_apic_read
+
+#endif /* CONFIG_PARAVIRT */
+
 static __inline__ void apic_wait_icr_idle(void)
 {
 	while (apic_read( APIC_ICR ) & APIC_ICR_BUSY)
include/asm-x86_64/desc.h +35 -20

93 lines not on this page · raw message

include/asm-x86_64/irqflags.h +16 -4
Index: linux-2.6.19-quilt/include/asm-x86_64/irqflags.h
===================================================================
@@ -11,6 +11,16 @@
 #define _ASM_IRQFLAGS_H
 
 #ifndef __ASSEMBLY__
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & (1 << 9));
+}
+
+#else
+
 /*
  * Interrupt control:
  */
@@ -30,8 +40,6 @@ static inline unsigned long __raw_local_
 	return flags;
 }
 
-#define raw_local_save_flags(flags) \
-		do { (flags) = __raw_local_save_flags(); } while (0)
 
 static inline void raw_local_irq_restore(unsigned long flags)
 {
@@ -100,8 +108,6 @@ static inline unsigned long __raw_local_
 	return flags;
 }
 
-#define raw_local_irq_save(flags) \
-		do { (flags) = __raw_local_irq_save(); } while (0)
 
 static inline int raw_irqs_disabled(void)
 {
@@ -128,6 +134,7 @@ static inline void halt(void)
 	__asm__ __volatile__("hlt": : :"memory");
 }
 
+#endif /* CONFIG_PARAVIRT */
 #else /* __ASSEMBLY__: */
 # ifdef CONFIG_TRACE_IRQFLAGS
 #  define TRACE_IRQS_ON		call trace_hardirqs_on_thunk
@@ -138,4 +145,9 @@ static inline void halt(void)
 # endif
 #endif
 
+#define raw_local_save_flags(flags) \
+		do { (flags) = __raw_local_save_flags(); } while (0)
+
+#define raw_local_irq_save(flags) \
+		do { (flags) = __raw_local_irq_save(); } while (0)
 #endif
include/asm-x86_64/irq.h +3 -0
Index: linux-2.6.19-quilt/include/asm-x86_64/irq.h
===================================================================
@@ -46,6 +46,9 @@ static __inline__ int irq_canonicalize(i
 extern void fixup_irqs(cpumask_t map);
 #endif
 
+void init_IRQ(void);
+void native_init_IRQ(void);
+
 #define __ARCH_HAS_DO_SOFTIRQ 1
 
 #endif /* _ASM_IRQ_H */
include/asm-x86_64/mmu_context.h +2 -2
Index: linux-2.6.19-quilt/include/asm-x86_64/mmu_context.h
===================================================================
@@ -42,7 +42,7 @@ static inline void switch_mm(struct mm_s
 		load_cr3(next->pgd);
 
 		if (unlikely(next->context.ldt != prev->context.ldt)) 
-			load_LDT_nolock(&next->context, cpu);
+			load_LDT_nolock(&next->context);
 	}
 #ifdef CONFIG_SMP
 	else {
@@ -55,7 +55,7 @@ static inline void switch_mm(struct mm_s
 			 * to make sure to use no freed page tables.
 			 */
 			load_cr3(next->pgd);
-			load_LDT_nolock(&next->context, cpu);
+			load_LDT_nolock(&next->context);
 		}
 	}
 #endif
include/asm-x86_64/page.h +29 -1
Index: linux-2.6.19-quilt/include/asm-x86_64/page.h
===================================================================
@@ -64,16 +64,44 @@ typedef struct { unsigned long pgd; } pg
 
 typedef struct { unsigned long pgprot; } pgprot_t;
 
+static inline unsigned long native_pte_val(pte_t pte)
+{
+	return pte.pte;
+}
+
+static inline unsigned long native_pud_val(pud_t pud)
+{
+	return pud.pud;
+}
+
+
+static inline unsigned long native_pmd_val(pmd_t pmd)
+{
+	return pmd.pmd;
+}
+
+static inline unsigned long native_pgd_val(pgd_t pgd)
+{
+	return pgd.pgd;
+}
+
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+
 #define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
 #define pud_val(x)	((x).pud)
 #define pgd_val(x)	((x).pgd)
-#define pgprot_val(x)	((x).pgprot)
 
 #define __pte(x) ((pte_t) { (x) } )
 #define __pmd(x) ((pmd_t) { (x) } )
 #define __pud(x) ((pud_t) { (x) } )
 #define __pgd(x) ((pgd_t) { (x) } )
+#endif /* CONFIG_PARAVIRT */
+
+#define pgprot_val(x)	((x).pgprot)
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
 #define __PHYSICAL_START	((unsigned long)CONFIG_PHYSICAL_START)
include/asm-x86_64/pgtable.h +49 -40

143 lines not on this page · raw message

include/asm-x86_64/processor.h +5 -0
Index: linux-2.6.19-quilt/include/asm-x86_64/processor.h
===================================================================
@@ -299,6 +299,10 @@ struct thread_struct {
 	set_fs(USER_DS);							 \
 } while(0) 
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+#define paravirt_enabled() 0
 #define get_debugreg(var, register)				\
 		__asm__("movq %%db" #register ", %0"		\
 			:"=r" (var))
@@ -306,6 +310,7 @@ struct thread_struct {
 		__asm__("movq %0,%%db" #register		\
 			: /* no output */			\
 			:"r" (value))
+#endif
 
 struct task_struct;
 struct mm_struct;
include/asm-x86_64/spinlock.h +4 -0
Index: linux-2.6.19-quilt/include/asm-x86_64/spinlock.h
===================================================================
@@ -6,6 +6,10 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#endif
+
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  *
include/asm-x86_64/system.h +8 -3
Index: linux-2.6.19-quilt/include/asm-x86_64/system.h
===================================================================
@@ -65,6 +65,9 @@ extern void load_gs_index(unsigned); 
 		".previous"			\
 		: :"r" (value), "r" (0))
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
 /*
  * Clear and set 'TS' bit respectively
  */
@@ -99,12 +102,14 @@ static inline unsigned long read_cr4(voi
 static inline void write_cr4(unsigned long val)
 { 
 	asm volatile("movq %0,%%cr4" :: "r" (val));
-} 
-
-#define stts() write_cr0(8 | read_cr0())
+}
 
 #define wbinvd() \
 	__asm__ __volatile__ ("wbinvd": : :"memory");
+#endif /* CONFIG_PARAVIRT */
+
+#define stts() write_cr0(8 | read_cr0())
+
 
 /*
  * On SMP systems, when the scheduler does migration-cost autodetection,
include/asm-x86_64/time.h new file +18 -0
Index: linux-2.6.19-quilt/include/asm-x86_64/time.h
===================================================================
@@ -0,0 +1,18 @@
+#ifndef _ASM_X86_64_TIME_H
+#define _ASM_X86_64_TIME_H
+
+inline void time_init_hook(void);
+unsigned long do_get_cmos_time(void);
+void do_set_rtc_mmss(unsigned long nowtime);
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else /* !CONFIG_PARAVIRT */
+
+#define get_wallclock() do_get_cmos_time()
+#define set_wallclock(x) do_set_rtc_mmss(x)
+#define do_time_init() time_init_hook()
+
+#endif /* CONFIG_PARAVIRT */
+
+#endif
include/asm-x86_64/tlbflush.h +11 -3
Index: linux-2.6.19-quilt/include/asm-x86_64/tlbflush.h
===================================================================
@@ -4,6 +4,7 @@
 #include <linux/mm.h>
 #include <asm/processor.h>
 
+
 static inline unsigned long get_cr3(void)
 {
 	unsigned long cr3;
@@ -16,7 +17,7 @@ static inline void set_cr3(unsigned long
 	asm volatile("mov %0,%%cr3" :: "r" (cr3) : "memory");
 }
 
-static inline void __flush_tlb(void)
+static inline void __native_flush_tlb(void)
 {
 	set_cr3(get_cr3());
 }
@@ -33,17 +34,24 @@ static inline void set_cr4(unsigned long
 	asm volatile("mov %0,%%cr4" :: "r" (cr4) : "memory");
 }
 
-static inline void __flush_tlb_all(void)
+static inline void __native_flush_tlb_all(void)
 {
 	unsigned long cr4 = get_cr4();
 	set_cr4(cr4 & ~X86_CR4_PGE);	/* clear PGE */
 	set_cr4(cr4);			/* write old PGE again and flush TLBs */
 }
 
-#define __flush_tlb_one(addr) \
+#define __native_flush_tlb_one(addr) \
 	__asm__ __volatile__("invlpg (%0)" :: "r" (addr) : "memory")
 
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+#define __flush_tlb __native_flush_tlb
+#define __flush_tlb_one __native_flush_tlb_one
+#define __flush_tlb_all __native_flush_tlb_all
+#endif /* CONFIG_PARAVIRT */
 /*
  * TLB flushing:
  *
arch/x86_64/kernel/paravirt.c new file +583 -0

583 lines not on this page · raw message

include/asm-x86_64/paravirt.h new file +641 -0

641 lines not on this page · raw message

include/asm-x86_64/msr.h +53 -48

158 lines not on this page · raw message

arch/i386/kernel/alternative.c +2 -0
Index: linux-2.6.19-quilt/arch/i386/kernel/alternative.c
===================================================================
@@ -431,7 +431,9 @@ void __init alternative_instructions(voi
 	}
 #endif
 #ifdef CONFIG_PARAVIRT
+  #ifndef CONFIG_X86_64 /* Not working properly yet */
  	apply_paravirt(__start_parainstructions, __stop_parainstructions);
+  #endif
 #endif
 	local_irq_restore(flags);
 }

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/virtualization

#1 lore raw
Quoted 5 lines · Glauber de Oliveira Costa

Hi all,

I've been working on a port of paravirt_ops for the x86_64 architectures for a couple of days. Here's the result so far. I'm posting it soon for early cooments. The more, the better.

Hi Glauber!

This looks like a great start! Note that i386 is heading away from
exporting the entire paravirt_ops structure and just exporting some wrappers, but that can be retro'd in once you've got it all working.

There's one critical bug which will stop it from booting reliably:

Quoted 1 line

+ Based on i386 work by Rusty Russel.

Cheers!
Rusty Russell.

#2 lore raw
Quoted 4 lines

There's one critical bug which will stop it from booting reliably:

Quoted 1 line

+ Based on i386 work by Rusty Russel.

Thanks for the tip, Rusty. In fact, I fixed that, and the random crashes disappeared. ;-)

Signature · 3 lines
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
#3 lore raw
In reply to Glauber de Oliveira Costa
Quoted 3 lines · * Glauber de Oliveira Costa ([email protected]) wrote:

I've been working on a port of paravirt_ops for the x86_64 architectures for a couple of days. Here's the result so far. I'm posting it soon for early cooments. The more, the better.

Thanks a lot for getting this started Glauber. As Rusty mentioned, we'll want to follow the no export paravirt_ops motion upstream for x86_64 as well.

Quoted 11 lines

Index: linux-2.6.19-quilt/arch/x86_64/kernel/entry.S
===================================================================

arch/x86_64/kernel/entry.S +3 -0
@@ -1064,6 +1064,22 @@ KPROBE_ENTRY(int3)
  	CFI_ENDPROC
 KPROBE_END(int3)
 
+#ifdef CONFIG_PARAVIRT
+ENTRY(native_iret)
+1:	iretq

arch/x86_64/kernel/entry.S KPROBE_ENTRY(int3) · line 1079

Quoted 10 lines
arch/x86_64/kernel/entry.S +10 -0
+.section __ex_table,"a"
+	.align 8
+	.quad 1b, bad_iret
+.previous
+ENDPROC(native_iret)
+
+ENTRY(native_irq_enable_sysexit)
+	sti
+	sysretq
+ENDPROC(native_irq_enable_sysexit)

sysexit is legacy mode only

and I think we'll need a story for swapgs