Marc convinced me that there will be no unreasonable breakage to user space for neither 32-bit or arm64 so we go back to this api to please reviewers and potentially make shared instruction decoding easier to implement. QEMU has been updated to work with this API and can be found here: git@xxxxxxxxxx:virtualopensystems/linux-kvm-arm.git kvm-arm Signed-off-by: Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> --- arch/arm/include/asm/kvm_emulate.h | 8 ++++---- arch/arm/include/uapi/asm/kvm.h | 5 ++--- arch/arm/kernel/asm-offsets.c | 4 ++-- arch/arm/kvm/emulate.c | 4 +--- arch/arm/kvm/guest.c | 2 +- arch/arm/kvm/reset.c | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index b94863a..375795b 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -36,23 +36,23 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); static inline u32 *vcpu_pc(struct kvm_vcpu *vcpu) { - return &vcpu->arch.regs.pc; + return (u32 *)&vcpu->arch.regs.usr_regs.ARM_pc; } static inline u32 *vcpu_cpsr(struct kvm_vcpu *vcpu) { - return &vcpu->arch.regs.cpsr; + return (u32 *)&vcpu->arch.regs.usr_regs.ARM_cpsr; } static inline bool mode_has_spsr(struct kvm_vcpu *vcpu) { - unsigned long cpsr_mode = vcpu->arch.regs.cpsr & MODE_MASK; + unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK; return (cpsr_mode > USR_MODE && cpsr_mode < SYSTEM_MODE); } static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu) { - unsigned long cpsr_mode = vcpu->arch.regs.cpsr & MODE_MASK; + unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK; return cpsr_mode > USR_MODE;; } diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index a7ae073..b1c7871 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -20,6 +20,7 @@ #define __ARM_KVM_H__ #include <asm/types.h> +#include <asm/ptrace.h> #define __KVM_HAVE_GUEST_DEBUG #define __KVM_HAVE_IRQ_LINE @@ -28,14 +29,12 @@ (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) struct kvm_regs { - __u32 usr_regs[15]; /* R0_usr - R14_usr */ + struct pt_regs usr_regs;/* R0_usr - R14_usr, PC, CPSR */ __u32 svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */ __u32 abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */ __u32 und_regs[3]; /* SP_und, LR_und, SPSR_und */ __u32 irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */ __u32 fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */ - __u32 pc; /* The program counter (r15) */ - __u32 cpsr; /* The guest CPSR */ }; /* Supported Processor Types */ diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 813d386..50df318 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -160,8 +160,8 @@ int main(void) DEFINE(VCPU_UND_REGS, offsetof(struct kvm_vcpu, arch.regs.und_regs)); DEFINE(VCPU_IRQ_REGS, offsetof(struct kvm_vcpu, arch.regs.irq_regs)); DEFINE(VCPU_FIQ_REGS, offsetof(struct kvm_vcpu, arch.regs.fiq_regs)); - DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.regs.pc)); - DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu, arch.regs.cpsr)); + DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_pc)); + DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_cpsr)); DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); DEFINE(VCPU_HSR, offsetof(struct kvm_vcpu, arch.hsr)); DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.hxfar)); diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index 30124cb..ca72be9 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -28,7 +28,7 @@ #define REG_OFFSET(_reg) \ (offsetof(struct kvm_regs, _reg) / sizeof(u32)) -#define USR_REG_OFFSET(_num) REG_OFFSET(usr_regs[_num]) +#define USR_REG_OFFSET(_num) REG_OFFSET(usr_regs.uregs[_num]) static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][15] = { /* USR/SYS Registers */ @@ -108,8 +108,6 @@ u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num) u32 *reg_array = (u32 *)&vcpu->arch.regs; u32 mode = *vcpu_cpsr(vcpu) & MODE_MASK; - BUG_ON(reg_num >= 15); - switch (mode) { case USR_MODE...SVC_MODE: mode &= ~MODE32_BIT; /* 0 ... 3 */ diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index de05c557c..65ae563 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c @@ -79,7 +79,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) if (get_user(val, uaddr) != 0) return -EFAULT; - if (off == KVM_REG_ARM_CORE_REG(cpsr)) { + if (off == KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr)) { unsigned long mode = val & MODE_MASK; switch (mode) { case USR_MODE: diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index bb17def..67ca4a3 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -34,7 +34,7 @@ static const int a15_max_cpu_idx = 3; static struct kvm_regs a15_regs_reset = { - .cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, + .usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, }; #ifdef CONFIG_KVM_ARM_TIMER _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm