mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
arm64: Change type of hsr, cpsr, spsr_el1 to uint64_t
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 type of hsr, cpsr, spsr_el1 to uint64_t. Previously we relied on the padding after spsr_el1. As we removed the padding, modify the union to be 64bit so we don't corrupt spsr_fiq. No need to modify the assembly code because the accesses were based on 64bit registers as there was a 32bit padding after spsr_el1. Remove 32bit padding in cpu_user_regs before spsr_fiq as it is no longer needed due to upper union being 64bit now. Add 64bit padding in cpu_user_regs before spsr_el1 because the kernel frame should be 16-byte aligned. Change type of cpsr to uint64_t in the public outside interface "public/arch-arm.h" to allow ABI compatibility between 32bit and 64bit. Increment XEN_DOMCTL_INTERFACE_VERSION. Change type of cpsr to uint64_t in the public outside interface "public/vm_event.h" to allow ABI compatibility between 32bit and 64bit. Signed-off-by: Michal Orzel <michal.orzel@arm.com> Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com> Reviewed-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
1 parent
4473f36010
commit
918b8842a8
11 files changed
+39
-35
No files matched your search
@@ -155,7 +155,7 @@
|
||||
add x21, sp, #UREGS_CPSR
|
||||
mrs x22, spsr_el2
|
||||
mrs x23, esr_el2
|
||||
stp w22, w23, [x21]
|
||||
stp x22, x23, [x21]
|
||||
|
||||
.endm
|
||||
|
||||
@@ -432,7 +432,7 @@ return_from_trap:
|
||||
msr daifset, #IFLAGS___I_ /* Mask interrupts */
|
||||
|
||||
ldr x21, [sp, #UREGS_PC] /* load ELR */
|
||||
ldr w22, [sp, #UREGS_CPSR] /* load SPSR */
|
||||
ldr x22, [sp, #UREGS_CPSR] /* load SPSR */
|
||||
|
||||
pop x0, x1
|
||||
pop x2, x3
|
||||
|
||||
@@ -36,7 +36,7 @@ void do_bad_mode(struct cpu_user_regs *regs, int reason)
|
||||
union hsr hsr = { .bits = regs->hsr };
|
||||
|
||||
printk("Bad mode in %s handler detected\n", handler[reason]);
|
||||
printk("ESR=0x%08"PRIx32": EC=%"PRIx32", IL=%"PRIx32", ISS=%"PRIx32"\n",
|
||||
printk("ESR=%#"PRIregister": EC=%"PRIx32", IL=%"PRIx32", ISS=%"PRIx32"\n",
|
||||
hsr.bits, hsr.ec, hsr.len, hsr.iss);
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
@@ -368,7 +368,8 @@ void do_sysreg(struct cpu_user_regs *regs,
|
||||
sysreg.op2,
|
||||
sysreg.read ? "=>" : "<=",
|
||||
sysreg.reg, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x\n",
|
||||
gdprintk(XENLOG_ERR,
|
||||
"unhandled 64-bit sysreg access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_SYSREG_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
return;
|
||||
|
||||
@@ -845,7 +845,7 @@ static int is_guest_pv32_psr(uint32_t psr)
|
||||
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
static int is_guest_pv64_psr(uint32_t psr)
|
||||
static int is_guest_pv64_psr(uint64_t psr)
|
||||
{
|
||||
if ( psr & PSR_MODE_BIT )
|
||||
return 0;
|
||||
|
||||
+15
-13
@@ -546,7 +546,7 @@ void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len)
|
||||
PSR_IRQ_MASK | PSR_DBG_MASK;
|
||||
regs->pc = handler;
|
||||
|
||||
WRITE_SYSREG32(esr.bits, ESR_EL1);
|
||||
WRITE_SYSREG(esr.bits, ESR_EL1);
|
||||
}
|
||||
|
||||
/* Inject an abort exception into a 64 bit guest */
|
||||
@@ -580,7 +580,7 @@ static void inject_abt64_exception(struct cpu_user_regs *regs,
|
||||
regs->pc = handler;
|
||||
|
||||
WRITE_SYSREG(addr, FAR_EL1);
|
||||
WRITE_SYSREG32(esr.bits, ESR_EL1);
|
||||
WRITE_SYSREG(esr.bits, ESR_EL1);
|
||||
}
|
||||
|
||||
static void inject_dabt64_exception(struct cpu_user_regs *regs,
|
||||
@@ -717,7 +717,7 @@ struct reg_ctxt {
|
||||
uint64_t vttbr_el2;
|
||||
};
|
||||
|
||||
static const char *mode_string(uint32_t cpsr)
|
||||
static const char *mode_string(register_t cpsr)
|
||||
{
|
||||
uint32_t mode;
|
||||
static const char *mode_strings[] = {
|
||||
@@ -762,7 +762,7 @@ static void show_registers_32(const struct cpu_user_regs *regs,
|
||||
printk(" %pS", _p(regs->pc));
|
||||
printk("\n");
|
||||
#endif
|
||||
printk("CPSR: %08"PRIx32" MODE:%s\n", regs->cpsr,
|
||||
printk("CPSR: %"PRIregister" MODE:%s\n", regs->cpsr,
|
||||
mode_string(regs->cpsr));
|
||||
printk(" R0: %08"PRIx32" R1: %08"PRIx32" R2: %08"PRIx32" R3: %08"PRIx32"\n",
|
||||
regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
@@ -846,7 +846,7 @@ static void show_registers_64(const struct cpu_user_regs *regs,
|
||||
{
|
||||
printk("SP: %016"PRIx64"\n", regs->sp);
|
||||
}
|
||||
printk("CPSR: %08"PRIx32" MODE:%s\n", regs->cpsr,
|
||||
printk("CPSR: %016"PRIx64" MODE:%s\n", regs->cpsr,
|
||||
mode_string(regs->cpsr));
|
||||
printk(" X0: %016"PRIx64" X1: %016"PRIx64" X2: %016"PRIx64"\n",
|
||||
regs->x0, regs->x1, regs->x2);
|
||||
@@ -919,7 +919,7 @@ static void _show_registers(const struct cpu_user_regs *regs,
|
||||
printk(" HCR_EL2: %"PRIregister"\n", READ_SYSREG(HCR_EL2));
|
||||
printk(" TTBR0_EL2: %016"PRIx64"\n", READ_SYSREG64(TTBR0_EL2));
|
||||
printk("\n");
|
||||
printk(" ESR_EL2: %08"PRIx32"\n", regs->hsr);
|
||||
printk(" ESR_EL2: %"PRIregister"\n", regs->hsr);
|
||||
printk(" HPFAR_EL2: %"PRIregister"\n", READ_SYSREG(HPFAR_EL2));
|
||||
|
||||
#ifdef CONFIG_ARM_32
|
||||
@@ -1599,7 +1599,7 @@ static const unsigned short cc_map[16] = {
|
||||
|
||||
int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
{
|
||||
unsigned long cpsr, cpsr_cond;
|
||||
register_t cpsr, cpsr_cond;
|
||||
int cond;
|
||||
|
||||
/*
|
||||
@@ -1661,7 +1661,7 @@ int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
|
||||
void advance_pc(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
{
|
||||
unsigned long itbits, cond, cpsr = regs->cpsr;
|
||||
register_t itbits, cond, cpsr = regs->cpsr;
|
||||
bool is_thumb = psr_mode_is_32bit(regs) && (cpsr & PSR_THUMB);
|
||||
|
||||
if ( is_thumb && (cpsr & PSR_IT_MASK) )
|
||||
@@ -2004,13 +2004,15 @@ static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs,
|
||||
|
||||
break;
|
||||
default:
|
||||
gprintk(XENLOG_WARNING, "Unsupported FSC: HSR=%#x DFSC=%#x\n",
|
||||
gprintk(XENLOG_WARNING,
|
||||
"Unsupported FSC: HSR=%#"PRIregister" DFSC=%#x\n",
|
||||
hsr.bits, xabt.fsc);
|
||||
}
|
||||
|
||||
inject_abt:
|
||||
gdprintk(XENLOG_DEBUG, "HSR=0x%x pc=%#"PRIregister" gva=%#"PRIvaddr
|
||||
" gpa=%#"PRIpaddr"\n", hsr.bits, regs->pc, gva, gpa);
|
||||
gdprintk(XENLOG_DEBUG,
|
||||
"HSR=%#"PRIregister" pc=%#"PRIregister" gva=%#"PRIvaddr" gpa=%#"PRIpaddr"\n",
|
||||
hsr.bits, regs->pc, gva, gpa);
|
||||
if ( is_data )
|
||||
inject_dabt_exception(regs, gva, hsr.len);
|
||||
else
|
||||
@@ -2204,7 +2206,7 @@ void do_trap_guest_sync(struct cpu_user_regs *regs)
|
||||
|
||||
default:
|
||||
gprintk(XENLOG_WARNING,
|
||||
"Unknown Guest Trap. HSR=0x%x EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
|
||||
"Unknown Guest Trap. HSR=%#"PRIregister" EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
|
||||
hsr.bits, hsr.ec, hsr.len, hsr.iss);
|
||||
inject_undef_exception(regs, hsr);
|
||||
}
|
||||
@@ -2242,7 +2244,7 @@ void do_trap_hyp_sync(struct cpu_user_regs *regs)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printk("Hypervisor Trap. HSR=0x%x EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
|
||||
printk("Hypervisor Trap. HSR=%#"PRIregister" EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
|
||||
hsr.bits, hsr.ec, hsr.len, hsr.iss);
|
||||
do_unexpected_trap("Hypervisor", regs);
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
|
||||
cp32.read ? "mrc" : "mcr",
|
||||
cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#x\n",
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP32_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
return;
|
||||
@@ -454,7 +454,8 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
|
||||
cp64.read ? "mrrc" : "mcrr",
|
||||
cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit CP15 access %#x\n",
|
||||
gdprintk(XENLOG_ERR,
|
||||
"unhandled 64-bit CP15 access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP64_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
return;
|
||||
@@ -585,7 +586,7 @@ void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p14, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
|
||||
cp32.read ? "mrc" : "mcr",
|
||||
cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit cp14 access %#x\n",
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit cp14 access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP32_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
return;
|
||||
@@ -627,7 +628,7 @@ void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p14, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
|
||||
cp64.read ? "mrrc" : "mcrr",
|
||||
cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 access %#x\n",
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP64_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
}
|
||||
@@ -658,7 +659,7 @@ void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p14, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
|
||||
cp64.read ? "mrrc" : "mcrr",
|
||||
cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 DBG access %#x\n",
|
||||
gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 DBG access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP64_REGS_MASK);
|
||||
|
||||
inject_undef_exception(regs, hsr);
|
||||
@@ -692,7 +693,7 @@ void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
|
||||
"%s p10, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
|
||||
cp32.read ? "mrc" : "mcr",
|
||||
cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit CP10 access %#x\n",
|
||||
gdprintk(XENLOG_ERR, "unhandled 32-bit CP10 access %#"PRIregister"\n",
|
||||
hsr.bits & HSR_CP32_REGS_MASK);
|
||||
inject_undef_exception(regs, hsr);
|
||||
return;
|
||||
|
||||
@@ -63,18 +63,19 @@ struct cpu_user_regs
|
||||
|
||||
/* Return address and mode */
|
||||
__DECL_REG(pc, pc32); /* ELR_EL2 */
|
||||
uint32_t cpsr; /* SPSR_EL2 */
|
||||
uint32_t hsr; /* ESR_EL2 */
|
||||
uint64_t cpsr; /* SPSR_EL2 */
|
||||
uint64_t hsr; /* ESR_EL2 */
|
||||
|
||||
/* The kernel frame should be 16-byte aligned. */
|
||||
uint64_t pad0;
|
||||
|
||||
/* Outer guest frame only from here on... */
|
||||
|
||||
union {
|
||||
uint32_t spsr_el1; /* AArch64 */
|
||||
uint64_t spsr_el1; /* AArch64 */
|
||||
uint32_t spsr_svc; /* AArch32 */
|
||||
};
|
||||
|
||||
uint32_t pad1; /* Doubleword-align the user half of the frame */
|
||||
|
||||
/* AArch32 guests only */
|
||||
uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ enum dabt_size {
|
||||
};
|
||||
|
||||
union hsr {
|
||||
uint32_t bits;
|
||||
register_t bits;
|
||||
struct {
|
||||
unsigned long iss:25; /* Instruction Specific Syndrome */
|
||||
unsigned long len:1; /* Instruction length */
|
||||
|
||||
@@ -267,10 +267,10 @@ struct vcpu_guest_core_regs
|
||||
|
||||
/* Return address and mode */
|
||||
__DECL_REG(pc64, pc32); /* ELR_EL2 */
|
||||
uint32_t cpsr; /* SPSR_EL2 */
|
||||
uint64_t cpsr; /* SPSR_EL2 */
|
||||
|
||||
union {
|
||||
uint32_t spsr_el1; /* AArch64 */
|
||||
uint64_t spsr_el1; /* AArch64 */
|
||||
uint32_t spsr_svc; /* AArch32 */
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "hvm/save.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define XEN_DOMCTL_INTERFACE_VERSION 0x00000013
|
||||
#define XEN_DOMCTL_INTERFACE_VERSION 0x00000014
|
||||
|
||||
/*
|
||||
* NB. xen_domctl.domain is an IN/OUT parameter for this operation.
|
||||
|
||||
@@ -266,8 +266,7 @@ struct vm_event_regs_arm {
|
||||
uint64_t ttbr1;
|
||||
uint64_t ttbcr;
|
||||
uint64_t pc;
|
||||
uint32_t cpsr;
|
||||
uint32_t _pad;
|
||||
uint64_t cpsr;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||