@@ -2038,6 +2038,27 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
2038
2038
return ret ;
2039
2039
}
2040
2040
2041
+ static bool apicv_basic_x2apic_read_msr_may_valid (uint32_t offset )
2042
+ {
2043
+ return (offset != APIC_OFFSET_DFR ) && (offset != APIC_OFFSET_ICR_HI );
2044
+ }
2045
+
2046
+ static bool apicv_advanced_x2apic_read_msr_may_valid (uint32_t offset )
2047
+ {
2048
+ return (offset == APIC_OFFSET_TIMER_CCR );
2049
+ }
2050
+
2051
+ static bool apicv_basic_x2apic_write_msr_may_valid (uint32_t offset )
2052
+ {
2053
+ return (offset != APIC_OFFSET_DFR ) && (offset != APIC_OFFSET_ICR_HI );
2054
+ }
2055
+
2056
+ static bool apicv_advanced_x2apic_write_msr_may_valid (uint32_t offset )
2057
+ {
2058
+ return (offset != APIC_OFFSET_DFR ) && (offset != APIC_OFFSET_ICR_HI ) &&
2059
+ (offset != APIC_OFFSET_EOI ) && (offset != APIC_OFFSET_SELF_IPI );
2060
+ }
2061
+
2041
2062
int32_t vlapic_x2apic_read (struct acrn_vcpu * vcpu , uint32_t msr , uint64_t * val )
2042
2063
{
2043
2064
struct acrn_vlapic * vlapic ;
@@ -2062,8 +2083,8 @@ int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
2062
2083
break ;
2063
2084
}
2064
2085
} else {
2065
- if (! is_x2apic_write_only_msr ( msr )) {
2066
- offset = x2apic_msr_to_regoff ( msr );
2086
+ offset = x2apic_msr_to_regoff ( msr );
2087
+ if ( apicv_ops -> x2apic_read_msr_may_valid ( offset )) {
2067
2088
error = vlapic_read (vlapic , offset , val );
2068
2089
}
2069
2090
}
@@ -2094,8 +2115,8 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
2094
2115
break ;
2095
2116
}
2096
2117
} else {
2097
- if (! is_x2apic_read_only_msr ( msr )) {
2098
- offset = x2apic_msr_to_regoff ( msr );
2118
+ offset = x2apic_msr_to_regoff ( msr );
2119
+ if ( apicv_ops -> x2apic_write_msr_may_valid ( offset )) {
2099
2120
error = vlapic_write (vlapic , offset , val );
2100
2121
}
2101
2122
}
@@ -2315,6 +2336,26 @@ bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
2315
2336
return apicv_ops -> has_pending_delivery_intr (vcpu );
2316
2337
}
2317
2338
2339
+ static bool apicv_basic_apic_read_access_may_valid (__unused uint32_t offset )
2340
+ {
2341
+ return true;
2342
+ }
2343
+
2344
+ static bool apicv_advanced_apic_read_access_may_valid (uint32_t offset )
2345
+ {
2346
+ return ((offset == APIC_OFFSET_CMCI_LVT ) || (offset == APIC_OFFSET_TIMER_CCR ));
2347
+ }
2348
+
2349
+ static bool apicv_basic_apic_write_access_may_valid (uint32_t offset )
2350
+ {
2351
+ return (offset != APIC_OFFSET_SELF_IPI );
2352
+ }
2353
+
2354
+ static bool apicv_advanced_apic_write_access_may_valid (uint32_t offset )
2355
+ {
2356
+ return (offset == APIC_OFFSET_CMCI_LVT );
2357
+ }
2358
+
2318
2359
int32_t apic_access_vmexit_handler (struct acrn_vcpu * vcpu )
2319
2360
{
2320
2361
int32_t err = 0 ;
@@ -2340,10 +2381,16 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
2340
2381
if (err >= 0 ) {
2341
2382
if (access_type == 1UL ) {
2342
2383
if (emulate_instruction (vcpu ) == 0 ) {
2343
- (void )vlapic_write (vlapic , offset , mmio -> value );
2384
+ if (apicv_ops -> apic_write_access_may_valid (offset )) {
2385
+ (void )vlapic_write (vlapic , offset , mmio -> value );
2386
+ }
2344
2387
}
2345
2388
} else if (access_type == 0UL ) {
2346
- (void )vlapic_read (vlapic , offset , & mmio -> value );
2389
+ if (apicv_ops -> apic_read_access_may_valid (offset )) {
2390
+ (void )vlapic_read (vlapic , offset , & mmio -> value );
2391
+ } else {
2392
+ mmio -> value = 0ULL ;
2393
+ }
2347
2394
err = emulate_instruction (vcpu );
2348
2395
} else {
2349
2396
pr_err ("Unhandled APIC access type: %lu\n" , access_type );
@@ -2502,12 +2549,20 @@ static const struct acrn_apicv_ops apicv_basic_ops = {
2502
2549
.accept_intr = apicv_basic_accept_intr ,
2503
2550
.inject_intr = apicv_basic_inject_intr ,
2504
2551
.has_pending_delivery_intr = apicv_basic_has_pending_delivery_intr ,
2552
+ .apic_read_access_may_valid = apicv_basic_apic_read_access_may_valid ,
2553
+ .apic_write_access_may_valid = apicv_basic_apic_write_access_may_valid ,
2554
+ .x2apic_read_msr_may_valid = apicv_basic_x2apic_read_msr_may_valid ,
2555
+ .x2apic_write_msr_may_valid = apicv_basic_x2apic_write_msr_may_valid ,
2505
2556
};
2506
2557
2507
2558
static const struct acrn_apicv_ops apicv_advanced_ops = {
2508
2559
.accept_intr = apicv_advanced_accept_intr ,
2509
2560
.inject_intr = apicv_advanced_inject_intr ,
2510
2561
.has_pending_delivery_intr = apicv_advanced_has_pending_delivery_intr ,
2562
+ .apic_read_access_may_valid = apicv_advanced_apic_read_access_may_valid ,
2563
+ .apic_write_access_may_valid = apicv_advanced_apic_write_access_may_valid ,
2564
+ .x2apic_read_msr_may_valid = apicv_advanced_x2apic_read_msr_may_valid ,
2565
+ .x2apic_write_msr_may_valid = apicv_advanced_x2apic_write_msr_may_valid ,
2511
2566
};
2512
2567
2513
2568
/*
0 commit comments