aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/enlighten.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r--arch/x86/xen/enlighten.c161
1 files changed, 128 insertions, 33 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index e90540a46a0b..544eb7496531 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -51,6 +51,7 @@
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/tlbflush.h> 52#include <asm/tlbflush.h>
53#include <asm/reboot.h> 53#include <asm/reboot.h>
54#include <asm/stackprotector.h>
54 55
55#include "xen-ops.h" 56#include "xen-ops.h"
56#include "mmu.h" 57#include "mmu.h"
@@ -215,6 +216,7 @@ static __init void xen_init_cpuid_mask(void)
215 (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 216 (1 << X86_FEATURE_ACPI)); /* disable ACPI */
216 217
217 ax = 1; 218 ax = 1;
219 cx = 0;
218 xen_cpuid(&ax, &bx, &cx, &dx); 220 xen_cpuid(&ax, &bx, &cx, &dx);
219 221
220 /* cpuid claims we support xsave; try enabling it to see what happens */ 222 /* cpuid claims we support xsave; try enabling it to see what happens */
@@ -329,18 +331,28 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
329 unsigned long frames[pages]; 331 unsigned long frames[pages];
330 int f; 332 int f;
331 333
332 /* A GDT can be up to 64k in size, which corresponds to 8192 334 /*
333 8-byte entries, or 16 4k pages.. */ 335 * A GDT can be up to 64k in size, which corresponds to 8192
336 * 8-byte entries, or 16 4k pages..
337 */
334 338
335 BUG_ON(size > 65536); 339 BUG_ON(size > 65536);
336 BUG_ON(va & ~PAGE_MASK); 340 BUG_ON(va & ~PAGE_MASK);
337 341
338 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { 342 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
339 int level; 343 int level;
340 pte_t *ptep = lookup_address(va, &level); 344 pte_t *ptep;
341 unsigned long pfn, mfn; 345 unsigned long pfn, mfn;
342 void *virt; 346 void *virt;
343 347
348 /*
349 * The GDT is per-cpu and is in the percpu data area.
350 * That can be virtually mapped, so we need to do a
351 * page-walk to get the underlying MFN for the
352 * hypercall. The page can also be in the kernel's
353 * linear range, so we need to RO that mapping too.
354 */
355 ptep = lookup_address(va, &level);
344 BUG_ON(ptep == NULL); 356 BUG_ON(ptep == NULL);
345 357
346 pfn = pte_pfn(*ptep); 358 pfn = pte_pfn(*ptep);
@@ -357,6 +369,44 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
357 BUG(); 369 BUG();
358} 370}
359 371
372/*
373 * load_gdt for early boot, when the gdt is only mapped once
374 */
375static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
376{
377 unsigned long va = dtr->address;
378 unsigned int size = dtr->size + 1;
379 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
380 unsigned long frames[pages];
381 int f;
382
383 /*
384 * A GDT can be up to 64k in size, which corresponds to 8192
385 * 8-byte entries, or 16 4k pages..
386 */
387
388 BUG_ON(size > 65536);
389 BUG_ON(va & ~PAGE_MASK);
390
391 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
392 pte_t pte;
393 unsigned long pfn, mfn;
394
395 pfn = virt_to_pfn(va);
396 mfn = pfn_to_mfn(pfn);
397
398 pte = pfn_pte(pfn, PAGE_KERNEL_RO);
399
400 if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
401 BUG();
402
403 frames[f] = mfn;
404 }
405
406 if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
407 BUG();
408}
409
360static void load_TLS_descriptor(struct thread_struct *t, 410static void load_TLS_descriptor(struct thread_struct *t,
361 unsigned int cpu, unsigned int i) 411 unsigned int cpu, unsigned int i)
362{ 412{
@@ -580,6 +630,29 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
580 preempt_enable(); 630 preempt_enable();
581} 631}
582 632
633/*
634 * Version of write_gdt_entry for use at early boot-time needed to
635 * update an entry as simply as possible.
636 */
637static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
638 const void *desc, int type)
639{
640 switch (type) {
641 case DESC_LDT:
642 case DESC_TSS:
643 /* ignore */
644 break;
645
646 default: {
647 xmaddr_t maddr = virt_to_machine(&dt[entry]);
648
649 if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
650 dt[entry] = *(struct desc_struct *)desc;
651 }
652
653 }
654}
655
583static void xen_load_sp0(struct tss_struct *tss, 656static void xen_load_sp0(struct tss_struct *tss,
584 struct thread_struct *thread) 657 struct thread_struct *thread)
585{ 658{
@@ -713,7 +786,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
713 set: 786 set:
714 base = ((u64)high << 32) | low; 787 base = ((u64)high << 32) | low;
715 if (HYPERVISOR_set_segment_base(which, base) != 0) 788 if (HYPERVISOR_set_segment_base(which, base) != 0)
716 ret = -EFAULT; 789 ret = -EIO;
717 break; 790 break;
718#endif 791#endif
719 792
@@ -839,19 +912,9 @@ static const struct pv_info xen_info __initdata = {
839 912
840static const struct pv_init_ops xen_init_ops __initdata = { 913static const struct pv_init_ops xen_init_ops __initdata = {
841 .patch = xen_patch, 914 .patch = xen_patch,
842
843 .banner = xen_banner,
844 .memory_setup = xen_memory_setup,
845 .arch_setup = xen_arch_setup,
846 .post_allocator_init = xen_post_allocator_init,
847}; 915};
848 916
849static const struct pv_time_ops xen_time_ops __initdata = { 917static const struct pv_time_ops xen_time_ops __initdata = {
850 .time_init = xen_time_init,
851
852 .set_wallclock = xen_set_wallclock,
853 .get_wallclock = xen_get_wallclock,
854 .get_tsc_khz = xen_tsc_khz,
855 .sched_clock = xen_sched_clock, 918 .sched_clock = xen_sched_clock,
856}; 919};
857 920
@@ -917,8 +980,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
917 980
918static const struct pv_apic_ops xen_apic_ops __initdata = { 981static const struct pv_apic_ops xen_apic_ops __initdata = {
919#ifdef CONFIG_X86_LOCAL_APIC 982#ifdef CONFIG_X86_LOCAL_APIC
920 .setup_boot_clock = paravirt_nop,
921 .setup_secondary_clock = paravirt_nop,
922 .startup_ipi_hook = paravirt_nop, 983 .startup_ipi_hook = paravirt_nop,
923#endif 984#endif
924}; 985};
@@ -964,6 +1025,23 @@ static const struct machine_ops __initdata xen_machine_ops = {
964 .emergency_restart = xen_emergency_restart, 1025 .emergency_restart = xen_emergency_restart,
965}; 1026};
966 1027
1028/*
1029 * Set up the GDT and segment registers for -fstack-protector. Until
1030 * we do this, we have to be careful not to call any stack-protected
1031 * function, which is most of the kernel.
1032 */
1033static void __init xen_setup_stackprotector(void)
1034{
1035 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
1036 pv_cpu_ops.load_gdt = xen_load_gdt_boot;
1037
1038 setup_stack_canary_segment(0);
1039 switch_to_new_gdt(0);
1040
1041 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry;
1042 pv_cpu_ops.load_gdt = xen_load_gdt;
1043}
1044
967/* First C function to be called on Xen boot */ 1045/* First C function to be called on Xen boot */
968asmlinkage void __init xen_start_kernel(void) 1046asmlinkage void __init xen_start_kernel(void)
969{ 1047{
@@ -980,16 +1058,43 @@ asmlinkage void __init xen_start_kernel(void)
980 pv_time_ops = xen_time_ops; 1058 pv_time_ops = xen_time_ops;
981 pv_cpu_ops = xen_cpu_ops; 1059 pv_cpu_ops = xen_cpu_ops;
982 pv_apic_ops = xen_apic_ops; 1060 pv_apic_ops = xen_apic_ops;
983 pv_mmu_ops = xen_mmu_ops;
984 1061
985#ifdef CONFIG_X86_64 1062 x86_init.resources.memory_setup = xen_memory_setup;
1063 x86_init.oem.arch_setup = xen_arch_setup;
1064 x86_init.oem.banner = xen_banner;
1065
1066 x86_init.timers.timer_init = xen_time_init;
1067 x86_init.timers.setup_percpu_clockev = x86_init_noop;
1068 x86_cpuinit.setup_percpu_clockev = x86_init_noop;
1069
1070 x86_platform.calibrate_tsc = xen_tsc_khz;
1071 x86_platform.get_wallclock = xen_get_wallclock;
1072 x86_platform.set_wallclock = xen_set_wallclock;
1073
986 /* 1074 /*
987 * Setup percpu state. We only need to do this for 64-bit 1075 * Set up some pagetable state before starting to set any ptes.
988 * because 32-bit already has %fs set properly.
989 */ 1076 */
990 load_percpu_segment(0);
991#endif
992 1077
1078 /* Prevent unwanted bits from being set in PTEs. */
1079 __supported_pte_mask &= ~_PAGE_GLOBAL;
1080 if (!xen_initial_domain())
1081 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1082
1083 __supported_pte_mask |= _PAGE_IOMAP;
1084
1085 xen_setup_features();
1086
1087 /* Get mfn list */
1088 if (!xen_feature(XENFEAT_auto_translated_physmap))
1089 xen_build_dynamic_phys_to_machine();
1090
1091 /*
1092 * Set up kernel GDT and segment registers, mainly so that
1093 * -fstack-protector code can be executed.
1094 */
1095 xen_setup_stackprotector();
1096
1097 xen_init_mmu_ops();
993 xen_init_irq_ops(); 1098 xen_init_irq_ops();
994 xen_init_cpuid_mask(); 1099 xen_init_cpuid_mask();
995 1100
@@ -1000,8 +1105,6 @@ asmlinkage void __init xen_start_kernel(void)
1000 set_xen_basic_apic_ops(); 1105 set_xen_basic_apic_ops();
1001#endif 1106#endif
1002 1107
1003 xen_setup_features();
1004
1005 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { 1108 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1006 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; 1109 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1007 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; 1110 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
@@ -1018,17 +1121,8 @@ asmlinkage void __init xen_start_kernel(void)
1018 1121
1019 xen_smp_init(); 1122 xen_smp_init();
1020 1123
1021 /* Get mfn list */
1022 if (!xen_feature(XENFEAT_auto_translated_physmap))
1023 xen_build_dynamic_phys_to_machine();
1024
1025 pgd = (pgd_t *)xen_start_info->pt_base; 1124 pgd = (pgd_t *)xen_start_info->pt_base;
1026 1125
1027 /* Prevent unwanted bits from being set in PTEs. */
1028 __supported_pte_mask &= ~_PAGE_GLOBAL;
1029 if (!xen_initial_domain())
1030 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1031
1032#ifdef CONFIG_X86_64 1126#ifdef CONFIG_X86_64
1033 /* Work out if we support NX */ 1127 /* Work out if we support NX */
1034 check_efer(); 1128 check_efer();
@@ -1059,6 +1153,7 @@ asmlinkage void __init xen_start_kernel(void)
1059 /* set up basic CPUID stuff */ 1153 /* set up basic CPUID stuff */
1060 cpu_detect(&new_cpu_data); 1154 cpu_detect(&new_cpu_data);
1061 new_cpu_data.hard_math = 1; 1155 new_cpu_data.hard_math = 1;
1156 new_cpu_data.wp_works_ok = 1;
1062 new_cpu_data.x86_capability[0] = cpuid_edx(1); 1157 new_cpu_data.x86_capability[0] = cpuid_edx(1);
1063#endif 1158#endif
1064 1159