diff options
| -rw-r--r-- | arch/x86/xen/enlighten.c | 5 | ||||
| -rw-r--r-- | arch/x86/xen/mmu.c | 56 | ||||
| -rw-r--r-- | arch/x86/xen/xen-head.S | 2 | ||||
| -rw-r--r-- | drivers/lguest/x86/core.c | 15 | ||||
| -rw-r--r-- | drivers/xen/events.c | 2 |
5 files changed, 46 insertions, 34 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index c8a56e457d61..c048de34d6a1 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -1228,6 +1228,11 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1228 | if (xen_feature(XENFEAT_supervisor_mode_kernel)) | 1228 | if (xen_feature(XENFEAT_supervisor_mode_kernel)) |
| 1229 | pv_info.kernel_rpl = 0; | 1229 | pv_info.kernel_rpl = 0; |
| 1230 | 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 | |||
| 1231 | /* set the limit of our address space */ | 1236 | /* set the limit of our address space */ |
| 1232 | xen_reserve_top(); | 1237 | xen_reserve_top(); |
| 1233 | 1238 | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 3525ef523a74..265601d5a6ae 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -179,48 +179,54 @@ out: | |||
| 179 | preempt_enable(); | 179 | preempt_enable(); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | pteval_t xen_pte_val(pte_t pte) | 182 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
| 183 | static pteval_t pte_mfn_to_pfn(pteval_t val) | ||
| 183 | { | 184 | { |
| 184 | pteval_t ret = pte.pte; | 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 | } | ||
| 185 | 201 | ||
| 186 | if (ret & _PAGE_PRESENT) | 202 | return val; |
| 187 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | 203 | } |
| 188 | 204 | ||
| 189 | return ret; | 205 | pteval_t xen_pte_val(pte_t pte) |
| 206 | { | ||
| 207 | return pte_mfn_to_pfn(pte.pte); | ||
| 190 | } | 208 | } |
| 191 | 209 | ||
| 192 | pgdval_t xen_pgd_val(pgd_t pgd) | 210 | pgdval_t xen_pgd_val(pgd_t pgd) |
| 193 | { | 211 | { |
| 194 | pgdval_t ret = pgd.pgd; | 212 | return pte_mfn_to_pfn(pgd.pgd); |
| 195 | if (ret & _PAGE_PRESENT) | ||
| 196 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
| 197 | return ret; | ||
| 198 | } | 213 | } |
| 199 | 214 | ||
| 200 | pte_t xen_make_pte(pteval_t pte) | 215 | pte_t xen_make_pte(pteval_t pte) |
| 201 | { | 216 | { |
| 202 | if (pte & _PAGE_PRESENT) { | 217 | pte = pte_pfn_to_mfn(pte); |
| 203 | pte = phys_to_machine(XPADDR(pte)).maddr; | 218 | return native_make_pte(pte); |
| 204 | pte &= ~(_PAGE_PCD | _PAGE_PWT); | ||
| 205 | } | ||
| 206 | |||
| 207 | return (pte_t){ .pte = pte }; | ||
| 208 | } | 219 | } |
| 209 | 220 | ||
| 210 | pgd_t xen_make_pgd(pgdval_t pgd) | 221 | pgd_t xen_make_pgd(pgdval_t pgd) |
| 211 | { | 222 | { |
| 212 | if (pgd & _PAGE_PRESENT) | 223 | pgd = pte_pfn_to_mfn(pgd); |
| 213 | pgd = phys_to_machine(XPADDR(pgd)).maddr; | 224 | return native_make_pgd(pgd); |
| 214 | |||
| 215 | return (pgd_t){ pgd }; | ||
| 216 | } | 225 | } |
| 217 | 226 | ||
| 218 | pmdval_t xen_pmd_val(pmd_t pmd) | 227 | pmdval_t xen_pmd_val(pmd_t pmd) |
| 219 | { | 228 | { |
| 220 | pmdval_t ret = native_pmd_val(pmd); | 229 | return pte_mfn_to_pfn(pmd.pmd); |
| 221 | if (ret & _PAGE_PRESENT) | ||
| 222 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
| 223 | return ret; | ||
| 224 | } | 230 | } |
| 225 | #ifdef CONFIG_X86_PAE | 231 | #ifdef CONFIG_X86_PAE |
| 226 | void xen_set_pud(pud_t *ptr, pud_t val) | 232 | void xen_set_pud(pud_t *ptr, pud_t val) |
| @@ -267,9 +273,7 @@ void xen_pmd_clear(pmd_t *pmdp) | |||
| 267 | 273 | ||
| 268 | pmd_t xen_make_pmd(pmdval_t pmd) | 274 | pmd_t xen_make_pmd(pmdval_t pmd) |
| 269 | { | 275 | { |
| 270 | if (pmd & _PAGE_PRESENT) | 276 | pmd = pte_pfn_to_mfn(pmd); |
| 271 | pmd = phys_to_machine(XPADDR(pmd)).maddr; | ||
| 272 | |||
| 273 | return native_make_pmd(pmd); | 277 | return native_make_pmd(pmd); |
| 274 | } | 278 | } |
| 275 | #else /* !PAE */ | 279 | #else /* !PAE */ |
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 288d587ce73c..3175e973fd0d 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S | |||
| @@ -17,7 +17,7 @@ ENTRY(startup_xen) | |||
| 17 | 17 | ||
| 18 | __FINIT | 18 | __FINIT |
| 19 | 19 | ||
| 20 | .pushsection .bss.page_aligned | 20 | .pushsection .text |
| 21 | .align PAGE_SIZE_asm | 21 | .align PAGE_SIZE_asm |
| 22 | ENTRY(hypercall_page) | 22 | ENTRY(hypercall_page) |
| 23 | .skip 0x1000 | 23 | .skip 0x1000 |
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 5126d5d9ea0e..2e554a4ab337 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
| @@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) | |||
| 176 | * we set it now, so we can trap and pass that trap to the Guest if it | 176 | * we set it now, so we can trap and pass that trap to the Guest if it |
| 177 | * uses the FPU. */ | 177 | * uses the FPU. */ |
| 178 | if (cpu->ts) | 178 | if (cpu->ts) |
| 179 | lguest_set_ts(); | 179 | unlazy_fpu(current); |
| 180 | 180 | ||
| 181 | /* SYSENTER is an optimized way of doing system calls. We can't allow | 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 | 182 | * it because it always jumps to privilege level 0. A normal Guest |
| @@ -196,6 +196,10 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) | |||
| 196 | * trap made the switcher code come back, and an error code which some | 196 | * trap made the switcher code come back, and an error code which some |
| 197 | * traps set. */ | 197 | * traps set. */ |
| 198 | 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 | |||
| 199 | /* If the Guest page faulted, then the cr2 register will tell us the | 203 | /* 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 | 204 | * bad virtual address. We have to grab this now, because once we |
| 201 | * re-enable interrupts an interrupt could fault and thus overwrite | 205 | * re-enable interrupts an interrupt could fault and thus overwrite |
| @@ -203,13 +207,12 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) | |||
| 203 | if (cpu->regs->trapnum == 14) | 207 | if (cpu->regs->trapnum == 14) |
| 204 | cpu->arch.last_pagefault = read_cr2(); | 208 | cpu->arch.last_pagefault = read_cr2(); |
| 205 | /* Similarly, if we took a trap because the Guest used the FPU, | 209 | /* Similarly, if we took a trap because the Guest used the FPU, |
| 206 | * we have to restore the FPU it expects to see. */ | 210 | * we have to restore the FPU it expects to see. |
| 211 | * math_state_restore() may sleep and we may even move off to | ||
| 212 | * a different CPU. So all the critical stuff should be done | ||
| 213 | * before this. */ | ||
| 207 | else if (cpu->regs->trapnum == 7) | 214 | else if (cpu->regs->trapnum == 7) |
| 208 | math_state_restore(); | 215 | math_state_restore(); |
| 209 | |||
| 210 | /* Restore SYSENTER if it's supposed to be on. */ | ||
| 211 | if (boot_cpu_has(X86_FEATURE_SEP)) | ||
| 212 | wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); | ||
| 213 | } | 216 | } |
| 214 | 217 | ||
| 215 | /*H:130 Now we've examined the hypercall code; our Guest can make requests. | 218 | /*H:130 Now we've examined the hypercall code; our Guest can make requests. |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 4f0f22b020ea..76e5b7386af9 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
| @@ -529,7 +529,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) | |||
| 529 | 529 | ||
| 530 | #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ | 530 | #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ |
| 531 | /* Clear master flag /before/ clearing selector flag. */ | 531 | /* Clear master flag /before/ clearing selector flag. */ |
| 532 | rmb(); | 532 | wmb(); |
| 533 | #endif | 533 | #endif |
| 534 | pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); | 534 | pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); |
| 535 | while (pending_words != 0) { | 535 | while (pending_words != 0) { |
