Skip to content

Commit a1886b9

Browse files
committed
xen/pv: refactor msr access functions to support safe and unsafe accesses
Refactor and rename xen_read_msr_safe() and xen_write_msr_safe() to support both cases of MSR accesses, safe ones and potentially GP-fault generating ones. This will prepare to no longer swallow GPs silently in xen_read_msr() and xen_write_msr(). Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Jan Beulich <[email protected]> Signed-off-by: Juergen Gross <[email protected]>
1 parent f90d98b commit a1886b9

File tree

1 file changed

+56
-19
lines changed

1 file changed

+56
-19
lines changed

arch/x86/xen/enlighten_pv.c

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -916,14 +916,18 @@ static void xen_write_cr4(unsigned long cr4)
916916
native_write_cr4(cr4);
917917
}
918918

919-
static u64 xen_read_msr_safe(unsigned int msr, int *err)
919+
static u64 xen_do_read_msr(unsigned int msr, int *err)
920920
{
921-
u64 val;
921+
u64 val = 0; /* Avoid uninitialized value for safe variant. */
922922

923923
if (pmu_msr_read(msr, &val, err))
924924
return val;
925925

926-
val = native_read_msr_safe(msr, err);
926+
if (err)
927+
val = native_read_msr_safe(msr, err);
928+
else
929+
val = native_read_msr(msr);
930+
927931
switch (msr) {
928932
case MSR_IA32_APICBASE:
929933
val &= ~X2APIC_ENABLE;
@@ -932,23 +936,39 @@ static u64 xen_read_msr_safe(unsigned int msr, int *err)
932936
return val;
933937
}
934938

935-
static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
939+
static void set_seg(unsigned int which, unsigned int low, unsigned int high,
940+
int *err)
936941
{
937-
int ret;
938-
unsigned int which;
939-
u64 base;
942+
u64 base = ((u64)high << 32) | low;
943+
944+
if (HYPERVISOR_set_segment_base(which, base) == 0)
945+
return;
940946

941-
ret = 0;
947+
if (err)
948+
*err = -EIO;
949+
else
950+
WARN(1, "Xen set_segment_base(%u, %llx) failed\n", which, base);
951+
}
942952

953+
/*
954+
* Support write_msr_safe() and write_msr() semantics.
955+
* With err == NULL write_msr() semantics are selected.
956+
* Supplying an err pointer requires err to be pre-initialized with 0.
957+
*/
958+
static void xen_do_write_msr(unsigned int msr, unsigned int low,
959+
unsigned int high, int *err)
960+
{
943961
switch (msr) {
944-
case MSR_FS_BASE: which = SEGBASE_FS; goto set;
945-
case MSR_KERNEL_GS_BASE: which = SEGBASE_GS_USER; goto set;
946-
case MSR_GS_BASE: which = SEGBASE_GS_KERNEL; goto set;
947-
948-
set:
949-
base = ((u64)high << 32) | low;
950-
if (HYPERVISOR_set_segment_base(which, base) != 0)
951-
ret = -EIO;
962+
case MSR_FS_BASE:
963+
set_seg(SEGBASE_FS, low, high, err);
964+
break;
965+
966+
case MSR_KERNEL_GS_BASE:
967+
set_seg(SEGBASE_GS_USER, low, high, err);
968+
break;
969+
970+
case MSR_GS_BASE:
971+
set_seg(SEGBASE_GS_KERNEL, low, high, err);
952972
break;
953973

954974
case MSR_STAR:
@@ -964,11 +984,28 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
964984
break;
965985

966986
default:
967-
if (!pmu_msr_write(msr, low, high, &ret))
968-
ret = native_write_msr_safe(msr, low, high);
987+
if (!pmu_msr_write(msr, low, high, err)) {
988+
if (err)
989+
*err = native_write_msr_safe(msr, low, high);
990+
else
991+
native_write_msr(msr, low, high);
992+
}
969993
}
994+
}
995+
996+
static u64 xen_read_msr_safe(unsigned int msr, int *err)
997+
{
998+
return xen_do_read_msr(msr, err);
999+
}
1000+
1001+
static int xen_write_msr_safe(unsigned int msr, unsigned int low,
1002+
unsigned int high)
1003+
{
1004+
int err = 0;
1005+
1006+
xen_do_write_msr(msr, low, high, &err);
9701007

971-
return ret;
1008+
return err;
9721009
}
9731010

9741011
static u64 xen_read_msr(unsigned int msr)

0 commit comments

Comments
 (0)