Message ID | 1480959803-4206-1-git-send-email-julien.grall@arm.com |
---|---|
State | New |
Headers | show |
On Mon, 5 Dec 2016, Julien Grall wrote: > Recent Linux kernel (4.4 and onwards [1]) is checking whether it is possible > to enable sysreg access (ICC_SRE_EL1.SRE) when the ID register > (ID_AA64PRF0_EL1.GIC) is reporting the presence of the sysreg interface. > > When the guest has been configured to use GICv2, the hypervisor will > disable sysreg access for this vm (via ICC_SRE_EL2.Enable) and therefore > access to system register such as ICC_SRE_EL1 are trapped in EL2. > > However, ICC_SRE_EL1 is not emulated by the hypervisor. This means that > Linux will crash as soon as it is trying to access ICC_SRE_EL1. > > To solve this problem, Xen can implement ICC_SRE_EL1 as read-as-zero > write-ignore. The emulation will only be used when sysreg are disabled > for EL1. > > [1] 963fcd409 "arm64: cpufeatures: Check ICC_EL1_SRE.SRE before > enabling ARM64_HAS_SYSREG_GIC_CPUIF" > > Signed-off-by: Julien Grall <julien.grall@arm.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> And applied > --- > I think this patch would need to be backported as recent Linux (4.4 > and onwards) are trying to access ICC_EL1_SRE during boot time. > > The first support of GICv2 on GICv3 was in Xen 4.6. > --- > xen/arch/arm/traps.c | 14 ++++++++++++++ > xen/include/asm-arm/sysregs.h | 1 + > 2 files changed, 15 insertions(+) > > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > index 8ff73fe..ae921d7 100644 > --- a/xen/arch/arm/traps.c > +++ b/xen/arch/arm/traps.c > @@ -2280,6 +2280,20 @@ static void do_sysreg(struct cpu_user_regs *regs, > return inject_undef64_exception(regs, hsr.len); > > /* > + * ICC_SRE_EL2.Enable = 0 > + * > + * GIC Architecture Specification (IHI 0069C): Section 8.1.9 > + */ > + case HSR_SYSREG_ICC_SRE_EL1: > + /* > + * Trapped when the guest is using GICv2 whilst the platform > + * interrupt controller is GICv3. In this case, the register > + * should be emulate as RAZ/WI to tell the guest to use the GIC > + * memory mapped interface (i.e GICv2 compatibility). > + */ > + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1); > + > + /* > * HCR_EL2.TIDCP > * > * ARMv8 (DDI 0487A.d): D1-1501 Table D1-43 > diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h > index 570f43e..887368e 100644 > --- a/xen/include/asm-arm/sysregs.h > +++ b/xen/include/asm-arm/sysregs.h > @@ -90,6 +90,7 @@ > #define HSR_SYSREG_ICC_SGI1R_EL1 HSR_SYSREG(3,0,c12,c11,5) > #define HSR_SYSREG_ICC_ASGI1R_EL1 HSR_SYSREG(3,1,c12,c11,6) > #define HSR_SYSREG_ICC_SGI0R_EL1 HSR_SYSREG(3,2,c12,c11,7) > +#define HSR_SYSREG_ICC_SRE_EL1 HSR_SYSREG(3,0,c12,c12,5) > #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1) > > #define HSR_SYSREG_PMCR_EL0 HSR_SYSREG(3,3,c9,c12,0) > -- > 1.9.1 >
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 8ff73fe..ae921d7 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2280,6 +2280,20 @@ static void do_sysreg(struct cpu_user_regs *regs, return inject_undef64_exception(regs, hsr.len); /* + * ICC_SRE_EL2.Enable = 0 + * + * GIC Architecture Specification (IHI 0069C): Section 8.1.9 + */ + case HSR_SYSREG_ICC_SRE_EL1: + /* + * Trapped when the guest is using GICv2 whilst the platform + * interrupt controller is GICv3. In this case, the register + * should be emulate as RAZ/WI to tell the guest to use the GIC + * memory mapped interface (i.e GICv2 compatibility). + */ + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1); + + /* * HCR_EL2.TIDCP * * ARMv8 (DDI 0487A.d): D1-1501 Table D1-43 diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h index 570f43e..887368e 100644 --- a/xen/include/asm-arm/sysregs.h +++ b/xen/include/asm-arm/sysregs.h @@ -90,6 +90,7 @@ #define HSR_SYSREG_ICC_SGI1R_EL1 HSR_SYSREG(3,0,c12,c11,5) #define HSR_SYSREG_ICC_ASGI1R_EL1 HSR_SYSREG(3,1,c12,c11,6) #define HSR_SYSREG_ICC_SGI0R_EL1 HSR_SYSREG(3,2,c12,c11,7) +#define HSR_SYSREG_ICC_SRE_EL1 HSR_SYSREG(3,0,c12,c12,5) #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1) #define HSR_SYSREG_PMCR_EL0 HSR_SYSREG(3,3,c9,c12,0)
Recent Linux kernel (4.4 and onwards [1]) is checking whether it is possible to enable sysreg access (ICC_SRE_EL1.SRE) when the ID register (ID_AA64PRF0_EL1.GIC) is reporting the presence of the sysreg interface. When the guest has been configured to use GICv2, the hypervisor will disable sysreg access for this vm (via ICC_SRE_EL2.Enable) and therefore access to system register such as ICC_SRE_EL1 are trapped in EL2. However, ICC_SRE_EL1 is not emulated by the hypervisor. This means that Linux will crash as soon as it is trying to access ICC_SRE_EL1. To solve this problem, Xen can implement ICC_SRE_EL1 as read-as-zero write-ignore. The emulation will only be used when sysreg are disabled for EL1. [1] 963fcd409 "arm64: cpufeatures: Check ICC_EL1_SRE.SRE before enabling ARM64_HAS_SYSREG_GIC_CPUIF" Signed-off-by: Julien Grall <julien.grall@arm.com> --- I think this patch would need to be backported as recent Linux (4.4 and onwards) are trying to access ICC_EL1_SRE during boot time. The first support of GICv2 on GICv3 was in Xen 4.6. --- xen/arch/arm/traps.c | 14 ++++++++++++++ xen/include/asm-arm/sysregs.h | 1 + 2 files changed, 15 insertions(+)