diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-07-08 18:07:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-16 05:06:20 -0400 |
commit | 1153968a48e3ca3e2b7a437e8b82ec9e6f768e24 (patch) | |
tree | 1dd347e5ae7a472f2757915d5927eaca4404d15a /arch | |
parent | bf18bf94dc72db998d0fbebc846c07c858a59c90 (diff) |
xen: implement Xen write_msr operation
64-bit uses MSRs for important things like the base for fs and
gs-prefixed addresses. It's more efficient to use a hypercall to
update these, rather than go via the trap and emulate path.
Other MSR writes are just passed through; in an unprivileged domain
they do nothing, but it might be useful later.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: Stephen Tweedie <sct@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/xen/enlighten.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index f64b8729cd07..776c0fb77d69 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/xen/hypervisor.h> | 41 | #include <asm/xen/hypervisor.h> |
42 | #include <asm/fixmap.h> | 42 | #include <asm/fixmap.h> |
43 | #include <asm/processor.h> | 43 | #include <asm/processor.h> |
44 | #include <asm/msr-index.h> | ||
44 | #include <asm/setup.h> | 45 | #include <asm/setup.h> |
45 | #include <asm/desc.h> | 46 | #include <asm/desc.h> |
46 | #include <asm/pgtable.h> | 47 | #include <asm/pgtable.h> |
@@ -777,6 +778,34 @@ static void xen_write_cr3(unsigned long cr3) | |||
777 | xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */ | 778 | xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */ |
778 | } | 779 | } |
779 | 780 | ||
781 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) | ||
782 | { | ||
783 | int ret; | ||
784 | |||
785 | ret = 0; | ||
786 | |||
787 | switch(msr) { | ||
788 | #ifdef CONFIG_X86_64 | ||
789 | unsigned which; | ||
790 | u64 base; | ||
791 | |||
792 | case MSR_FS_BASE: which = SEGBASE_FS; goto set; | ||
793 | case MSR_KERNEL_GS_BASE: which = SEGBASE_GS_USER; goto set; | ||
794 | case MSR_GS_BASE: which = SEGBASE_GS_KERNEL; goto set; | ||
795 | |||
796 | set: | ||
797 | base = ((u64)high << 32) | low; | ||
798 | if (HYPERVISOR_set_segment_base(which, base) != 0) | ||
799 | ret = -EFAULT; | ||
800 | break; | ||
801 | #endif | ||
802 | default: | ||
803 | ret = native_write_msr_safe(msr, low, high); | ||
804 | } | ||
805 | |||
806 | return ret; | ||
807 | } | ||
808 | |||
780 | /* Early in boot, while setting up the initial pagetable, assume | 809 | /* Early in boot, while setting up the initial pagetable, assume |
781 | everything is pinned. */ | 810 | everything is pinned. */ |
782 | static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn) | 811 | static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn) |
@@ -1165,7 +1194,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { | |||
1165 | .wbinvd = native_wbinvd, | 1194 | .wbinvd = native_wbinvd, |
1166 | 1195 | ||
1167 | .read_msr = native_read_msr_safe, | 1196 | .read_msr = native_read_msr_safe, |
1168 | .write_msr = native_write_msr_safe, | 1197 | .write_msr = xen_write_msr_safe, |
1169 | .read_tsc = native_read_tsc, | 1198 | .read_tsc = native_read_tsc, |
1170 | .read_pmc = native_read_pmc, | 1199 | .read_pmc = native_read_pmc, |
1171 | 1200 | ||