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.c184
1 files changed, 127 insertions, 57 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c8a56e457d61..bd74229081c3 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -75,13 +75,13 @@ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
75struct start_info *xen_start_info; 75struct start_info *xen_start_info;
76EXPORT_SYMBOL_GPL(xen_start_info); 76EXPORT_SYMBOL_GPL(xen_start_info);
77 77
78static /* __initdata */ struct shared_info dummy_shared_info; 78struct shared_info xen_dummy_shared_info;
79 79
80/* 80/*
81 * Point at some empty memory to start with. We map the real shared_info 81 * Point at some empty memory to start with. We map the real shared_info
82 * page as soon as fixmap is up and running. 82 * page as soon as fixmap is up and running.
83 */ 83 */
84struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info; 84struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
85 85
86/* 86/*
87 * Flag to determine whether vcpu info placement is available on all 87 * Flag to determine whether vcpu info placement is available on all
@@ -98,13 +98,13 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info;
98 */ 98 */
99static int have_vcpu_info_placement = 1; 99static int have_vcpu_info_placement = 1;
100 100
101static void __init xen_vcpu_setup(int cpu) 101static void xen_vcpu_setup(int cpu)
102{ 102{
103 struct vcpu_register_vcpu_info info; 103 struct vcpu_register_vcpu_info info;
104 int err; 104 int err;
105 struct vcpu_info *vcpup; 105 struct vcpu_info *vcpup;
106 106
107 BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info); 107 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
108 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 108 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
109 109
110 if (!have_vcpu_info_placement) 110 if (!have_vcpu_info_placement)
@@ -136,11 +136,41 @@ static void __init xen_vcpu_setup(int cpu)
136 } 136 }
137} 137}
138 138
139/*
140 * On restore, set the vcpu placement up again.
141 * If it fails, then we're in a bad state, since
142 * we can't back out from using it...
143 */
144void xen_vcpu_restore(void)
145{
146 if (have_vcpu_info_placement) {
147 int cpu;
148
149 for_each_online_cpu(cpu) {
150 bool other_cpu = (cpu != smp_processor_id());
151
152 if (other_cpu &&
153 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
154 BUG();
155
156 xen_vcpu_setup(cpu);
157
158 if (other_cpu &&
159 HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
160 BUG();
161 }
162
163 BUG_ON(!have_vcpu_info_placement);
164 }
165}
166
139static void __init xen_banner(void) 167static void __init xen_banner(void)
140{ 168{
141 printk(KERN_INFO "Booting paravirtualized kernel on %s\n", 169 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
142 pv_info.name); 170 pv_info.name);
143 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic); 171 printk(KERN_INFO "Hypervisor signature: %s%s\n",
172 xen_start_info->magic,
173 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
144} 174}
145 175
146static void xen_cpuid(unsigned int *ax, unsigned int *bx, 176static void xen_cpuid(unsigned int *ax, unsigned int *bx,
@@ -235,13 +265,13 @@ static void xen_irq_enable(void)
235{ 265{
236 struct vcpu_info *vcpu; 266 struct vcpu_info *vcpu;
237 267
238 /* There's a one instruction preempt window here. We need to 268 /* We don't need to worry about being preempted here, since
239 make sure we're don't switch CPUs between getting the vcpu 269 either a) interrupts are disabled, so no preemption, or b)
240 pointer and updating the mask. */ 270 the caller is confused and is trying to re-enable interrupts
241 preempt_disable(); 271 on an indeterminate processor. */
272
242 vcpu = x86_read_percpu(xen_vcpu); 273 vcpu = x86_read_percpu(xen_vcpu);
243 vcpu->evtchn_upcall_mask = 0; 274 vcpu->evtchn_upcall_mask = 0;
244 preempt_enable_no_resched();
245 275
246 /* Doesn't matter if we get preempted here, because any 276 /* Doesn't matter if we get preempted here, because any
247 pending event will get dealt with anyway. */ 277 pending event will get dealt with anyway. */
@@ -254,7 +284,7 @@ static void xen_irq_enable(void)
254static void xen_safe_halt(void) 284static void xen_safe_halt(void)
255{ 285{
256 /* Blocking includes an implicit local_irq_enable(). */ 286 /* Blocking includes an implicit local_irq_enable(). */
257 if (HYPERVISOR_sched_op(SCHEDOP_block, 0) != 0) 287 if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)
258 BUG(); 288 BUG();
259} 289}
260 290
@@ -607,6 +637,30 @@ static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
607 xen_mc_issue(PARAVIRT_LAZY_MMU); 637 xen_mc_issue(PARAVIRT_LAZY_MMU);
608} 638}
609 639
640static void xen_clts(void)
641{
642 struct multicall_space mcs;
643
644 mcs = xen_mc_entry(0);
645
646 MULTI_fpu_taskswitch(mcs.mc, 0);
647
648 xen_mc_issue(PARAVIRT_LAZY_CPU);
649}
650
651static void xen_write_cr0(unsigned long cr0)
652{
653 struct multicall_space mcs;
654
655 /* Only pay attention to cr0.TS; everything else is
656 ignored. */
657 mcs = xen_mc_entry(0);
658
659 MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0);
660
661 xen_mc_issue(PARAVIRT_LAZY_CPU);
662}
663
610static void xen_write_cr2(unsigned long cr2) 664static void xen_write_cr2(unsigned long cr2)
611{ 665{
612 x86_read_percpu(xen_vcpu)->arch.cr2 = cr2; 666 x86_read_percpu(xen_vcpu)->arch.cr2 = cr2;
@@ -624,8 +678,10 @@ static unsigned long xen_read_cr2_direct(void)
624 678
625static void xen_write_cr4(unsigned long cr4) 679static void xen_write_cr4(unsigned long cr4)
626{ 680{
627 /* Just ignore cr4 changes; Xen doesn't allow us to do 681 cr4 &= ~X86_CR4_PGE;
628 anything anyway. */ 682 cr4 &= ~X86_CR4_PSE;
683
684 native_write_cr4(cr4);
629} 685}
630 686
631static unsigned long xen_read_cr3(void) 687static unsigned long xen_read_cr3(void)
@@ -785,38 +841,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
785static __init void xen_pagetable_setup_start(pgd_t *base) 841static __init void xen_pagetable_setup_start(pgd_t *base)
786{ 842{
787 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base; 843 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
844 int i;
788 845
789 /* special set_pte for pagetable initialization */ 846 /* special set_pte for pagetable initialization */
790 pv_mmu_ops.set_pte = xen_set_pte_init; 847 pv_mmu_ops.set_pte = xen_set_pte_init;
791 848
792 init_mm.pgd = base; 849 init_mm.pgd = base;
793 /* 850 /*
794 * copy top-level of Xen-supplied pagetable into place. For 851 * copy top-level of Xen-supplied pagetable into place. This
795 * !PAE we can use this as-is, but for PAE it is a stand-in 852 * is a stand-in while we copy the pmd pages.
796 * while we copy the pmd pages.
797 */ 853 */
798 memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t)); 854 memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
799 855
800 if (PTRS_PER_PMD > 1) { 856 /*
801 int i; 857 * For PAE, need to allocate new pmds, rather than
802 /* 858 * share Xen's, since Xen doesn't like pmd's being
803 * For PAE, need to allocate new pmds, rather than 859 * shared between address spaces.
804 * share Xen's, since Xen doesn't like pmd's being 860 */
805 * shared between address spaces. 861 for (i = 0; i < PTRS_PER_PGD; i++) {
806 */ 862 if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
807 for (i = 0; i < PTRS_PER_PGD; i++) { 863 pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
808 if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
809 pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
810 864
811 memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), 865 memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
812 PAGE_SIZE); 866 PAGE_SIZE);
813 867
814 make_lowmem_page_readonly(pmd); 868 make_lowmem_page_readonly(pmd);
815 869
816 set_pgd(&base[i], __pgd(1 + __pa(pmd))); 870 set_pgd(&base[i], __pgd(1 + __pa(pmd)));
817 } else 871 } else
818 pgd_clear(&base[i]); 872 pgd_clear(&base[i]);
819 }
820 } 873 }
821 874
822 /* make sure zero_page is mapped RO so we can use it in pagetables */ 875 /* make sure zero_page is mapped RO so we can use it in pagetables */
@@ -834,7 +887,7 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
834 PFN_DOWN(__pa(xen_start_info->pt_base))); 887 PFN_DOWN(__pa(xen_start_info->pt_base)));
835} 888}
836 889
837static __init void setup_shared_info(void) 890void xen_setup_shared_info(void)
838{ 891{
839 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 892 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
840 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP); 893 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
@@ -857,6 +910,8 @@ static __init void setup_shared_info(void)
857 /* In UP this is as good a place as any to set up shared info */ 910 /* In UP this is as good a place as any to set up shared info */
858 xen_setup_vcpu_info_placement(); 911 xen_setup_vcpu_info_placement();
859#endif 912#endif
913
914 xen_setup_mfn_list_list();
860} 915}
861 916
862static __init void xen_pagetable_setup_done(pgd_t *base) 917static __init void xen_pagetable_setup_done(pgd_t *base)
@@ -869,25 +924,23 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
869 pv_mmu_ops.release_pmd = xen_release_pmd; 924 pv_mmu_ops.release_pmd = xen_release_pmd;
870 pv_mmu_ops.set_pte = xen_set_pte; 925 pv_mmu_ops.set_pte = xen_set_pte;
871 926
872 setup_shared_info(); 927 xen_setup_shared_info();
873 928
874 /* Actually pin the pagetable down, but we can't set PG_pinned 929 /* Actually pin the pagetable down, but we can't set PG_pinned
875 yet because the page structures don't exist yet. */ 930 yet because the page structures don't exist yet. */
876 { 931 pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
877 unsigned level; 932}
878 933
879#ifdef CONFIG_X86_PAE 934static __init void xen_post_allocator_init(void)
880 level = MMUEXT_PIN_L3_TABLE; 935{
881#else 936 pv_mmu_ops.set_pmd = xen_set_pmd;
882 level = MMUEXT_PIN_L2_TABLE; 937 pv_mmu_ops.set_pud = xen_set_pud;
883#endif
884 938
885 pin_pagetable_pfn(level, PFN_DOWN(__pa(base))); 939 xen_mark_init_mm_pinned();
886 }
887} 940}
888 941
889/* This is called once we have the cpu_possible_map */ 942/* This is called once we have the cpu_possible_map */
890void __init xen_setup_vcpu_info_placement(void) 943void xen_setup_vcpu_info_placement(void)
891{ 944{
892 int cpu; 945 int cpu;
893 946
@@ -973,7 +1026,7 @@ static const struct pv_init_ops xen_init_ops __initdata = {
973 .banner = xen_banner, 1026 .banner = xen_banner,
974 .memory_setup = xen_memory_setup, 1027 .memory_setup = xen_memory_setup,
975 .arch_setup = xen_arch_setup, 1028 .arch_setup = xen_arch_setup,
976 .post_allocator_init = xen_mark_init_mm_pinned, 1029 .post_allocator_init = xen_post_allocator_init,
977}; 1030};
978 1031
979static const struct pv_time_ops xen_time_ops __initdata = { 1032static const struct pv_time_ops xen_time_ops __initdata = {
@@ -991,10 +1044,10 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
991 .set_debugreg = xen_set_debugreg, 1044 .set_debugreg = xen_set_debugreg,
992 .get_debugreg = xen_get_debugreg, 1045 .get_debugreg = xen_get_debugreg,
993 1046
994 .clts = native_clts, 1047 .clts = xen_clts,
995 1048
996 .read_cr0 = native_read_cr0, 1049 .read_cr0 = native_read_cr0,
997 .write_cr0 = native_write_cr0, 1050 .write_cr0 = xen_write_cr0,
998 1051
999 .read_cr4 = native_read_cr4, 1052 .read_cr4 = native_read_cr4,
1000 .read_cr4_safe = native_read_cr4_safe, 1053 .read_cr4_safe = native_read_cr4_safe,
@@ -1085,24 +1138,26 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1085 1138
1086 .set_pte = NULL, /* see xen_pagetable_setup_* */ 1139 .set_pte = NULL, /* see xen_pagetable_setup_* */
1087 .set_pte_at = xen_set_pte_at, 1140 .set_pte_at = xen_set_pte_at,
1088 .set_pmd = xen_set_pmd, 1141 .set_pmd = xen_set_pmd_hyper,
1142
1143 .ptep_modify_prot_start = __ptep_modify_prot_start,
1144 .ptep_modify_prot_commit = __ptep_modify_prot_commit,
1089 1145
1090 .pte_val = xen_pte_val, 1146 .pte_val = xen_pte_val,
1147 .pte_flags = native_pte_val,
1091 .pgd_val = xen_pgd_val, 1148 .pgd_val = xen_pgd_val,
1092 1149
1093 .make_pte = xen_make_pte, 1150 .make_pte = xen_make_pte,
1094 .make_pgd = xen_make_pgd, 1151 .make_pgd = xen_make_pgd,
1095 1152
1096#ifdef CONFIG_X86_PAE
1097 .set_pte_atomic = xen_set_pte_atomic, 1153 .set_pte_atomic = xen_set_pte_atomic,
1098 .set_pte_present = xen_set_pte_at, 1154 .set_pte_present = xen_set_pte_at,
1099 .set_pud = xen_set_pud, 1155 .set_pud = xen_set_pud_hyper,
1100 .pte_clear = xen_pte_clear, 1156 .pte_clear = xen_pte_clear,
1101 .pmd_clear = xen_pmd_clear, 1157 .pmd_clear = xen_pmd_clear,
1102 1158
1103 .make_pmd = xen_make_pmd, 1159 .make_pmd = xen_make_pmd,
1104 .pmd_val = xen_pmd_val, 1160 .pmd_val = xen_pmd_val,
1105#endif /* PAE */
1106 1161
1107 .activate_mm = xen_activate_mm, 1162 .activate_mm = xen_activate_mm,
1108 .dup_mmap = xen_dup_mmap, 1163 .dup_mmap = xen_dup_mmap,
@@ -1129,11 +1184,13 @@ static const struct smp_ops xen_smp_ops __initdata = {
1129 1184
1130static void xen_reboot(int reason) 1185static void xen_reboot(int reason)
1131{ 1186{
1187 struct sched_shutdown r = { .reason = reason };
1188
1132#ifdef CONFIG_SMP 1189#ifdef CONFIG_SMP
1133 smp_send_stop(); 1190 smp_send_stop();
1134#endif 1191#endif
1135 1192
1136 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, reason)) 1193 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
1137 BUG(); 1194 BUG();
1138} 1195}
1139 1196
@@ -1188,6 +1245,8 @@ asmlinkage void __init xen_start_kernel(void)
1188 1245
1189 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); 1246 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
1190 1247
1248 xen_setup_features();
1249
1191 /* Install Xen paravirt ops */ 1250 /* Install Xen paravirt ops */
1192 pv_info = xen_info; 1251 pv_info = xen_info;
1193 pv_init_ops = xen_init_ops; 1252 pv_init_ops = xen_init_ops;
@@ -1197,17 +1256,20 @@ asmlinkage void __init xen_start_kernel(void)
1197 pv_apic_ops = xen_apic_ops; 1256 pv_apic_ops = xen_apic_ops;
1198 pv_mmu_ops = xen_mmu_ops; 1257 pv_mmu_ops = xen_mmu_ops;
1199 1258
1259 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1260 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1261 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
1262 }
1263
1200 machine_ops = xen_machine_ops; 1264 machine_ops = xen_machine_ops;
1201 1265
1202#ifdef CONFIG_SMP 1266#ifdef CONFIG_SMP
1203 smp_ops = xen_smp_ops; 1267 smp_ops = xen_smp_ops;
1204#endif 1268#endif
1205 1269
1206 xen_setup_features();
1207
1208 /* Get mfn list */ 1270 /* Get mfn list */
1209 if (!xen_feature(XENFEAT_auto_translated_physmap)) 1271 if (!xen_feature(XENFEAT_auto_translated_physmap))
1210 phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list; 1272 xen_build_dynamic_phys_to_machine();
1211 1273
1212 pgd = (pgd_t *)xen_start_info->pt_base; 1274 pgd = (pgd_t *)xen_start_info->pt_base;
1213 1275
@@ -1228,6 +1290,11 @@ asmlinkage void __init xen_start_kernel(void)
1228 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1290 if (xen_feature(XENFEAT_supervisor_mode_kernel))
1229 pv_info.kernel_rpl = 0; 1291 pv_info.kernel_rpl = 0;
1230 1292
1293 /* Prevent unwanted bits from being set in PTEs. */
1294 __supported_pte_mask &= ~_PAGE_GLOBAL;
1295 if (!is_initial_xendomain())
1296 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1297
1231 /* set the limit of our address space */ 1298 /* set the limit of our address space */
1232 xen_reserve_top(); 1299 xen_reserve_top();
1233 1300
@@ -1242,8 +1309,11 @@ asmlinkage void __init xen_start_kernel(void)
1242 ? __pa(xen_start_info->mod_start) : 0; 1309 ? __pa(xen_start_info->mod_start) : 0;
1243 boot_params.hdr.ramdisk_size = xen_start_info->mod_len; 1310 boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
1244 1311
1245 if (!is_initial_xendomain()) 1312 if (!is_initial_xendomain()) {
1313 add_preferred_console("xenboot", 0, NULL);
1314 add_preferred_console("tty", 0, NULL);
1246 add_preferred_console("hvc", 0, NULL); 1315 add_preferred_console("hvc", 0, NULL);
1316 }
1247 1317
1248 /* Start the world */ 1318 /* Start the world */
1249 start_kernel(); 1319 start_kernel();