aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-07-08 18:07:16 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-16 05:06:20 -0400
commit1153968a48e3ca3e2b7a437e8b82ec9e6f768e24 (patch)
tree1dd347e5ae7a472f2757915d5927eaca4404d15a /arch
parentbf18bf94dc72db998d0fbebc846c07c858a59c90 (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.c31
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
781static 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. */
782static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn) 811static __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