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.c176
1 files changed, 147 insertions, 29 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index f09c1c69c37a..dcd4e51f2f16 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -45,6 +45,7 @@
45#include <asm/pgtable.h> 45#include <asm/pgtable.h>
46#include <asm/tlbflush.h> 46#include <asm/tlbflush.h>
47#include <asm/reboot.h> 47#include <asm/reboot.h>
48#include <asm/pgalloc.h>
48 49
49#include "xen-ops.h" 50#include "xen-ops.h"
50#include "mmu.h" 51#include "mmu.h"
@@ -75,13 +76,13 @@ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
75struct start_info *xen_start_info; 76struct start_info *xen_start_info;
76EXPORT_SYMBOL_GPL(xen_start_info); 77EXPORT_SYMBOL_GPL(xen_start_info);
77 78
78static /* __initdata */ struct shared_info dummy_shared_info; 79struct shared_info xen_dummy_shared_info;
79 80
80/* 81/*
81 * Point at some empty memory to start with. We map the real shared_info 82 * Point at some empty memory to start with. We map the real shared_info
82 * page as soon as fixmap is up and running. 83 * page as soon as fixmap is up and running.
83 */ 84 */
84struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info; 85struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
85 86
86/* 87/*
87 * Flag to determine whether vcpu info placement is available on all 88 * Flag to determine whether vcpu info placement is available on all
@@ -98,13 +99,13 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info;
98 */ 99 */
99static int have_vcpu_info_placement = 1; 100static int have_vcpu_info_placement = 1;
100 101
101static void __init xen_vcpu_setup(int cpu) 102static void xen_vcpu_setup(int cpu)
102{ 103{
103 struct vcpu_register_vcpu_info info; 104 struct vcpu_register_vcpu_info info;
104 int err; 105 int err;
105 struct vcpu_info *vcpup; 106 struct vcpu_info *vcpup;
106 107
107 BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info); 108 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
108 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 109 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
109 110
110 if (!have_vcpu_info_placement) 111 if (!have_vcpu_info_placement)
@@ -136,11 +137,41 @@ static void __init xen_vcpu_setup(int cpu)
136 } 137 }
137} 138}
138 139
140/*
141 * On restore, set the vcpu placement up again.
142 * If it fails, then we're in a bad state, since
143 * we can't back out from using it...
144 */
145void xen_vcpu_restore(void)
146{
147 if (have_vcpu_info_placement) {
148 int cpu;
149
150 for_each_online_cpu(cpu) {
151 bool other_cpu = (cpu != smp_processor_id());
152
153 if (other_cpu &&
154 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
155 BUG();
156
157 xen_vcpu_setup(cpu);
158
159 if (other_cpu &&
160 HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
161 BUG();
162 }
163
164 BUG_ON(!have_vcpu_info_placement);
165 }
166}
167
139static void __init xen_banner(void) 168static void __init xen_banner(void)
140{ 169{
141 printk(KERN_INFO "Booting paravirtualized kernel on %s\n", 170 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
142 pv_info.name); 171 pv_info.name);
143 printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic); 172 printk(KERN_INFO "Hypervisor signature: %s%s\n",
173 xen_start_info->magic,
174 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
144} 175}
145 176
146static void xen_cpuid(unsigned int *ax, unsigned int *bx, 177static void xen_cpuid(unsigned int *ax, unsigned int *bx,
@@ -235,13 +266,13 @@ static void xen_irq_enable(void)
235{ 266{
236 struct vcpu_info *vcpu; 267 struct vcpu_info *vcpu;
237 268
238 /* There's a one instruction preempt window here. We need to 269 /* We don't need to worry about being preempted here, since
239 make sure we're don't switch CPUs between getting the vcpu 270 either a) interrupts are disabled, so no preemption, or b)
240 pointer and updating the mask. */ 271 the caller is confused and is trying to re-enable interrupts
241 preempt_disable(); 272 on an indeterminate processor. */
273
242 vcpu = x86_read_percpu(xen_vcpu); 274 vcpu = x86_read_percpu(xen_vcpu);
243 vcpu->evtchn_upcall_mask = 0; 275 vcpu->evtchn_upcall_mask = 0;
244 preempt_enable_no_resched();
245 276
246 /* Doesn't matter if we get preempted here, because any 277 /* Doesn't matter if we get preempted here, because any
247 pending event will get dealt with anyway. */ 278 pending event will get dealt with anyway. */
@@ -254,7 +285,7 @@ static void xen_irq_enable(void)
254static void xen_safe_halt(void) 285static void xen_safe_halt(void)
255{ 286{
256 /* Blocking includes an implicit local_irq_enable(). */ 287 /* Blocking includes an implicit local_irq_enable(). */
257 if (HYPERVISOR_sched_op(SCHEDOP_block, 0) != 0) 288 if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)
258 BUG(); 289 BUG();
259} 290}
260 291
@@ -607,6 +638,30 @@ static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
607 xen_mc_issue(PARAVIRT_LAZY_MMU); 638 xen_mc_issue(PARAVIRT_LAZY_MMU);
608} 639}
609 640
641static void xen_clts(void)
642{
643 struct multicall_space mcs;
644
645 mcs = xen_mc_entry(0);
646
647 MULTI_fpu_taskswitch(mcs.mc, 0);
648
649 xen_mc_issue(PARAVIRT_LAZY_CPU);
650}
651
652static void xen_write_cr0(unsigned long cr0)
653{
654 struct multicall_space mcs;
655
656 /* Only pay attention to cr0.TS; everything else is
657 ignored. */
658 mcs = xen_mc_entry(0);
659
660 MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0);
661
662 xen_mc_issue(PARAVIRT_LAZY_CPU);
663}
664
610static void xen_write_cr2(unsigned long cr2) 665static void xen_write_cr2(unsigned long cr2)
611{ 666{
612 x86_read_percpu(xen_vcpu)->arch.cr2 = cr2; 667 x86_read_percpu(xen_vcpu)->arch.cr2 = cr2;
@@ -624,8 +679,10 @@ static unsigned long xen_read_cr2_direct(void)
624 679
625static void xen_write_cr4(unsigned long cr4) 680static void xen_write_cr4(unsigned long cr4)
626{ 681{
627 /* Just ignore cr4 changes; Xen doesn't allow us to do 682 cr4 &= ~X86_CR4_PGE;
628 anything anyway. */ 683 cr4 &= ~X86_CR4_PSE;
684
685 native_write_cr4(cr4);
629} 686}
630 687
631static unsigned long xen_read_cr3(void) 688static unsigned long xen_read_cr3(void)
@@ -831,7 +888,7 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
831 PFN_DOWN(__pa(xen_start_info->pt_base))); 888 PFN_DOWN(__pa(xen_start_info->pt_base)));
832} 889}
833 890
834static __init void setup_shared_info(void) 891void xen_setup_shared_info(void)
835{ 892{
836 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 893 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
837 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP); 894 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
@@ -854,6 +911,8 @@ static __init void setup_shared_info(void)
854 /* In UP this is as good a place as any to set up shared info */ 911 /* In UP this is as good a place as any to set up shared info */
855 xen_setup_vcpu_info_placement(); 912 xen_setup_vcpu_info_placement();
856#endif 913#endif
914
915 xen_setup_mfn_list_list();
857} 916}
858 917
859static __init void xen_pagetable_setup_done(pgd_t *base) 918static __init void xen_pagetable_setup_done(pgd_t *base)
@@ -866,15 +925,23 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
866 pv_mmu_ops.release_pmd = xen_release_pmd; 925 pv_mmu_ops.release_pmd = xen_release_pmd;
867 pv_mmu_ops.set_pte = xen_set_pte; 926 pv_mmu_ops.set_pte = xen_set_pte;
868 927
869 setup_shared_info(); 928 xen_setup_shared_info();
870 929
871 /* Actually pin the pagetable down, but we can't set PG_pinned 930 /* Actually pin the pagetable down, but we can't set PG_pinned
872 yet because the page structures don't exist yet. */ 931 yet because the page structures don't exist yet. */
873 pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base))); 932 pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
874} 933}
875 934
935static __init void xen_post_allocator_init(void)
936{
937 pv_mmu_ops.set_pmd = xen_set_pmd;
938 pv_mmu_ops.set_pud = xen_set_pud;
939
940 xen_mark_init_mm_pinned();
941}
942
876/* This is called once we have the cpu_possible_map */ 943/* This is called once we have the cpu_possible_map */
877void __init xen_setup_vcpu_info_placement(void) 944void xen_setup_vcpu_info_placement(void)
878{ 945{
879 int cpu; 946 int cpu;
880 947
@@ -947,6 +1014,33 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
947 return ret; 1014 return ret;
948} 1015}
949 1016
1017static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
1018{
1019 pte_t pte;
1020
1021 phys >>= PAGE_SHIFT;
1022
1023 switch (idx) {
1024 case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
1025#ifdef CONFIG_X86_F00F_BUG
1026 case FIX_F00F_IDT:
1027#endif
1028 case FIX_WP_TEST:
1029 case FIX_VDSO:
1030#ifdef CONFIG_X86_LOCAL_APIC
1031 case FIX_APIC_BASE: /* maps dummy local APIC */
1032#endif
1033 pte = pfn_pte(phys, prot);
1034 break;
1035
1036 default:
1037 pte = mfn_pte(phys, prot);
1038 break;
1039 }
1040
1041 __native_set_fixmap(idx, pte);
1042}
1043
950static const struct pv_info xen_info __initdata = { 1044static const struct pv_info xen_info __initdata = {
951 .paravirt_enabled = 1, 1045 .paravirt_enabled = 1,
952 .shared_kernel_pmd = 0, 1046 .shared_kernel_pmd = 0,
@@ -960,7 +1054,7 @@ static const struct pv_init_ops xen_init_ops __initdata = {
960 .banner = xen_banner, 1054 .banner = xen_banner,
961 .memory_setup = xen_memory_setup, 1055 .memory_setup = xen_memory_setup,
962 .arch_setup = xen_arch_setup, 1056 .arch_setup = xen_arch_setup,
963 .post_allocator_init = xen_mark_init_mm_pinned, 1057 .post_allocator_init = xen_post_allocator_init,
964}; 1058};
965 1059
966static const struct pv_time_ops xen_time_ops __initdata = { 1060static const struct pv_time_ops xen_time_ops __initdata = {
@@ -968,7 +1062,7 @@ static const struct pv_time_ops xen_time_ops __initdata = {
968 1062
969 .set_wallclock = xen_set_wallclock, 1063 .set_wallclock = xen_set_wallclock,
970 .get_wallclock = xen_get_wallclock, 1064 .get_wallclock = xen_get_wallclock,
971 .get_cpu_khz = xen_cpu_khz, 1065 .get_tsc_khz = xen_tsc_khz,
972 .sched_clock = xen_sched_clock, 1066 .sched_clock = xen_sched_clock,
973}; 1067};
974 1068
@@ -978,10 +1072,10 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
978 .set_debugreg = xen_set_debugreg, 1072 .set_debugreg = xen_set_debugreg,
979 .get_debugreg = xen_get_debugreg, 1073 .get_debugreg = xen_get_debugreg,
980 1074
981 .clts = native_clts, 1075 .clts = xen_clts,
982 1076
983 .read_cr0 = native_read_cr0, 1077 .read_cr0 = native_read_cr0,
984 .write_cr0 = native_write_cr0, 1078 .write_cr0 = xen_write_cr0,
985 1079
986 .read_cr4 = native_read_cr4, 1080 .read_cr4 = native_read_cr4,
987 .read_cr4_safe = native_read_cr4_safe, 1081 .read_cr4_safe = native_read_cr4_safe,
@@ -995,7 +1089,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
995 .read_pmc = native_read_pmc, 1089 .read_pmc = native_read_pmc,
996 1090
997 .iret = xen_iret, 1091 .iret = xen_iret,
998 .irq_enable_syscall_ret = xen_sysexit, 1092 .irq_enable_sysexit = xen_sysexit,
999 1093
1000 .load_tr_desc = paravirt_nop, 1094 .load_tr_desc = paravirt_nop,
1001 .set_ldt = xen_set_ldt, 1095 .set_ldt = xen_set_ldt,
@@ -1029,6 +1123,9 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
1029 .irq_enable = xen_irq_enable, 1123 .irq_enable = xen_irq_enable,
1030 .safe_halt = xen_safe_halt, 1124 .safe_halt = xen_safe_halt,
1031 .halt = xen_halt, 1125 .halt = xen_halt,
1126#ifdef CONFIG_X86_64
1127 .adjust_exception_frame = paravirt_nop,
1128#endif
1032}; 1129};
1033 1130
1034static const struct pv_apic_ops xen_apic_ops __initdata = { 1131static const struct pv_apic_ops xen_apic_ops __initdata = {
@@ -1060,6 +1157,9 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1060 .pte_update = paravirt_nop, 1157 .pte_update = paravirt_nop,
1061 .pte_update_defer = paravirt_nop, 1158 .pte_update_defer = paravirt_nop,
1062 1159
1160 .pgd_alloc = __paravirt_pgd_alloc,
1161 .pgd_free = paravirt_nop,
1162
1063 .alloc_pte = xen_alloc_pte_init, 1163 .alloc_pte = xen_alloc_pte_init,
1064 .release_pte = xen_release_pte_init, 1164 .release_pte = xen_release_pte_init,
1065 .alloc_pmd = xen_alloc_pte_init, 1165 .alloc_pmd = xen_alloc_pte_init,
@@ -1072,9 +1172,13 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1072 1172
1073 .set_pte = NULL, /* see xen_pagetable_setup_* */ 1173 .set_pte = NULL, /* see xen_pagetable_setup_* */
1074 .set_pte_at = xen_set_pte_at, 1174 .set_pte_at = xen_set_pte_at,
1075 .set_pmd = xen_set_pmd, 1175 .set_pmd = xen_set_pmd_hyper,
1176
1177 .ptep_modify_prot_start = __ptep_modify_prot_start,
1178 .ptep_modify_prot_commit = __ptep_modify_prot_commit,
1076 1179
1077 .pte_val = xen_pte_val, 1180 .pte_val = xen_pte_val,
1181 .pte_flags = native_pte_val,
1078 .pgd_val = xen_pgd_val, 1182 .pgd_val = xen_pgd_val,
1079 1183
1080 .make_pte = xen_make_pte, 1184 .make_pte = xen_make_pte,
@@ -1082,7 +1186,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1082 1186
1083 .set_pte_atomic = xen_set_pte_atomic, 1187 .set_pte_atomic = xen_set_pte_atomic,
1084 .set_pte_present = xen_set_pte_at, 1188 .set_pte_present = xen_set_pte_at,
1085 .set_pud = xen_set_pud, 1189 .set_pud = xen_set_pud_hyper,
1086 .pte_clear = xen_pte_clear, 1190 .pte_clear = xen_pte_clear,
1087 .pmd_clear = xen_pmd_clear, 1191 .pmd_clear = xen_pmd_clear,
1088 1192
@@ -1097,6 +1201,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1097 .enter = paravirt_enter_lazy_mmu, 1201 .enter = paravirt_enter_lazy_mmu,
1098 .leave = xen_leave_lazy, 1202 .leave = xen_leave_lazy,
1099 }, 1203 },
1204
1205 .set_fixmap = xen_set_fixmap,
1100}; 1206};
1101 1207
1102#ifdef CONFIG_SMP 1208#ifdef CONFIG_SMP
@@ -1114,11 +1220,13 @@ static const struct smp_ops xen_smp_ops __initdata = {
1114 1220
1115static void xen_reboot(int reason) 1221static void xen_reboot(int reason)
1116{ 1222{
1223 struct sched_shutdown r = { .reason = reason };
1224
1117#ifdef CONFIG_SMP 1225#ifdef CONFIG_SMP
1118 smp_send_stop(); 1226 smp_send_stop();
1119#endif 1227#endif
1120 1228
1121 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, reason)) 1229 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
1122 BUG(); 1230 BUG();
1123} 1231}
1124 1232
@@ -1173,6 +1281,8 @@ asmlinkage void __init xen_start_kernel(void)
1173 1281
1174 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); 1282 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
1175 1283
1284 xen_setup_features();
1285
1176 /* Install Xen paravirt ops */ 1286 /* Install Xen paravirt ops */
1177 pv_info = xen_info; 1287 pv_info = xen_info;
1178 pv_init_ops = xen_init_ops; 1288 pv_init_ops = xen_init_ops;
@@ -1182,21 +1292,26 @@ asmlinkage void __init xen_start_kernel(void)
1182 pv_apic_ops = xen_apic_ops; 1292 pv_apic_ops = xen_apic_ops;
1183 pv_mmu_ops = xen_mmu_ops; 1293 pv_mmu_ops = xen_mmu_ops;
1184 1294
1295 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1296 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1297 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
1298 }
1299
1185 machine_ops = xen_machine_ops; 1300 machine_ops = xen_machine_ops;
1186 1301
1187#ifdef CONFIG_SMP 1302#ifdef CONFIG_SMP
1188 smp_ops = xen_smp_ops; 1303 smp_ops = xen_smp_ops;
1189#endif 1304#endif
1190 1305
1191 xen_setup_features();
1192
1193 /* Get mfn list */ 1306 /* Get mfn list */
1194 if (!xen_feature(XENFEAT_auto_translated_physmap)) 1307 if (!xen_feature(XENFEAT_auto_translated_physmap))
1195 phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list; 1308 xen_build_dynamic_phys_to_machine();
1196 1309
1197 pgd = (pgd_t *)xen_start_info->pt_base; 1310 pgd = (pgd_t *)xen_start_info->pt_base;
1198 1311
1312 init_pg_tables_start = __pa(pgd);
1199 init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE; 1313 init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
1314 max_pfn_mapped = (init_pg_tables_end + 512*1024) >> PAGE_SHIFT;
1200 1315
1201 init_mm.pgd = pgd; /* use the Xen pagetables to start */ 1316 init_mm.pgd = pgd; /* use the Xen pagetables to start */
1202 1317
@@ -1232,9 +1347,12 @@ asmlinkage void __init xen_start_kernel(void)
1232 ? __pa(xen_start_info->mod_start) : 0; 1347 ? __pa(xen_start_info->mod_start) : 0;
1233 boot_params.hdr.ramdisk_size = xen_start_info->mod_len; 1348 boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
1234 1349
1235 if (!is_initial_xendomain()) 1350 if (!is_initial_xendomain()) {
1351 add_preferred_console("xenboot", 0, NULL);
1352 add_preferred_console("tty", 0, NULL);
1236 add_preferred_console("hvc", 0, NULL); 1353 add_preferred_console("hvc", 0, NULL);
1354 }
1237 1355
1238 /* Start the world */ 1356 /* Start the world */
1239 start_kernel(); 1357 i386_start_kernel();
1240} 1358}