|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 11/15] xen: arm: correctly handle sysreg accesses from userspace
Previously we implemented all registers as RAZ/WI even if they
shouldn't be accessible to userspace.
It is not entirely clear whether attempts to access *_EL1 registers
from EL0 will trap to EL1 or EL2, be conservative and treat as an
undef injection.
PMUSERENR_EL0 and MDCCSR_EL0 are R/O to EL0. MDCCSR_EL0 was previously
not handled at all.
Other PM*_EL0 registers are accessible at EL0 only if PMUSERENR_EL0.EN
is set, since we emulate that as RAZ/WI we know that bit cannot be
set.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Reviewed-by: Julien Grall <julien.grall@xxxxxxxxxx>
---
v4:
- Handle the possibility of EL1 trapping from EL0 as well, by
injecting an undef, since the docs are not completely unambiguous
about this possibility.
---
xen/arch/arm/traps.c | 55 +++++++++++++++++++++++++++++++----------
xen/include/asm-arm/sysregs.h | 1 +
2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 0c33191..2535512 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1806,9 +1806,42 @@ static void do_sysreg(struct cpu_user_regs *regs,
/* RAZ/WI registers: */
/* - Debug */
case HSR_SYSREG_MDSCR_EL1:
+ /* - Breakpoints */
+ HSR_SYSREG_DBG_CASES(DBGBVR):
+ HSR_SYSREG_DBG_CASES(DBGBCR):
+ /* - Watchpoints */
+ HSR_SYSREG_DBG_CASES(DBGWVR):
+ HSR_SYSREG_DBG_CASES(DBGWCR):
+ /* - Double Lock Register */
+ case HSR_SYSREG_OSDLR_EL1:
/* - Perf monitors */
case HSR_SYSREG_PMINTENSET_EL1:
case HSR_SYSREG_PMINTENCLR_EL1:
+ /*
+ * Accessible from EL1 only, but if EL0 trap happens handle as
+ * undef.
+ */
+ if ( psr_mode_is_user(regs) )
+ goto undef_sysreg;
+ goto sysreg_raz_wi;
+
+ case HSR_SYSREG_MDCCSR_EL0:
+ /*
+ * Accessible at EL0 only if MDSCR_EL1.TDCC is set to 0. We emulate
that
+ * register as RAZ/WI above. So RO at both EL0 and EL1.
+ */
+ if ( !hsr.sysreg.read )
+ goto undef_sysreg;
+
+ *x = 0;
+ break;
+
+ /* - Perf monitors */
+ case HSR_SYSREG_PMUSERENR_EL0:
+ /* RO at EL0. RAZ/WI at EL1 */
+ if ( psr_mode_is_user(regs) && !hsr.sysreg.read )
+ goto undef_sysreg;
+ goto sysreg_raz_wi;
case HSR_SYSREG_PMCR_EL0:
case HSR_SYSREG_PMCNTENSET_EL0:
case HSR_SYSREG_PMCNTENCLR_EL0:
@@ -1820,16 +1853,14 @@ static void do_sysreg(struct cpu_user_regs *regs,
case HSR_SYSREG_PMCCNTR_EL0:
case HSR_SYSREG_PMXEVTYPER_EL0:
case HSR_SYSREG_PMXEVCNTR_EL0:
- case HSR_SYSREG_PMUSERENR_EL0:
case HSR_SYSREG_PMOVSSET_EL0:
- /* - Breakpoints */
- HSR_SYSREG_DBG_CASES(DBGBVR):
- HSR_SYSREG_DBG_CASES(DBGBCR):
- /* - Watchpoints */
- HSR_SYSREG_DBG_CASES(DBGWVR):
- HSR_SYSREG_DBG_CASES(DBGWCR):
- /* - Double Lock Register */
- case HSR_SYSREG_OSDLR_EL1:
+ /*
+ * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We
+ * emulate that register as 0 above.
+ */
+ if ( psr_mode_is_user(regs) )
+ goto undef_sysreg;
+ sysreg_raz_wi:
if ( hsr.sysreg.read )
*x = 0;
/* else: write ignored */
@@ -1838,7 +1869,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
/* Write only, Write ignore registers: */
case HSR_SYSREG_OSLAR_EL1:
if ( hsr.sysreg.read )
- goto bad_sysreg;
+ goto undef_sysreg;
/* else: write ignored */
break;
case HSR_SYSREG_CNTP_CTL_EL0:
@@ -1862,7 +1893,6 @@ static void do_sysreg(struct cpu_user_regs *regs,
"Emulation of sysreg ICC_SGI0R_EL1/ASGI1R_EL1 not
supported\n");
inject_undef64_exception(regs, hsr.len);
default:
- bad_sysreg:
{
struct hsr_sysreg sysreg = hsr.sysreg;
@@ -2103,8 +2133,7 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs
*regs)
inject_undef64_exception(regs, hsr.len);
break;
case HSR_EC_SYSREG:
- if ( is_32bit_domain(current->domain) )
- goto bad_trap;
+ BUG_ON(psr_mode_is_32bit(regs->cpsr));
perfc_incr(trap_sysreg);
do_sysreg(regs, hsr);
break;
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
index 2e256cc..2284fd7 100644
--- a/xen/include/asm-arm/sysregs.h
+++ b/xen/include/asm-arm/sysregs.h
@@ -47,6 +47,7 @@
#define HSR_SYSREG_MDSCR_EL1 HSR_SYSREG(2,0,c0,c2,2)
#define HSR_SYSREG_OSLAR_EL1 HSR_SYSREG(2,0,c1,c0,4)
#define HSR_SYSREG_OSDLR_EL1 HSR_SYSREG(2,0,c1,c3,4)
+#define HSR_SYSREG_MDCCSR_EL0 HSR_SYSREG(2,3,c0,c1,0)
#define HSR_SYSREG_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4)
#define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5)
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |