Message ID | 20210427093546.30703-8-michal.orzel@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Get rid of READ/WRITE_SYSREG32 | expand |
On 27/04/2021 10:35, Michal Orzel wrote: > AArch64 registers are 64bit whereas AArch32 registers > are 32bit or 64bit. MSR/MRS are expecting 64bit values thus > we should get rid of helpers READ/WRITE_SYSREG32 > in favour of using READ/WRITE_SYSREG. > We should also use register_t type when reading sysregs > which can correspond to uint64_t or uint32_t. > Even though many AArch64 registers have upper 32bit reserved > it does not mean that they can't be widen in the future. > > Modify SCTLR_EL2 accesses to use READ/WRITE_SYSREG. > > SCTLR_EL2 already has bits defined in the range [32:63]. > The ARM ARM defines them as unknown if implemented. This is a bit ambiguous. > By writing in head.S SCTLR_EL2_SET we are zeroing the upper > 32bit half which is correct but referring to this sysreg > as 32bit is a latent bug because the top 32bit was not used > by Xen. This seems to suggest the patch below will call SCTLR_EL2_SET whereas this is already existing code. > > Signed-off-by: Michal Orzel <michal.orzel@arm.com> > --- > Changes since v1: > -Update commit message with SCTLR_EL2 analysis > --- > xen/arch/arm/mm.c | 2 +- > xen/arch/arm/traps.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index 59f8a3f15f..0e07335291 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -613,7 +613,7 @@ void __init remove_early_mappings(void) > */ > static void xen_pt_enforce_wnx(void) > { > - WRITE_SYSREG32(READ_SYSREG32(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); > + WRITE_SYSREG(READ_SYSREG(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); > /* > * The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized > * before flushing the TLBs. > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > index c7acdb2087..e7384381cc 100644 > --- a/xen/arch/arm/traps.c > +++ b/xen/arch/arm/traps.c > @@ -915,7 +915,7 @@ static void _show_registers(const struct cpu_user_regs *regs, > printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2); > printk("\n"); > > - printk(" SCTLR_EL2: %08"PRIx32"\n", READ_SYSREG32(SCTLR_EL2)); > + printk(" SCTLR_EL2: %"PRIregister"\n", READ_SYSREG(SCTLR_EL2)); Your commit title suggests that you will modify mm.c but you are also modifying traps.c. So how about the following commit message: " xen/arm: Always access SCTLR_EL2 using {READ, WRITE}_SYSREG() The Armv8 specification describes the system register as a 64-bit value on AArch64 and 32-bit value on AArch32 (same as Armv7). Unfortunately, Xen is accessing the system registers using {READ, WRITE}_SYSREG32() which means the top 32-bit are clobbered. This is only a latent bug so far because Xen will not yet use the top 32-bit. There is also no change in behavior because arch/arm/arm64/head.S will initialize SCTLR_EL2 to a sane value with the top 32-bit zeroed. " Cheers,
Hi Julien, On 27.04.2021 11:59, Julien Grall wrote: > > > On 27/04/2021 10:35, Michal Orzel wrote: >> AArch64 registers are 64bit whereas AArch32 registers >> are 32bit or 64bit. MSR/MRS are expecting 64bit values thus >> we should get rid of helpers READ/WRITE_SYSREG32 >> in favour of using READ/WRITE_SYSREG. >> We should also use register_t type when reading sysregs >> which can correspond to uint64_t or uint32_t. >> Even though many AArch64 registers have upper 32bit reserved >> it does not mean that they can't be widen in the future. >> >> Modify SCTLR_EL2 accesses to use READ/WRITE_SYSREG. >> >> SCTLR_EL2 already has bits defined in the range [32:63]. >> The ARM ARM defines them as unknown if implemented. > > This is a bit ambiguous. > >> By writing in head.S SCTLR_EL2_SET we are zeroing the upper >> 32bit half which is correct but referring to this sysreg >> as 32bit is a latent bug because the top 32bit was not used >> by Xen. > > This seems to suggest the patch below will call SCTLR_EL2_SET whereas this is already existing code. > >> >> Signed-off-by: Michal Orzel <michal.orzel@arm.com> >> --- >> Changes since v1: >> -Update commit message with SCTLR_EL2 analysis >> --- >> xen/arch/arm/mm.c | 2 +- >> xen/arch/arm/traps.c | 2 +- >> 2 files changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c >> index 59f8a3f15f..0e07335291 100644 >> --- a/xen/arch/arm/mm.c >> +++ b/xen/arch/arm/mm.c >> @@ -613,7 +613,7 @@ void __init remove_early_mappings(void) >> */ >> static void xen_pt_enforce_wnx(void) >> { >> - WRITE_SYSREG32(READ_SYSREG32(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); >> + WRITE_SYSREG(READ_SYSREG(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); >> /* >> * The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized >> * before flushing the TLBs. >> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c >> index c7acdb2087..e7384381cc 100644 >> --- a/xen/arch/arm/traps.c >> +++ b/xen/arch/arm/traps.c >> @@ -915,7 +915,7 @@ static void _show_registers(const struct cpu_user_regs *regs, >> printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2); >> printk("\n"); >> - printk(" SCTLR_EL2: %08"PRIx32"\n", READ_SYSREG32(SCTLR_EL2)); >> + printk(" SCTLR_EL2: %"PRIregister"\n", READ_SYSREG(SCTLR_EL2)); > > Your commit title suggests that you will modify mm.c but you are also modifying traps.c. So how about the following commit message: > > " > xen/arm: Always access SCTLR_EL2 using {READ, WRITE}_SYSREG() > > The Armv8 specification describes the system register as a 64-bit value on AArch64 and 32-bit value on AArch32 (same as Armv7). > > Unfortunately, Xen is accessing the system registers using {READ, WRITE}_SYSREG32() which means the top 32-bit are clobbered. > > This is only a latent bug so far because Xen will not yet use the top 32-bit. > > There is also no change in behavior because arch/arm/arm64/head.S will initialize SCTLR_EL2 to a sane value with the top 32-bit zeroed. > " > Thank you. I will modify the commit msg according to what you suggested. > Cheers, >
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 59f8a3f15f..0e07335291 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -613,7 +613,7 @@ void __init remove_early_mappings(void) */ static void xen_pt_enforce_wnx(void) { - WRITE_SYSREG32(READ_SYSREG32(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); + WRITE_SYSREG(READ_SYSREG(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2); /* * The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized * before flushing the TLBs. diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index c7acdb2087..e7384381cc 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -915,7 +915,7 @@ static void _show_registers(const struct cpu_user_regs *regs, printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2); printk("\n"); - printk(" SCTLR_EL2: %08"PRIx32"\n", READ_SYSREG32(SCTLR_EL2)); + printk(" SCTLR_EL2: %"PRIregister"\n", READ_SYSREG(SCTLR_EL2)); printk(" HCR_EL2: %"PRIregister"\n", READ_SYSREG(HCR_EL2)); printk(" TTBR0_EL2: %016"PRIx64"\n", READ_SYSREG64(TTBR0_EL2)); printk("\n");
AArch64 registers are 64bit whereas AArch32 registers are 32bit or 64bit. MSR/MRS are expecting 64bit values thus we should get rid of helpers READ/WRITE_SYSREG32 in favour of using READ/WRITE_SYSREG. We should also use register_t type when reading sysregs which can correspond to uint64_t or uint32_t. Even though many AArch64 registers have upper 32bit reserved it does not mean that they can't be widen in the future. Modify SCTLR_EL2 accesses to use READ/WRITE_SYSREG. SCTLR_EL2 already has bits defined in the range [32:63]. The ARM ARM defines them as unknown if implemented. By writing in head.S SCTLR_EL2_SET we are zeroing the upper 32bit half which is correct but referring to this sysreg as 32bit is a latent bug because the top 32bit was not used by Xen. Signed-off-by: Michal Orzel <michal.orzel@arm.com> --- Changes since v1: -Update commit message with SCTLR_EL2 analysis --- xen/arch/arm/mm.c | 2 +- xen/arch/arm/traps.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)