diff -r 8273f730371b linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Tue Aug 29 11:23:11 2006 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Tue Aug 29 23:23:12 2006 @@ -80,6 +80,10 @@ * be MACHINE addresses. */ +#if defined(CONFIG_X86_64) +#define _PAGE_GUEST_KERNEL (0x200) /* PTE Bit 9 */ +#endif + void xen_pt_switch(unsigned long ptr); void xen_new_user_pt(unsigned long ptr); /* x86_64 only */ void xen_load_gs(unsigned int selector); /* x86_64 only */ diff -r 8273f730371b linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Aug 29 11:23:11 2006 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Aug 29 23:23:12 2006 @@ -206,7 +206,7 @@ #define _PAGE_NX (1UL<<_PAGE_BIT_NX) #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_GUEST_KERNEL ) #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -219,21 +219,21 @@ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define __PAGE_KERNEL \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | _PAGE_GUEST_KERNEL) #define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GUEST_KERNEL) #define __PAGE_KERNEL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | _PAGE_GUEST_KERNEL) #define __PAGE_KERNEL_RO \ - (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | _PAGE_GUEST_KERNEL) #define __PAGE_KERNEL_VSYSCALL \ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define __PAGE_KERNEL_VSYSCALL_NOCACHE \ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) #define __PAGE_KERNEL_LARGE \ - (__PAGE_KERNEL | _PAGE_PSE) + (__PAGE_KERNEL | _PAGE_PSE | _PAGE_GUEST_KERNEL) #define __PAGE_KERNEL_LARGE_EXEC \ - (__PAGE_KERNEL_EXEC | _PAGE_PSE) + (__PAGE_KERNEL_EXEC | _PAGE_PSE | _PAGE_GUEST_KERNEL) /* * We don't support GLOBAL page in xenolinux64 @@ -422,7 +422,10 @@ can temporarily clear it. */ #define pmd_present(x) (pmd_val(x)) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT)) +#define pmd_bad(x) \ + ((pmd_val(x) & \ + (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != \ + (_KERNPG_TABLE & ~_PAGE_PRESENT & ~_PAGE_GUEST_KERNEL)) #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) diff -r 8273f730371b tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Tue Aug 29 11:23:11 2006 +++ b/tools/libxc/xc_linux_build.c Tue Aug 29 23:23:12 2006 @@ -16,11 +16,12 @@ /* Handy for printing out '0' prepended values at native pointer size */ #define _p(a) ((void *) ((ulong)a)) -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #if defined(__i386__) +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L3_PROT (_PAGE_PRESENT) #elif defined(__x86_64__) +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_GUEST_KERNEL) #define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #endif diff -r 8273f730371b tools/libxc/xg_private.h --- a/tools/libxc/xg_private.h Tue Aug 29 11:23:11 2006 +++ b/tools/libxc/xg_private.h Tue Aug 29 23:23:12 2006 @@ -45,6 +45,9 @@ #define _PAGE_PAT 0x080 #define _PAGE_PSE 0x080 #define _PAGE_GLOBAL 0x100 +#if defined(__x86_64__) +#define _PAGE_GUEST_KERNEL 0x200 +#endif #define L1_PAGETABLE_SHIFT_PAE 12 #define L2_PAGETABLE_SHIFT_PAE 21 diff -r 8273f730371b xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Tue Aug 29 11:23:11 2006 +++ b/xen/arch/x86/domain_build.c Tue Aug 29 23:23:12 2006 @@ -74,7 +74,7 @@ #define L3_PROT (_PAGE_PRESENT) #elif defined(__x86_64__) /* Allow ring-3 access in long mode as guest cannot use ring 1. */ -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER |_PAGE_GUEST_KERNEL) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) diff -r 8273f730371b xen/arch/x86/flushtlb.c --- a/xen/arch/x86/flushtlb.c Tue Aug 29 11:23:11 2006 +++ b/xen/arch/x86/flushtlb.c Tue Aug 29 23:23:12 2006 @@ -57,7 +57,14 @@ */ skip_clocktick: +#ifdef __x86_64__ + __pge_off(); + if ( !(cr3 & FLUSH_TLB_ONLY) ) + __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3 & ~FLUSH_TLB_ONLY) : "memory" ); + __pge_on(); +#else __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" ); +#endif /* * STEP 3. Update this CPU's timestamp. Note that this happens *after* diff -r 8273f730371b xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Tue Aug 29 11:23:11 2006 +++ b/xen/arch/x86/mm.c Tue Aug 29 23:23:12 2006 @@ -708,10 +708,14 @@ #endif /* 4 level */ #ifdef __x86_64__ -#define adjust_guest_l1e(pl1e) \ - do { \ - if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ - l1e_add_flags((pl1e), _PAGE_USER); \ +#define adjust_guest_l1e(pl1e) \ + do { \ + if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ + { \ + l1e_add_flags((pl1e), _PAGE_USER); \ + if ( !(l1e_get_flags((pl1e)) & _PAGE_GUEST_KERNEL) ) \ + l1e_add_flags((pl1e), _PAGE_GLOBAL); \ + } \ } while ( 0 ) #define adjust_guest_l2e(pl2e) \ diff -r 8273f730371b xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Tue Aug 29 11:23:11 2006 +++ b/xen/arch/x86/x86_64/traps.c Tue Aug 29 23:23:12 2006 @@ -167,7 +167,7 @@ v->arch.flags ^= TF_kernel_mode; __asm__ __volatile__ ( "swapgs" ); update_cr3(v); - write_ptbase(v); + __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (v->arch.cr3) : "memory" ); } unsigned long do_iret(void) diff -r 8273f730371b xen/include/asm-x86/flushtlb.h --- a/xen/include/asm-x86/flushtlb.h Tue Aug 29 11:23:11 2006 +++ b/xen/include/asm-x86/flushtlb.h Tue Aug 29 23:23:12 2006 @@ -71,10 +71,16 @@ /* Write pagetable base and implicitly tick the tlbflush clock. */ extern void write_cr3(unsigned long cr3); +#ifdef __x86_64__ +#define FLUSH_TLB_ONLY 1 +#else +#define FLUSH_TLB_ONLY 0 /* don't use for old processors */ +#endif + #define local_flush_tlb() \ do { \ unsigned long cr3 = read_cr3(); \ - write_cr3(cr3); \ + write_cr3(cr3|FLUSH_TLB_ONLY); \ } while ( 0 ) #define local_flush_tlb_pge() \ diff -r 8273f730371b xen/include/asm-x86/x86_64/page.h --- a/xen/include/asm-x86/x86_64/page.h Tue Aug 29 11:23:11 2006 +++ b/xen/include/asm-x86/x86_64/page.h Tue Aug 29 23:23:12 2006 @@ -71,11 +71,15 @@ #define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF)) #define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF)) -/* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte.*/ +/* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte. */ #define _PAGE_NX_BIT (1U<<23) #define _PAGE_NX (cpu_has_nx ? _PAGE_NX_BIT : 0U) -#define L1_DISALLOW_MASK BASE_DISALLOW_MASK +/* pte[11:9] */ +#define _PAGE_AVAIL_LOW (((1U<<3)-1)<<9) +#define _PAGE_GUEST_KERNEL _PAGE_AVAIL0 + +#define L1_DISALLOW_MASK (BASE_DISALLOW_MASK & ~_PAGE_AVAIL_LOW & ~_PAGE_GLOBAL) #define L2_DISALLOW_MASK BASE_DISALLOW_MASK #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)