@@ -252,10 +252,43 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
252
252
struct sys_reg_params * p ,
253
253
const struct sys_reg_desc * r )
254
254
{
255
+ bool g1 ;
256
+
255
257
if (!p -> is_write )
256
258
return read_from_write_only (vcpu , p , r );
257
259
258
- vgic_v3_dispatch_sgi (vcpu , p -> regval , true);
260
+ /*
261
+ * In a system where GICD_CTLR.DS=1, a ICC_SGI0R_EL1 access generates
262
+ * Group0 SGIs only, while ICC_SGI1R_EL1 can generate either group,
263
+ * depending on the SGI configuration. ICC_ASGI1R_EL1 is effectively
264
+ * equivalent to ICC_SGI0R_EL1, as there is no "alternative" secure
265
+ * group.
266
+ */
267
+ if (p -> is_aarch32 ) {
268
+ switch (p -> Op1 ) {
269
+ default : /* Keep GCC quiet */
270
+ case 0 : /* ICC_SGI1R */
271
+ g1 = true;
272
+ break ;
273
+ case 1 : /* ICC_ASGI1R */
274
+ case 2 : /* ICC_SGI0R */
275
+ g1 = false;
276
+ break ;
277
+ }
278
+ } else {
279
+ switch (p -> Op2 ) {
280
+ default : /* Keep GCC quiet */
281
+ case 5 : /* ICC_SGI1R_EL1 */
282
+ g1 = true;
283
+ break ;
284
+ case 6 : /* ICC_ASGI1R_EL1 */
285
+ case 7 : /* ICC_SGI0R_EL1 */
286
+ g1 = false;
287
+ break ;
288
+ }
289
+ }
290
+
291
+ vgic_v3_dispatch_sgi (vcpu , p -> regval , g1 );
259
292
260
293
return true;
261
294
}
@@ -1312,6 +1345,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1312
1345
{ SYS_DESC (SYS_ICC_DIR_EL1 ), read_from_write_only },
1313
1346
{ SYS_DESC (SYS_ICC_RPR_EL1 ), write_to_read_only },
1314
1347
{ SYS_DESC (SYS_ICC_SGI1R_EL1 ), access_gic_sgi },
1348
+ { SYS_DESC (SYS_ICC_ASGI1R_EL1 ), access_gic_sgi },
1349
+ { SYS_DESC (SYS_ICC_SGI0R_EL1 ), access_gic_sgi },
1315
1350
{ SYS_DESC (SYS_ICC_IAR1_EL1 ), write_to_read_only },
1316
1351
{ SYS_DESC (SYS_ICC_EOIR1_EL1 ), read_from_write_only },
1317
1352
{ SYS_DESC (SYS_ICC_HPPIR1_EL1 ), write_to_read_only },
@@ -1744,8 +1779,10 @@ static const struct sys_reg_desc cp15_regs[] = {
1744
1779
static const struct sys_reg_desc cp15_64_regs [] = {
1745
1780
{ Op1 ( 0 ), CRn ( 0 ), CRm ( 2 ), Op2 ( 0 ), access_vm_reg , NULL , c2_TTBR0 },
1746
1781
{ Op1 ( 0 ), CRn ( 0 ), CRm ( 9 ), Op2 ( 0 ), access_pmu_evcntr },
1747
- { Op1 ( 0 ), CRn ( 0 ), CRm (12 ), Op2 ( 0 ), access_gic_sgi },
1782
+ { Op1 ( 0 ), CRn ( 0 ), CRm (12 ), Op2 ( 0 ), access_gic_sgi }, /* ICC_SGI1R */
1748
1783
{ Op1 ( 1 ), CRn ( 0 ), CRm ( 2 ), Op2 ( 0 ), access_vm_reg , NULL , c2_TTBR1 },
1784
+ { Op1 ( 1 ), CRn ( 0 ), CRm (12 ), Op2 ( 0 ), access_gic_sgi }, /* ICC_ASGI1R */
1785
+ { Op1 ( 2 ), CRn ( 0 ), CRm (12 ), Op2 ( 0 ), access_gic_sgi }, /* ICC_SGI0R */
1749
1786
{ Op1 ( 2 ), CRn ( 0 ), CRm (14 ), Op2 ( 0 ), access_cntp_cval },
1750
1787
};
1751
1788
0 commit comments