aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/enlighten.c73
-rw-r--r--arch/x86/xen/xen-asm_64.S2
2 files changed, 71 insertions, 4 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 9ff6e3cbf08f..b795470ec069 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -325,6 +325,57 @@ static unsigned long xen_store_tr(void)
325 return 0; 325 return 0;
326} 326}
327 327
328/*
329 * If 'v' is a vmalloc mapping, then find the linear mapping of the
330 * page (if any) and also set its protections to match:
331 */
332static void set_aliased_prot(void *v, pgprot_t prot)
333{
334 int level;
335 pte_t *ptep;
336 pte_t pte;
337 unsigned long pfn;
338 struct page *page;
339
340 ptep = lookup_address((unsigned long)v, &level);
341 BUG_ON(ptep == NULL);
342
343 pfn = pte_pfn(*ptep);
344 page = pfn_to_page(pfn);
345
346 pte = pfn_pte(pfn, prot);
347
348 if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
349 BUG();
350
351 if (!PageHighMem(page)) {
352 void *av = __va(PFN_PHYS(pfn));
353
354 if (av != v)
355 if (HYPERVISOR_update_va_mapping((unsigned long)av, pte, 0))
356 BUG();
357 } else
358 kmap_flush_unused();
359}
360
361static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
362{
363 const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
364 int i;
365
366 for(i = 0; i < entries; i += entries_per_page)
367 set_aliased_prot(ldt + i, PAGE_KERNEL_RO);
368}
369
370static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)
371{
372 const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
373 int i;
374
375 for(i = 0; i < entries; i += entries_per_page)
376 set_aliased_prot(ldt + i, PAGE_KERNEL);
377}
378
328static void xen_set_ldt(const void *addr, unsigned entries) 379static void xen_set_ldt(const void *addr, unsigned entries)
329{ 380{
330 struct mmuext_op *op; 381 struct mmuext_op *op;
@@ -426,7 +477,7 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
426 const void *ptr) 477 const void *ptr)
427{ 478{
428 unsigned long lp = (unsigned long)&dt[entrynum]; 479 unsigned long lp = (unsigned long)&dt[entrynum];
429 xmaddr_t mach_lp = virt_to_machine(lp); 480 xmaddr_t mach_lp = arbitrary_virt_to_machine(lp);
430 u64 entry = *(u64 *)ptr; 481 u64 entry = *(u64 *)ptr;
431 482
432 preempt_disable(); 483 preempt_disable();
@@ -559,7 +610,7 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
559} 610}
560 611
561static void xen_load_sp0(struct tss_struct *tss, 612static void xen_load_sp0(struct tss_struct *tss,
562 struct thread_struct *thread) 613 struct thread_struct *thread)
563{ 614{
564 struct multicall_space mcs = xen_mc_entry(0); 615 struct multicall_space mcs = xen_mc_entry(0);
565 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0); 616 MULTI_stack_switch(mcs.mc, __KERNEL_DS, thread->sp0);
@@ -803,6 +854,19 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
803 ret = -EFAULT; 854 ret = -EFAULT;
804 break; 855 break;
805#endif 856#endif
857
858 case MSR_STAR:
859 case MSR_CSTAR:
860 case MSR_LSTAR:
861 case MSR_SYSCALL_MASK:
862 case MSR_IA32_SYSENTER_CS:
863 case MSR_IA32_SYSENTER_ESP:
864 case MSR_IA32_SYSENTER_EIP:
865 /* Fast syscall setup is all done in hypercalls, so
866 these are all ignored. Stub them out here to stop
867 Xen console noise. */
868 break;
869
806 default: 870 default:
807 ret = native_write_msr_safe(msr, low, high); 871 ret = native_write_msr_safe(msr, low, high);
808 } 872 }
@@ -1220,6 +1284,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
1220 .load_gs_index = xen_load_gs_index, 1284 .load_gs_index = xen_load_gs_index,
1221#endif 1285#endif
1222 1286
1287 .alloc_ldt = xen_alloc_ldt,
1288 .free_ldt = xen_free_ldt,
1289
1223 .store_gdt = native_store_gdt, 1290 .store_gdt = native_store_gdt,
1224 .store_idt = native_store_idt, 1291 .store_idt = native_store_idt,
1225 .store_tr = xen_store_tr, 1292 .store_tr = xen_store_tr,
@@ -1324,7 +1391,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1324 .ptep_modify_prot_commit = __ptep_modify_prot_commit, 1391 .ptep_modify_prot_commit = __ptep_modify_prot_commit,
1325 1392
1326 .pte_val = xen_pte_val, 1393 .pte_val = xen_pte_val,
1327 .pte_flags = native_pte_val, 1394 .pte_flags = native_pte_flags,
1328 .pgd_val = xen_pgd_val, 1395 .pgd_val = xen_pgd_val,
1329 1396
1330 .make_pte = xen_make_pte, 1397 .make_pte = xen_make_pte,
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index 4038cbfe3331..7f58304fafb3 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -173,7 +173,7 @@ ENTRY(xen_sysexit)
173 pushq $__USER32_CS 173 pushq $__USER32_CS
174 pushq %rdx 174 pushq %rdx
175 175
176 pushq $VGCF_in_syscall 176 pushq $0
1771: jmp hypercall_iret 1771: jmp hypercall_iret
178ENDPATCH(xen_sysexit) 178ENDPATCH(xen_sysexit)
179RELOC(xen_sysexit, 1b+1) 179RELOC(xen_sysexit, 1b+1)