diff options
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r-- | arch/x86/xen/enlighten.c | 184 |
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 */ | |||
75 | struct start_info *xen_start_info; | 75 | struct start_info *xen_start_info; |
76 | EXPORT_SYMBOL_GPL(xen_start_info); | 76 | EXPORT_SYMBOL_GPL(xen_start_info); |
77 | 77 | ||
78 | static /* __initdata */ struct shared_info dummy_shared_info; | 78 | struct 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 | */ |
84 | struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info; | 84 | struct 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 | */ |
99 | static int have_vcpu_info_placement = 1; | 99 | static int have_vcpu_info_placement = 1; |
100 | 100 | ||
101 | static void __init xen_vcpu_setup(int cpu) | 101 | static 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 | */ | ||
144 | void 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 | |||
139 | static void __init xen_banner(void) | 167 | static 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 | ||
146 | static void xen_cpuid(unsigned int *ax, unsigned int *bx, | 176 | static 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) | |||
254 | static void xen_safe_halt(void) | 284 | static 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 | ||
640 | static 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 | |||
651 | static 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 | |||
610 | static void xen_write_cr2(unsigned long cr2) | 664 | static 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 | ||
625 | static void xen_write_cr4(unsigned long cr4) | 679 | static 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 | ||
631 | static unsigned long xen_read_cr3(void) | 687 | static unsigned long xen_read_cr3(void) |
@@ -785,38 +841,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) | |||
785 | static __init void xen_pagetable_setup_start(pgd_t *base) | 841 | static __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 | ||
837 | static __init void setup_shared_info(void) | 890 | void 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 | ||
862 | static __init void xen_pagetable_setup_done(pgd_t *base) | 917 | static __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 | 934 | static __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 */ |
890 | void __init xen_setup_vcpu_info_placement(void) | 943 | void 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 | ||
979 | static const struct pv_time_ops xen_time_ops __initdata = { | 1032 | static 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 | ||
1130 | static void xen_reboot(int reason) | 1185 | static 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(); |