@@ -25,6 +25,53 @@ static const uint32_t emulated_msrs[] = {
25
25
*/
26
26
};
27
27
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
+
28
75
static void enable_msr_interception (uint8_t * bitmap , uint32_t msr_arg )
29
76
{
30
77
uint8_t * read_map ;
@@ -51,6 +98,23 @@ static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg)
51
98
write_map [(msr >> 3U )] = value ;
52
99
}
53
100
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
+
54
118
void init_msr_emulation (struct vcpu * vcpu )
55
119
{
56
120
uint32_t i ;
@@ -93,6 +157,8 @@ void init_msr_emulation(struct vcpu *vcpu)
93
157
i <= MSR_IA32_VMX_TRUE_ENTRY_CTLS ; i ++ ) {
94
158
enable_msr_interception (msr_bitmap , i );
95
159
}
160
+
161
+ intercept_x2apic_msrs (msr_bitmap );
96
162
}
97
163
98
164
/* Set up MSR bitmap - pg 2904 24.6.9 */
@@ -189,14 +255,18 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu)
189
255
}
190
256
default :
191
257
{
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 ;
197
269
}
198
- vcpu_inject_gp (vcpu , 0U );
199
- v = 0UL ;
200
270
break ;
201
271
}
202
272
}
@@ -321,13 +391,17 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu)
321
391
}
322
392
default :
323
393
{
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 );
329
404
}
330
- vcpu_inject_gp (vcpu , 0U );
331
405
break ;
332
406
}
333
407
}
0 commit comments