Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
xen: don't drop NX bit
xen: mask unwanted pte bits in __supported_pte_mask
xen: Use wmb instead of rmb in xen_evtchn_do_upcall().
x86: fix NULL pointer deref in __switch_to

+47 -35
+5
arch/x86/xen/enlighten.c
··· 1228 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1229 pv_info.kernel_rpl = 0; 1230 1231 /* set the limit of our address space */ 1232 xen_reserve_top(); 1233
··· 1228 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1229 pv_info.kernel_rpl = 0; 1230 1231 + /* Prevent unwanted bits from being set in PTEs. */ 1232 + __supported_pte_mask &= ~_PAGE_GLOBAL; 1233 + if (!is_initial_xendomain()) 1234 + __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); 1235 + 1236 /* set the limit of our address space */ 1237 xen_reserve_top(); 1238
+31 -27
arch/x86/xen/mmu.c
··· 179 preempt_enable(); 180 } 181 182 pteval_t xen_pte_val(pte_t pte) 183 { 184 - pteval_t ret = pte.pte; 185 - 186 - if (ret & _PAGE_PRESENT) 187 - ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; 188 - 189 - return ret; 190 } 191 192 pgdval_t xen_pgd_val(pgd_t pgd) 193 { 194 - pgdval_t ret = pgd.pgd; 195 - if (ret & _PAGE_PRESENT) 196 - ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; 197 - return ret; 198 } 199 200 pte_t xen_make_pte(pteval_t pte) 201 { 202 - if (pte & _PAGE_PRESENT) { 203 - pte = phys_to_machine(XPADDR(pte)).maddr; 204 - pte &= ~(_PAGE_PCD | _PAGE_PWT); 205 - } 206 - 207 - return (pte_t){ .pte = pte }; 208 } 209 210 pgd_t xen_make_pgd(pgdval_t pgd) 211 { 212 - if (pgd & _PAGE_PRESENT) 213 - pgd = phys_to_machine(XPADDR(pgd)).maddr; 214 - 215 - return (pgd_t){ pgd }; 216 } 217 218 pmdval_t xen_pmd_val(pmd_t pmd) 219 { 220 - pmdval_t ret = native_pmd_val(pmd); 221 - if (ret & _PAGE_PRESENT) 222 - ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; 223 - return ret; 224 } 225 #ifdef CONFIG_X86_PAE 226 void xen_set_pud(pud_t *ptr, pud_t val) ··· 273 274 pmd_t xen_make_pmd(pmdval_t pmd) 275 { 276 - if (pmd & _PAGE_PRESENT) 277 - pmd = phys_to_machine(XPADDR(pmd)).maddr; 278 - 279 return native_make_pmd(pmd); 280 } 281 #else /* !PAE */
··· 179 preempt_enable(); 180 } 181 182 + /* Assume pteval_t is equivalent to all the other *val_t types. */ 183 + static pteval_t pte_mfn_to_pfn(pteval_t val) 184 + { 185 + if (val & _PAGE_PRESENT) { 186 + unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT; 187 + pteval_t flags = val & ~PTE_MASK; 188 + val = (mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; 189 + } 190 + 191 + return val; 192 + } 193 + 194 + static pteval_t pte_pfn_to_mfn(pteval_t val) 195 + { 196 + if (val & _PAGE_PRESENT) { 197 + unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT; 198 + pteval_t flags = val & ~PTE_MASK; 199 + val = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flags; 200 + } 201 + 202 + return val; 203 + } 204 + 205 pteval_t xen_pte_val(pte_t pte) 206 { 207 + return pte_mfn_to_pfn(pte.pte); 208 } 209 210 pgdval_t xen_pgd_val(pgd_t pgd) 211 { 212 + return pte_mfn_to_pfn(pgd.pgd); 213 } 214 215 pte_t xen_make_pte(pteval_t pte) 216 { 217 + pte = pte_pfn_to_mfn(pte); 218 + return native_make_pte(pte); 219 } 220 221 pgd_t xen_make_pgd(pgdval_t pgd) 222 { 223 + pgd = pte_pfn_to_mfn(pgd); 224 + return native_make_pgd(pgd); 225 } 226 227 pmdval_t xen_pmd_val(pmd_t pmd) 228 { 229 + return pte_mfn_to_pfn(pmd.pmd); 230 } 231 #ifdef CONFIG_X86_PAE 232 void xen_set_pud(pud_t *ptr, pud_t val) ··· 267 268 pmd_t xen_make_pmd(pmdval_t pmd) 269 { 270 + pmd = pte_pfn_to_mfn(pmd); 271 return native_make_pmd(pmd); 272 } 273 #else /* !PAE */
+1 -1
arch/x86/xen/xen-head.S
··· 17 18 __FINIT 19 20 - .pushsection .bss.page_aligned 21 .align PAGE_SIZE_asm 22 ENTRY(hypercall_page) 23 .skip 0x1000
··· 17 18 __FINIT 19 20 + .pushsection .text 21 .align PAGE_SIZE_asm 22 ENTRY(hypercall_page) 23 .skip 0x1000
+9 -6
drivers/lguest/x86/core.c
··· 176 * we set it now, so we can trap and pass that trap to the Guest if it 177 * uses the FPU. */ 178 if (cpu->ts) 179 - lguest_set_ts(); 180 181 /* SYSENTER is an optimized way of doing system calls. We can't allow 182 * it because it always jumps to privilege level 0. A normal Guest ··· 196 * trap made the switcher code come back, and an error code which some 197 * traps set. */ 198 199 /* If the Guest page faulted, then the cr2 register will tell us the 200 * bad virtual address. We have to grab this now, because once we 201 * re-enable interrupts an interrupt could fault and thus overwrite ··· 207 if (cpu->regs->trapnum == 14) 208 cpu->arch.last_pagefault = read_cr2(); 209 /* Similarly, if we took a trap because the Guest used the FPU, 210 - * we have to restore the FPU it expects to see. */ 211 else if (cpu->regs->trapnum == 7) 212 math_state_restore(); 213 - 214 - /* Restore SYSENTER if it's supposed to be on. */ 215 - if (boot_cpu_has(X86_FEATURE_SEP)) 216 - wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); 217 } 218 219 /*H:130 Now we've examined the hypercall code; our Guest can make requests.
··· 176 * we set it now, so we can trap and pass that trap to the Guest if it 177 * uses the FPU. */ 178 if (cpu->ts) 179 + unlazy_fpu(current); 180 181 /* SYSENTER is an optimized way of doing system calls. We can't allow 182 * it because it always jumps to privilege level 0. A normal Guest ··· 196 * trap made the switcher code come back, and an error code which some 197 * traps set. */ 198 199 + /* Restore SYSENTER if it's supposed to be on. */ 200 + if (boot_cpu_has(X86_FEATURE_SEP)) 201 + wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); 202 + 203 /* If the Guest page faulted, then the cr2 register will tell us the 204 * bad virtual address. We have to grab this now, because once we 205 * re-enable interrupts an interrupt could fault and thus overwrite ··· 203 if (cpu->regs->trapnum == 14) 204 cpu->arch.last_pagefault = read_cr2(); 205 /* Similarly, if we took a trap because the Guest used the FPU, 206 + * we have to restore the FPU it expects to see. 207 + * math_state_restore() may sleep and we may even move off to 208 + * a different CPU. So all the critical stuff should be done 209 + * before this. */ 210 else if (cpu->regs->trapnum == 7) 211 math_state_restore(); 212 } 213 214 /*H:130 Now we've examined the hypercall code; our Guest can make requests.
+1 -1
drivers/xen/events.c
··· 529 530 #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ 531 /* Clear master flag /before/ clearing selector flag. */ 532 - rmb(); 533 #endif 534 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); 535 while (pending_words != 0) {
··· 529 530 #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ 531 /* Clear master flag /before/ clearing selector flag. */ 532 + wmb(); 533 #endif 534 pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); 535 while (pending_words != 0) {