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.c232
1 files changed, 171 insertions, 61 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c8a56e457d61..bb508456ef52 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)
@@ -785,38 +842,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
785static __init void xen_pagetable_setup_start(pgd_t *base) 842static __init void xen_pagetable_setup_start(pgd_t *base)
786{ 843{
787 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base; 844 pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
845 int i;
788 846
789 /* special set_pte for pagetable initialization */ 847 /* special set_pte for pagetable initialization */
790 pv_mmu_ops.set_pte = xen_set_pte_init; 848 pv_mmu_ops.set_pte = xen_set_pte_init;
791 849
792 init_mm.pgd = base; 850 init_mm.pgd = base;
793 /* 851 /*
794 * copy top-level of Xen-supplied pagetable into place. For 852 * 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 853 * is a stand-in while we copy the pmd pages.
796 * while we copy the pmd pages.
797 */ 854 */
798 memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t)); 855 memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
799 856
800 if (PTRS_PER_PMD > 1) { 857 /*
801 int i; 858 * For PAE, need to allocate new pmds, rather than
802 /* 859 * share Xen's, since Xen doesn't like pmd's being
803 * For PAE, need to allocate new pmds, rather than 860 * shared between address spaces.
804 * share Xen's, since Xen doesn't like pmd's being 861 */
805 * shared between address spaces. 862 for (i = 0; i < PTRS_PER_PGD; i++) {
806 */ 863 if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
807 for (i = 0; i < PTRS_PER_PGD; i++) { 864 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 865
811 memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), 866 memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
812 PAGE_SIZE); 867 PAGE_SIZE);
813 868
814 make_lowmem_page_readonly(pmd); 869 make_lowmem_page_readonly(pmd);
815 870
816 set_pgd(&base[i], __pgd(1 + __pa(pmd))); 871 set_pgd(&base[i], __pgd(1 + __pa(pmd)));
817 } else 872 } else
818 pgd_clear(&base[i]); 873 pgd_clear(&base[i]);
819 }
820 } 874 }
821 875
822 /* make sure zero_page is mapped RO so we can use it in pagetables */ 876 /* make sure zero_page is mapped RO so we can use it in pagetables */
@@ -834,7 +888,7 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
834 PFN_DOWN(__pa(xen_start_info->pt_base))); 888 PFN_DOWN(__pa(xen_start_info->pt_base)));
835} 889}
836 890
837static __init void setup_shared_info(void) 891void xen_setup_shared_info(void)
838{ 892{
839 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 893 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
840 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP); 894 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
@@ -857,6 +911,8 @@ static __init void setup_shared_info(void)
857 /* 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 */
858 xen_setup_vcpu_info_placement(); 912 xen_setup_vcpu_info_placement();
859#endif 913#endif
914
915 xen_setup_mfn_list_list();
860} 916}
861 917
862static __init void xen_pagetable_setup_done(pgd_t *base) 918static __init void xen_pagetable_setup_done(pgd_t *base)
@@ -869,25 +925,23 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
869 pv_mmu_ops.release_pmd = xen_release_pmd; 925 pv_mmu_ops.release_pmd = xen_release_pmd;
870 pv_mmu_ops.set_pte = xen_set_pte; 926 pv_mmu_ops.set_pte = xen_set_pte;
871 927
872 setup_shared_info(); 928 xen_setup_shared_info();
873 929
874 /* 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
875 yet because the page structures don't exist yet. */ 931 yet because the page structures don't exist yet. */
876 { 932 pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
877 unsigned level; 933}
878 934
879#ifdef CONFIG_X86_PAE 935static __init void xen_post_allocator_init(void)
880 level = MMUEXT_PIN_L3_TABLE; 936{
881#else 937 pv_mmu_ops.set_pmd = xen_set_pmd;
882 level = MMUEXT_PIN_L2_TABLE; 938 pv_mmu_ops.set_pud = xen_set_pud;
883#endif
884 939
885 pin_pagetable_pfn(level, PFN_DOWN(__pa(base))); 940 xen_mark_init_mm_pinned();
886 }
887} 941}
888 942
889/* This is called once we have the cpu_possible_map */ 943/* This is called once we have the cpu_possible_map */
890void __init xen_setup_vcpu_info_placement(void) 944void xen_setup_vcpu_info_placement(void)
891{ 945{
892 int cpu; 946 int cpu;
893 947
@@ -960,6 +1014,33 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
960 return ret; 1014 return ret;
961} 1015}
962 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
963static const struct pv_info xen_info __initdata = { 1044static const struct pv_info xen_info __initdata = {
964 .paravirt_enabled = 1, 1045 .paravirt_enabled = 1,
965 .shared_kernel_pmd = 0, 1046 .shared_kernel_pmd = 0,
@@ -973,7 +1054,7 @@ static const struct pv_init_ops xen_init_ops __initdata = {
973 .banner = xen_banner, 1054 .banner = xen_banner,
974 .memory_setup = xen_memory_setup, 1055 .memory_setup = xen_memory_setup,
975 .arch_setup = xen_arch_setup, 1056 .arch_setup = xen_arch_setup,
976 .post_allocator_init = xen_mark_init_mm_pinned, 1057 .post_allocator_init = xen_post_allocator_init,
977}; 1058};
978 1059
979static const struct pv_time_ops xen_time_ops __initdata = { 1060static const struct pv_time_ops xen_time_ops __initdata = {
@@ -981,7 +1062,7 @@ static const struct pv_time_ops xen_time_ops __initdata = {
981 1062
982 .set_wallclock = xen_set_wallclock, 1063 .set_wallclock = xen_set_wallclock,
983 .get_wallclock = xen_get_wallclock, 1064 .get_wallclock = xen_get_wallclock,
984 .get_cpu_khz = xen_cpu_khz, 1065 .get_tsc_khz = xen_tsc_khz,
985 .sched_clock = xen_sched_clock, 1066 .sched_clock = xen_sched_clock,
986}; 1067};
987 1068
@@ -991,10 +1072,10 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
991 .set_debugreg = xen_set_debugreg, 1072 .set_debugreg = xen_set_debugreg,
992 .get_debugreg = xen_get_debugreg, 1073 .get_debugreg = xen_get_debugreg,
993 1074
994 .clts = native_clts, 1075 .clts = xen_clts,
995 1076
996 .read_cr0 = native_read_cr0, 1077 .read_cr0 = native_read_cr0,
997 .write_cr0 = native_write_cr0, 1078 .write_cr0 = xen_write_cr0,
998 1079
999 .read_cr4 = native_read_cr4, 1080 .read_cr4 = native_read_cr4,
1000 .read_cr4_safe = native_read_cr4_safe, 1081 .read_cr4_safe = native_read_cr4_safe,
@@ -1008,7 +1089,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
1008 .read_pmc = native_read_pmc, 1089 .read_pmc = native_read_pmc,
1009 1090
1010 .iret = xen_iret, 1091 .iret = xen_iret,
1011 .irq_enable_syscall_ret = xen_sysexit, 1092 .irq_enable_sysexit = xen_sysexit,
1012 1093
1013 .load_tr_desc = paravirt_nop, 1094 .load_tr_desc = paravirt_nop,
1014 .set_ldt = xen_set_ldt, 1095 .set_ldt = xen_set_ldt,
@@ -1042,6 +1123,9 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
1042 .irq_enable = xen_irq_enable, 1123 .irq_enable = xen_irq_enable,
1043 .safe_halt = xen_safe_halt, 1124 .safe_halt = xen_safe_halt,
1044 .halt = xen_halt, 1125 .halt = xen_halt,
1126#ifdef CONFIG_X86_64
1127 .adjust_exception_frame = paravirt_nop,
1128#endif
1045}; 1129};
1046 1130
1047static const struct pv_apic_ops xen_apic_ops __initdata = { 1131static const struct pv_apic_ops xen_apic_ops __initdata = {
@@ -1073,6 +1157,9 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1073 .pte_update = paravirt_nop, 1157 .pte_update = paravirt_nop,
1074 .pte_update_defer = paravirt_nop, 1158 .pte_update_defer = paravirt_nop,
1075 1159
1160 .pgd_alloc = __paravirt_pgd_alloc,
1161 .pgd_free = paravirt_nop,
1162
1076 .alloc_pte = xen_alloc_pte_init, 1163 .alloc_pte = xen_alloc_pte_init,
1077 .release_pte = xen_release_pte_init, 1164 .release_pte = xen_release_pte_init,
1078 .alloc_pmd = xen_alloc_pte_init, 1165 .alloc_pmd = xen_alloc_pte_init,
@@ -1085,24 +1172,26 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1085 1172
1086 .set_pte = NULL, /* see xen_pagetable_setup_* */ 1173 .set_pte = NULL, /* see xen_pagetable_setup_* */
1087 .set_pte_at = xen_set_pte_at, 1174 .set_pte_at = xen_set_pte_at,
1088 .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,
1089 1179
1090 .pte_val = xen_pte_val, 1180 .pte_val = xen_pte_val,
1181 .pte_flags = native_pte_val,
1091 .pgd_val = xen_pgd_val, 1182 .pgd_val = xen_pgd_val,
1092 1183
1093 .make_pte = xen_make_pte, 1184 .make_pte = xen_make_pte,
1094 .make_pgd = xen_make_pgd, 1185 .make_pgd = xen_make_pgd,
1095 1186
1096#ifdef CONFIG_X86_PAE
1097 .set_pte_atomic = xen_set_pte_atomic, 1187 .set_pte_atomic = xen_set_pte_atomic,
1098 .set_pte_present = xen_set_pte_at, 1188 .set_pte_present = xen_set_pte_at,
1099 .set_pud = xen_set_pud, 1189 .set_pud = xen_set_pud_hyper,
1100 .pte_clear = xen_pte_clear, 1190 .pte_clear = xen_pte_clear,
1101 .pmd_clear = xen_pmd_clear, 1191 .pmd_clear = xen_pmd_clear,
1102 1192
1103 .make_pmd = xen_make_pmd, 1193 .make_pmd = xen_make_pmd,
1104 .pmd_val = xen_pmd_val, 1194 .pmd_val = xen_pmd_val,
1105#endif /* PAE */
1106 1195
1107 .activate_mm = xen_activate_mm, 1196 .activate_mm = xen_activate_mm,
1108 .dup_mmap = xen_dup_mmap, 1197 .dup_mmap = xen_dup_mmap,
@@ -1112,6 +1201,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1112 .enter = paravirt_enter_lazy_mmu, 1201 .enter = paravirt_enter_lazy_mmu,
1113 .leave = xen_leave_lazy, 1202 .leave = xen_leave_lazy,
1114 }, 1203 },
1204
1205 .set_fixmap = xen_set_fixmap,
1115}; 1206};
1116 1207
1117#ifdef CONFIG_SMP 1208#ifdef CONFIG_SMP
@@ -1123,17 +1214,21 @@ static const struct smp_ops xen_smp_ops __initdata = {
1123 1214
1124 .smp_send_stop = xen_smp_send_stop, 1215 .smp_send_stop = xen_smp_send_stop,
1125 .smp_send_reschedule = xen_smp_send_reschedule, 1216 .smp_send_reschedule = xen_smp_send_reschedule,
1126 .smp_call_function_mask = xen_smp_call_function_mask, 1217
1218 .send_call_func_ipi = xen_smp_send_call_function_ipi,
1219 .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi,
1127}; 1220};
1128#endif /* CONFIG_SMP */ 1221#endif /* CONFIG_SMP */
1129 1222
1130static void xen_reboot(int reason) 1223static void xen_reboot(int reason)
1131{ 1224{
1225 struct sched_shutdown r = { .reason = reason };
1226
1132#ifdef CONFIG_SMP 1227#ifdef CONFIG_SMP
1133 smp_send_stop(); 1228 smp_send_stop();
1134#endif 1229#endif
1135 1230
1136 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, reason)) 1231 if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
1137 BUG(); 1232 BUG();
1138} 1233}
1139 1234
@@ -1188,6 +1283,8 @@ asmlinkage void __init xen_start_kernel(void)
1188 1283
1189 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); 1284 BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
1190 1285
1286 xen_setup_features();
1287
1191 /* Install Xen paravirt ops */ 1288 /* Install Xen paravirt ops */
1192 pv_info = xen_info; 1289 pv_info = xen_info;
1193 pv_init_ops = xen_init_ops; 1290 pv_init_ops = xen_init_ops;
@@ -1197,21 +1294,26 @@ asmlinkage void __init xen_start_kernel(void)
1197 pv_apic_ops = xen_apic_ops; 1294 pv_apic_ops = xen_apic_ops;
1198 pv_mmu_ops = xen_mmu_ops; 1295 pv_mmu_ops = xen_mmu_ops;
1199 1296
1297 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1298 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1299 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
1300 }
1301
1200 machine_ops = xen_machine_ops; 1302 machine_ops = xen_machine_ops;
1201 1303
1202#ifdef CONFIG_SMP 1304#ifdef CONFIG_SMP
1203 smp_ops = xen_smp_ops; 1305 smp_ops = xen_smp_ops;
1204#endif 1306#endif
1205 1307
1206 xen_setup_features();
1207
1208 /* Get mfn list */ 1308 /* Get mfn list */
1209 if (!xen_feature(XENFEAT_auto_translated_physmap)) 1309 if (!xen_feature(XENFEAT_auto_translated_physmap))
1210 phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list; 1310 xen_build_dynamic_phys_to_machine();
1211 1311
1212 pgd = (pgd_t *)xen_start_info->pt_base; 1312 pgd = (pgd_t *)xen_start_info->pt_base;
1213 1313
1314 init_pg_tables_start = __pa(pgd);
1214 init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE; 1315 init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
1316 max_pfn_mapped = (init_pg_tables_end + 512*1024) >> PAGE_SHIFT;
1215 1317
1216 init_mm.pgd = pgd; /* use the Xen pagetables to start */ 1318 init_mm.pgd = pgd; /* use the Xen pagetables to start */
1217 1319
@@ -1228,6 +1330,11 @@ asmlinkage void __init xen_start_kernel(void)
1228 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1330 if (xen_feature(XENFEAT_supervisor_mode_kernel))
1229 pv_info.kernel_rpl = 0; 1331 pv_info.kernel_rpl = 0;
1230 1332
1333 /* Prevent unwanted bits from being set in PTEs. */
1334 __supported_pte_mask &= ~_PAGE_GLOBAL;
1335 if (!is_initial_xendomain())
1336 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1337
1231 /* set the limit of our address space */ 1338 /* set the limit of our address space */
1232 xen_reserve_top(); 1339 xen_reserve_top();
1233 1340
@@ -1242,9 +1349,12 @@ asmlinkage void __init xen_start_kernel(void)
1242 ? __pa(xen_start_info->mod_start) : 0; 1349 ? __pa(xen_start_info->mod_start) : 0;
1243 boot_params.hdr.ramdisk_size = xen_start_info->mod_len; 1350 boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
1244 1351
1245 if (!is_initial_xendomain()) 1352 if (!is_initial_xendomain()) {
1353 add_preferred_console("xenboot", 0, NULL);
1354 add_preferred_console("tty", 0, NULL);
1246 add_preferred_console("hvc", 0, NULL); 1355 add_preferred_console("hvc", 0, NULL);
1356 }
1247 1357
1248 /* Start the world */ 1358 /* Start the world */
1249 start_kernel(); 1359 i386_start_kernel();
1250} 1360}