Skip to content

Commit 64f6196

Browse files
Sainath Grandhilijinxia
authored andcommitted
hv: add missing support to intercept x2APIC MSRs
Accessing x2APIC MSRs in xAPIC mode should result in GP exception according to SDM section 10.12.2. Adding support to ACRN to inject GP into guests for the same reason. Tracked-On: #1626 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Reviewed-by: Xu Anthony <anthony.xu@intel.com>
1 parent 94dadc1 commit 64f6196

File tree

3 files changed

+139
-17
lines changed

3 files changed

+139
-17
lines changed

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,32 @@ static void vlapic_timer_expired(void *data)
19361936
}
19371937
}
19381938

1939+
static inline bool is_x2apic_enabled(const struct acrn_vlapic *vlapic)
1940+
{
1941+
if ((vlapic_get_apicbase(vlapic) & APICBASE_X2APIC) == 0UL) {
1942+
return false;
1943+
} else {
1944+
return true;
1945+
}
1946+
}
1947+
1948+
static int vlapic_x2apic_access(struct vcpu *vcpu)
1949+
{
1950+
struct acrn_vlapic *vlapic;
1951+
int error = 0;
1952+
1953+
vlapic = vcpu_vlapic(vcpu);
1954+
if (is_x2apic_enabled(vlapic) == false) {
1955+
/*
1956+
* If vLAPIC is in xAPIC mode and guest tries to access x2APIC MSRs
1957+
* inject a GP to guest
1958+
*/
1959+
error = -1;
1960+
}
1961+
1962+
return error;
1963+
}
1964+
19391965
int
19401966
vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval)
19411967
{
@@ -1955,8 +1981,13 @@ vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval)
19551981
break;
19561982

19571983
default:
1958-
dev_dbg(ACRN_DBG_LAPIC,
1959-
"Invalid vlapic msr 0x%x access\n", msr);
1984+
if (is_x2apic_msr(msr)) {
1985+
error = vlapic_x2apic_access(vcpu);
1986+
} else {
1987+
error = -1;
1988+
dev_dbg(ACRN_DBG_LAPIC,
1989+
"Invalid vlapic msr 0x%x access\n", msr);
1990+
}
19601991
break;
19611992
}
19621993

@@ -1981,8 +2012,13 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t wval)
19812012
break;
19822013

19832014
default:
1984-
dev_dbg(ACRN_DBG_LAPIC,
1985-
"Invalid vlapic msr 0x%x access\n", msr);
2015+
if (is_x2apic_msr(msr)) {
2016+
error = vlapic_x2apic_access(vcpu);
2017+
} else {
2018+
error = -1;
2019+
dev_dbg(ACRN_DBG_LAPIC,
2020+
"Invalid vlapic msr 0x%x access\n", msr);
2021+
}
19862022
break;
19872023
}
19882024

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,53 @@ static const uint32_t emulated_msrs[] = {
2525
*/
2626
};
2727

28+
static const uint32_t x2apic_msrs[] = {
29+
MSR_IA32_EXT_XAPICID,
30+
MSR_IA32_EXT_APIC_VERSION,
31+
MSR_IA32_EXT_APIC_TPR,
32+
MSR_IA32_EXT_APIC_PPR,
33+
MSR_IA32_EXT_APIC_EOI,
34+
MSR_IA32_EXT_APIC_LDR,
35+
MSR_IA32_EXT_APIC_SIVR,
36+
MSR_IA32_EXT_APIC_ISR0,
37+
MSR_IA32_EXT_APIC_ISR1,
38+
MSR_IA32_EXT_APIC_ISR2,
39+
MSR_IA32_EXT_APIC_ISR3,
40+
MSR_IA32_EXT_APIC_ISR4,
41+
MSR_IA32_EXT_APIC_ISR5,
42+
MSR_IA32_EXT_APIC_ISR6,
43+
MSR_IA32_EXT_APIC_ISR7,
44+
MSR_IA32_EXT_APIC_TMR0,
45+
MSR_IA32_EXT_APIC_TMR1,
46+
MSR_IA32_EXT_APIC_TMR2,
47+
MSR_IA32_EXT_APIC_TMR3,
48+
MSR_IA32_EXT_APIC_TMR4,
49+
MSR_IA32_EXT_APIC_TMR5,
50+
MSR_IA32_EXT_APIC_TMR6,
51+
MSR_IA32_EXT_APIC_TMR7,
52+
MSR_IA32_EXT_APIC_IRR0,
53+
MSR_IA32_EXT_APIC_IRR1,
54+
MSR_IA32_EXT_APIC_IRR2,
55+
MSR_IA32_EXT_APIC_IRR3,
56+
MSR_IA32_EXT_APIC_IRR4,
57+
MSR_IA32_EXT_APIC_IRR5,
58+
MSR_IA32_EXT_APIC_IRR6,
59+
MSR_IA32_EXT_APIC_IRR7,
60+
MSR_IA32_EXT_APIC_ESR,
61+
MSR_IA32_EXT_APIC_LVT_CMCI,
62+
MSR_IA32_EXT_APIC_ICR,
63+
MSR_IA32_EXT_APIC_LVT_TIMER,
64+
MSR_IA32_EXT_APIC_LVT_THERMAL,
65+
MSR_IA32_EXT_APIC_LVT_PMI,
66+
MSR_IA32_EXT_APIC_LVT_LINT0,
67+
MSR_IA32_EXT_APIC_LVT_LINT1,
68+
MSR_IA32_EXT_APIC_LVT_ERROR,
69+
MSR_IA32_EXT_APIC_INIT_COUNT,
70+
MSR_IA32_EXT_APIC_CUR_COUNT,
71+
MSR_IA32_EXT_APIC_DIV_CONF,
72+
MSR_IA32_EXT_APIC_SELF_IPI,
73+
};
74+
2875
static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg)
2976
{
3077
uint8_t *read_map;
@@ -51,6 +98,23 @@ static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg)
5198
write_map[(msr >> 3U)] = value;
5299
}
53100

