---
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien.grall@xxxxxxx>
---
Changes in v2:
- Commit message fix (arm64 related change instead of arm)
- Add Stefano's reviewed-by
Changes in v3:
- Added Julien's acked-by
Changes in v5:
-Insted of zero the reading of OSLSR_EL1 should return set bit 3
-Implement new helper handle_ro_read_val() to support read only as a value.
handle_ro_read_val() reuses the implementation of handle_ro_raz() and
extends it with additional argument for passing the value to be returned
-Use handle_ro_read_val() for handle_ro_raz() implementation to avoid code
duplication
-Fix commit message to reflect changes made in this version
---
xen/arch/arm/arm64/vsysreg.c | 4 +++-
xen/arch/arm/traps.c | 26 ++++++++++++++++++--------
xen/include/asm-arm/traps.h | 4 ++++
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
index c57ac12503..6e60824572 100644
--- a/xen/arch/arm/arm64/vsysreg.c
+++ b/xen/arch/arm/arm64/vsysreg.c
@@ -57,13 +57,15 @@ void do_sysreg(struct cpu_user_regs *regs,
* ARMv8 (DDI 0487A.d): D1-1509 Table D1-58
*
* Unhandled:
- * OSLSR_EL1
* DBGPRCR_EL1
*/
case HSR_SYSREG_OSLAR_EL1:
return handle_wo_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
case HSR_SYSREG_OSDLR_EL1:
return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
+ case HSR_SYSREG_OSLSR_EL1:
+ return handle_ro_read_val(regs, regidx, hsr.sysreg.read, hsr, 1,
+ 1 << 3);
/*
* MDCR_EL2.TDA
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 5c18e918b0..d71adfa745 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1739,12 +1739,13 @@ void handle_wo_wi(struct cpu_user_regs *regs,
advance_pc(regs, hsr);
}
-/* Read only as read as zero */
-void handle_ro_raz(struct cpu_user_regs *regs,
- int regidx,
- bool read,
- const union hsr hsr,
- int min_el)
+/* Read only as value provided with 'val' argument of this function */
+void handle_ro_read_val(struct cpu_user_regs *regs,
+ int regidx,
+ bool read,
+ const union hsr hsr,
+ int min_el,
+ register_t val)
{
ASSERT((min_el == 0) || (min_el == 1));
@@ -1753,13 +1754,22 @@ void handle_ro_raz(struct cpu_user_regs *regs,
if ( !read )
return inject_undef_exception(regs, hsr);
- /* else: raz */
- set_user_reg(regs, regidx, 0);
+ set_user_reg(regs, regidx, val);
advance_pc(regs, hsr);
}
+/* Read only as read as zero */
+inline void handle_ro_raz(struct cpu_user_regs *regs,
+ int regidx,
+ bool read,
+ const union hsr hsr,
+ int min_el)
+{
+ handle_ro_read_val(regs, regidx, read, hsr, min_el, 0);
+}
+
void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
{
register_t ttbcr = READ_SYSREG(TCR_EL1);
diff --git a/xen/include/asm-arm/traps.h b/xen/include/asm-arm/traps.h
index a0e5e92ebb..70b52d1d16 100644
--- a/xen/include/asm-arm/traps.h
+++ b/xen/include/asm-arm/traps.h
@@ -27,6 +27,10 @@ void handle_wo_wi(struct cpu_user_regs *regs, int regidx,
bool read,
void handle_ro_raz(struct cpu_user_regs *regs, int regidx, bool read,
const union hsr hsr, int min_el);
+/* Read only as value provided with 'val' argument */
+void handle_ro_read_val(struct cpu_user_regs *regs, int regidx, bool read,
+ const union hsr hsr, int min_el, register_t val);
+
/* Co-processor registers emulation (see arch/arm/vcpreg.c). */
void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr);
void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr);