@@ -49,10 +49,10 @@ static inline uint32_t prio(uint32_t x)
49
49
#define APICBASE_BSP 0x00000100UL
50
50
#define APICBASE_X2APIC 0x00000400U
51
51
#define APICBASE_ENABLED 0x00000800UL
52
- #define LOGICAL_ID_MASK 0xFU
53
- #define CLUSTER_ID_MASK 0xFFFF0U
52
+ #define LOGICAL_ID_MASK 0xFU
53
+ #define CLUSTER_ID_MASK 0xFFFF0U
54
54
55
- #define ACRN_DBG_LAPIC 6U
55
+ #define ACRN_DBG_LAPIC 6U
56
56
57
57
#if VLAPIC_VERBOS
58
58
static inline void vlapic_dump_irr (struct acrn_vlapic * vlapic , char * msg )
@@ -1010,19 +1010,6 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
1010
1010
bitmap_set_lock (vcpu_id , dmask );
1011
1011
}
1012
1012
} else {
1013
- /*
1014
- * In the "Flat Model" the MDA is interpreted as an 8-bit wide
1015
- * bitmask. This model is only available in the xAPIC mode.
1016
- */
1017
- mda_flat_ldest = dest & 0xffU ;
1018
-
1019
- /*
1020
- * In the "Cluster Model" the MDA is used to identify a
1021
- * specific cluster and a set of APICs in that cluster.
1022
- */
1023
- mda_cluster_id = (dest >> 4U ) & 0xfU ;
1024
- mda_cluster_ldest = dest & 0xfU ;
1025
-
1026
1013
/*
1027
1014
* Logical mode: match each APIC that has a bit set
1028
1015
* in its LDR that matches a bit in the ldest.
@@ -1032,35 +1019,59 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
1032
1019
for (vcpu_id = 0U ; vcpu_id < vm -> hw .created_vcpus ; vcpu_id ++ ) {
1033
1020
if (amask & (1U << vcpu_id )) {
1034
1021
vlapic = vm_lapic_from_vcpu_id (vm , vcpu_id );
1035
- dfr = vlapic -> apic_page .dfr .v ;
1036
- ldr = vlapic -> apic_page .ldr .v ;
1037
-
1038
- if ((dfr & APIC_DFR_MODEL_MASK ) ==
1039
- APIC_DFR_MODEL_FLAT ) {
1040
- ldest = ldr >> 24U ;
1041
- mda_ldest = mda_flat_ldest ;
1042
- } else if ((dfr & APIC_DFR_MODEL_MASK ) ==
1043
- APIC_DFR_MODEL_CLUSTER ) {
1044
1022
1045
- cluster = ldr >> 28U ;
1046
- ldest = (ldr >> 24U ) & 0xfU ;
1023
+ if (is_x2apic_enabled (vlapic )){
1024
+ ldr = vlapic -> apic_page .ldr .v ;
1025
+ ldest = ldr & 0xFFFFU ;
1047
1026
1048
- if (cluster != mda_cluster_id ) {
1027
+ mda_cluster_id = (dest >> 16U ) & 0xFFFFU ;
1028
+ mda_ldest = dest & 0xFFFFU ;
1029
+ if (mda_cluster_id != ((ldr >> 16U ) & 0xFFFFU )) {
1049
1030
continue ;
1050
1031
}
1051
- mda_ldest = mda_cluster_ldest ;
1052
1032
} else {
1053
1033
/*
1054
- * Guest has configured a bad logical
1055
- * model for this vcpu - skip it .
1034
+ * In the "Flat Model" the MDA is interpreted as an 8-bit wide
1035
+ * bitmask. This model is only available in the xAPIC mode .
1056
1036
*/
1057
- dev_dbg (ACRN_DBG_LAPIC ,
1058
- "CANNOT deliver interrupt" );
1059
- dev_dbg (ACRN_DBG_LAPIC ,
1060
- "vlapic has bad logical model %x" , dfr );
1061
- continue ;
1062
- }
1037
+ mda_flat_ldest = dest & 0xffU ;
1038
+
1039
+ /*
1040
+ * In the "Cluster Model" the MDA is used to identify a
1041
+ * specific cluster and a set of APICs in that cluster.
1042
+ */
1043
+ mda_cluster_id = (dest >> 4U ) & 0xfU ;
1044
+ mda_cluster_ldest = dest & 0xfU ;
1045
+
1046
+ dfr = vlapic -> apic_page .dfr .v ;
1047
+ ldr = vlapic -> apic_page .ldr .v ;
1063
1048
1049
+ if ((dfr & APIC_DFR_MODEL_MASK ) ==
1050
+ APIC_DFR_MODEL_FLAT ) {
1051
+ ldest = ldr >> 24U ;
1052
+ mda_ldest = mda_flat_ldest ;
1053
+ } else if ((dfr & APIC_DFR_MODEL_MASK ) ==
1054
+ APIC_DFR_MODEL_CLUSTER ) {
1055
+
1056
+ cluster = ldr >> 28U ;
1057
+ ldest = (ldr >> 24U ) & 0xfU ;
1058
+
1059
+ if (cluster != mda_cluster_id ) {
1060
+ continue ;
1061
+ }
1062
+ mda_ldest = mda_cluster_ldest ;
1063
+ } else {
1064
+ /*
1065
+ * Guest has configured a bad logical
1066
+ * model for this vcpu - skip it.
1067
+ */
1068
+ dev_dbg (ACRN_DBG_LAPIC ,
1069
+ "CANNOT deliver interrupt" );
1070
+ dev_dbg (ACRN_DBG_LAPIC ,
1071
+ "vlapic has bad logical model %x" , dfr );
1072
+ continue ;
1073
+ }
1074
+ }
1064
1075
if ((mda_ldest & ldest ) != 0U ) {
1065
1076
if (lowprio ) {
1066
1077
if (target == NULL ) {
@@ -1152,7 +1163,11 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
1152
1163
1153
1164
icr_low = lapic -> icr_lo .v ;
1154
1165
icr_high = lapic -> icr_hi .v ;
1155
- dest = icr_high >> APIC_ID_SHIFT ;
1166
+ if (is_x2apic_enabled (vlapic )) {
1167
+ dest = icr_high ;
1168
+ } else {
1169
+ dest = icr_high >> APIC_ID_SHIFT ;
1170
+ }
1156
1171
vec = icr_low & APIC_VECTOR_MASK ;
1157
1172
mode = icr_low & APIC_DELMODE_MASK ;
1158
1173
phys = ((icr_low & APIC_DESTMODE_LOG ) == 0UL );
@@ -1542,7 +1557,12 @@ vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset,
1542
1557
vlapic_svr_write_handler (vlapic );
1543
1558
break ;
1544
1559
case APIC_OFFSET_ICR_LOW :
1545
- lapic -> icr_lo .v = data32 ;
1560
+ if (is_x2apic_enabled (vlapic )) {
1561
+ lapic -> icr_hi .v = (uint32_t )(data >> 32U );
1562
+ lapic -> icr_lo .v = data32 ;
1563
+ } else {
1564
+ lapic -> icr_lo .v = data32 ;
1565
+ }
1546
1566
retval = vlapic_icrlo_write_handler (vlapic );
1547
1567
break ;
1548
1568
case APIC_OFFSET_ICR_HI :
0 commit comments