101+
/*
102+
* Enable read and write msr interception for x2APIC MSRs
103+
* MSRs that are not supported in the x2APIC range of MSRs,
104+
* i.e. anything other than the ones below and between
105+
* 0x802 and 0x83F, are not intercepted
106+
*/
107+
108+
static void intercept_x2apic_msrs(uint8_t *msr_bitmap_arg)
109+
{
110+
uint8_t *msr_bitmap = msr_bitmap_arg;
111+
uint32_t i;
112+
113+
for (i = 0U; i < ARRAY_SIZE(x2apic_msrs); i++) {
114+
enable_msr_interception(msr_bitmap, x2apic_msrs[i]);
115+
}
116+
}
117+
54118
void init_msr_emulation(struct vcpu *vcpu)
55119
{
56120
uint32_t i;
@@ -93,6 +157,8 @@ void init_msr_emulation(struct vcpu *vcpu)
93157
i <= MSR_IA32_VMX_TRUE_ENTRY_CTLS; i++) {
94158
enable_msr_interception(msr_bitmap, i);
95159
}
160+
161+
intercept_x2apic_msrs(msr_bitmap);
96162
}
97163

98164
/* Set up MSR bitmap - pg 2904 24.6.9 */
@@ -189,14 +255,18 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu)
189255
}
190256
default:
191257
{
192-
if (!(((msr >= MSR_IA32_MTRR_PHYSBASE_0) &&
193-
(msr <= MSR_IA32_MTRR_PHYSMASK_9)) ||
194-
((msr >= MSR_IA32_VMX_BASIC) &&
195-
(msr <= MSR_IA32_VMX_TRUE_ENTRY_CTLS)))) {
196-
pr_warn("rdmsr: %lx should not come here!", msr);
258+
if (is_x2apic_msr(msr)) {
259+
err = vlapic_rdmsr(vcpu, msr, &v);
260+
} else {
261+
if (!(((msr >= MSR_IA32_MTRR_PHYSBASE_0) &&
262+
(msr <= MSR_IA32_MTRR_PHYSMASK_9)) ||
263+
((msr >= MSR_IA32_VMX_BASIC) &&
264+
(msr <= MSR_IA32_VMX_TRUE_ENTRY_CTLS)))) {
265+
pr_warn("rdmsr: %lx should not come here!", msr);
266+
}
267+
vcpu_inject_gp(vcpu, 0U);
268+
v = 0UL;
197269
}
198-
vcpu_inject_gp(vcpu, 0U);
199-
v = 0UL;
200270
break;
201271
}
202272
}
@@ -321,13 +391,17 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu)
321391
}
322392
default:
323393
{
324-
if (!(((msr >= MSR_IA32_MTRR_PHYSBASE_0) &&
325-
(msr <= MSR_IA32_MTRR_PHYSMASK_9)) ||
326-
((msr >= MSR_IA32_VMX_BASIC) &&
327-
(msr <= MSR_IA32_VMX_TRUE_ENTRY_CTLS)))) {
328-
pr_warn("rdmsr: %lx should not come here!", msr);
394+
if (is_x2apic_msr(msr)) {
395+
err = vlapic_wrmsr(vcpu, msr, v);
396+
} else {
397+
if (!(((msr >= MSR_IA32_MTRR_PHYSBASE_0) &&
398+
(msr <= MSR_IA32_MTRR_PHYSMASK_9)) ||
399+
((msr >= MSR_IA32_VMX_BASIC) &&
400+
(msr <= MSR_IA32_VMX_TRUE_ENTRY_CTLS)))) {
401+
pr_warn("wrmsr: %lx should not come here!", msr);
402+
}
403+
vcpu_inject_gp(vcpu, 0U);
329404
}
330-
vcpu_inject_gp(vcpu, 0U);
331405
break;
332406
}
333407
}

hypervisor/include/arch/x86/msr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,18 @@ static inline bool pat_mem_type_invalid(uint64_t x)
529529
(x != PAT_MEM_TYPE_WT) && (x != PAT_MEM_TYPE_WP) &&
530530
(x != PAT_MEM_TYPE_WB) && (x != PAT_MEM_TYPE_UCM));
531531
}
532+
533+
static inline bool is_x2apic_msr(uint32_t msr)
534+
{
535+
bool ret = false;
536+
/*
537+
* if msr is in the range of x2APIC MSRs
538+
*/
539+
if ((msr >= MSR_IA32_EXT_XAPICID) && (msr <= MSR_IA32_EXT_APIC_SELF_IPI)) {
540+
ret = true;
541+
}
542+
return ret;
543+
}
532544
#endif /* ASSEMBLER */
533545

534546
/* 5 high-order bits in every field are reserved */

0 commit comments

Comments
 (0)