hw/intc/arm_gicv3: Fix APxR<n> register dispatching
There was a nasty flip in identifying which register group an access is targeting. The issue caused spuriously raised priorities of the guest when handing CPUs over in the Jailhouse hypervisor. Cc: qemu-stable@nongnu.org Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									0d4a7551d9
								
							
						
					
					
						commit
						887aae10f6
					
				@ -427,7 +427,7 @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
					    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
 | 
				
			||||||
    uint64_t value = cs->ich_apr[grp][regno];
 | 
					    uint64_t value = cs->ich_apr[grp][regno];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
					    trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
				
			||||||
@ -439,7 +439,7 @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
					    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
					    trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1461,7 +1461,7 @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 | 
				
			|||||||
    uint64_t value;
 | 
					    uint64_t value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
 | 
					    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
 | 
				
			||||||
        return icv_ap_read(env, ri);
 | 
					        return icv_ap_read(env, ri);
 | 
				
			||||||
@ -1483,7 +1483,7 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
					    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
 | 
					    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
 | 
				
			||||||
        icv_ap_write(env, ri, value);
 | 
					        icv_ap_write(env, ri, value);
 | 
				
			||||||
@ -2292,7 +2292,7 @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
					    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
 | 
				
			||||||
    uint64_t value;
 | 
					    uint64_t value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    value = cs->ich_apr[grp][regno];
 | 
					    value = cs->ich_apr[grp][regno];
 | 
				
			||||||
@ -2305,7 +2305,7 @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
					    GICv3CPUState *cs = icc_cs_from_env(env);
 | 
				
			||||||
    int regno = ri->opc2 & 3;
 | 
					    int regno = ri->opc2 & 3;
 | 
				
			||||||
    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
 | 
					    int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
					    trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user