diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-03-17 19:36:53 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-03-27 11:08:45 -0400 |
commit | 2e8fe719b57bbdc9e313daed1204bb55fed3ed44 (patch) | |
tree | cec338fa69120c53f63e5798f7fd87c0fa7800df | |
parent | 04c44a080d2f699a3042d4e743f7ad2ffae9d538 (diff) |
xen: fix UP setup of shared_info
We need to set up the shared_info pointer once we've mapped the real
shared_info into its fixmap slot. That needs to happen once the general
pagetable setup has been done. Previously, the UP shared_info was set
up one in xen_start_kernel, but that was left pointing to the dummy
shared info. Unfortunately there's no really good place to do a later
setup of the shared_info in UP, so just do it once the pagetable setup
has been done.
[ Stable: needed in 2.6.24.x ]
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: Stable Kernel <stable@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/xen/enlighten.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 1a20318c8cff..de4e6f05840b 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -103,6 +103,7 @@ static void __init xen_vcpu_setup(int cpu) | |||
103 | int err; | 103 | int err; |
104 | struct vcpu_info *vcpup; | 104 | struct vcpu_info *vcpup; |
105 | 105 | ||
106 | BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info); | ||
106 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; | 107 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; |
107 | 108 | ||
108 | if (!have_vcpu_info_placement) | 109 | if (!have_vcpu_info_placement) |
@@ -805,33 +806,43 @@ static __init void xen_pagetable_setup_start(pgd_t *base) | |||
805 | PFN_DOWN(__pa(xen_start_info->pt_base))); | 806 | PFN_DOWN(__pa(xen_start_info->pt_base))); |
806 | } | 807 | } |
807 | 808 | ||
808 | static __init void xen_pagetable_setup_done(pgd_t *base) | 809 | static __init void setup_shared_info(void) |
809 | { | 810 | { |
810 | /* This will work as long as patching hasn't happened yet | ||
811 | (which it hasn't) */ | ||
812 | pv_mmu_ops.alloc_pt = xen_alloc_pt; | ||
813 | pv_mmu_ops.alloc_pd = xen_alloc_pd; | ||
814 | pv_mmu_ops.release_pt = xen_release_pt; | ||
815 | pv_mmu_ops.release_pd = xen_release_pt; | ||
816 | pv_mmu_ops.set_pte = xen_set_pte; | ||
817 | |||
818 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | 811 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
812 | unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP); | ||
813 | |||
819 | /* | 814 | /* |
820 | * Create a mapping for the shared info page. | 815 | * Create a mapping for the shared info page. |
821 | * Should be set_fixmap(), but shared_info is a machine | 816 | * Should be set_fixmap(), but shared_info is a machine |
822 | * address with no corresponding pseudo-phys address. | 817 | * address with no corresponding pseudo-phys address. |
823 | */ | 818 | */ |
824 | set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP), | 819 | set_pte_mfn(addr, |
825 | PFN_DOWN(xen_start_info->shared_info), | 820 | PFN_DOWN(xen_start_info->shared_info), |
826 | PAGE_KERNEL); | 821 | PAGE_KERNEL); |
827 | 822 | ||
828 | HYPERVISOR_shared_info = | 823 | HYPERVISOR_shared_info = (struct shared_info *)addr; |
829 | (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); | ||
830 | |||
831 | } else | 824 | } else |
832 | HYPERVISOR_shared_info = | 825 | HYPERVISOR_shared_info = |
833 | (struct shared_info *)__va(xen_start_info->shared_info); | 826 | (struct shared_info *)__va(xen_start_info->shared_info); |
834 | 827 | ||
828 | #ifndef CONFIG_SMP | ||
829 | /* In UP this is as good a place as any to set up shared info */ | ||
830 | xen_setup_vcpu_info_placement(); | ||
831 | #endif | ||
832 | } | ||
833 | |||
834 | static __init void xen_pagetable_setup_done(pgd_t *base) | ||
835 | { | ||
836 | /* This will work as long as patching hasn't happened yet | ||
837 | (which it hasn't) */ | ||
838 | pv_mmu_ops.alloc_pt = xen_alloc_pt; | ||
839 | pv_mmu_ops.alloc_pd = xen_alloc_pd; | ||
840 | pv_mmu_ops.release_pt = xen_release_pt; | ||
841 | pv_mmu_ops.release_pd = xen_release_pt; | ||
842 | pv_mmu_ops.set_pte = xen_set_pte; | ||
843 | |||
844 | setup_shared_info(); | ||
845 | |||
835 | /* Actually pin the pagetable down, but we can't set PG_pinned | 846 | /* Actually pin the pagetable down, but we can't set PG_pinned |
836 | yet because the page structures don't exist yet. */ | 847 | yet because the page structures don't exist yet. */ |
837 | { | 848 | { |
@@ -1182,15 +1193,9 @@ asmlinkage void __init xen_start_kernel(void) | |||
1182 | x86_write_percpu(xen_cr3, __pa(pgd)); | 1193 | x86_write_percpu(xen_cr3, __pa(pgd)); |
1183 | x86_write_percpu(xen_current_cr3, __pa(pgd)); | 1194 | x86_write_percpu(xen_current_cr3, __pa(pgd)); |
1184 | 1195 | ||
1185 | #ifdef CONFIG_SMP | ||
1186 | /* Don't do the full vcpu_info placement stuff until we have a | 1196 | /* Don't do the full vcpu_info placement stuff until we have a |
1187 | possible map. */ | 1197 | possible map and a non-dummy shared_info. */ |
1188 | per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; | 1198 | per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; |
1189 | #else | ||
1190 | /* May as well do it now, since there's no good time to call | ||
1191 | it later on UP. */ | ||
1192 | xen_setup_vcpu_info_placement(); | ||
1193 | #endif | ||
1194 | 1199 | ||
1195 | pv_info.kernel_rpl = 1; | 1200 | pv_info.kernel_rpl = 1; |
1196 | if (xen_feature(XENFEAT_supervisor_mode_kernel)) | 1201 | if (xen_feature(XENFEAT_supervisor_mode_kernel)) |