mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch kvm-arm64/s390-7.4 into kvmarm-master/next
* kvm-arm64/s390-7.4: : \ : Add the first attempt at sharing code with s390 in an effort to support : the arm64-on-s390 effort. This relies on ARM64_S390_COMMON markers in : relevant places. Patches courtesy of Steffen Eiden. : / KVM: arm64: Share arm64 code with s390 arm64: Share arm64 headers with s390 arm64: Prepare sharing arm64 headers with s390 KVM: arm64: Use accessor functions for core regs KVM: arm64: Access elements of vcpu_gp_regs individually arm64: sysreg: Convert SPSR_ELx to automatic register generation arm64: ptrace: Use constants for compat register numbers Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
commit
1d800989ce
|
|
@ -45,6 +45,9 @@ KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \
|
|||
KBUILD_CFLAGS += $(call cc-disable-warning, psabi)
|
||||
KBUILD_AFLAGS += $(compat_vdso)
|
||||
|
||||
# Enable all code shared to s390
|
||||
KBUILD_CPPFLAGS += -DARM64_S390_COMMON=1
|
||||
|
||||
ifeq ($(call rustc-min-version, 108500),y)
|
||||
KBUILD_RUSTFLAGS += --target=aarch64-unknown-none-softfloat
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*/
|
||||
/* Whole file is shared with s390 */
|
||||
|
||||
#ifndef __ASM_BRK_IMM_H
|
||||
#define __ASM_BRK_IMM_H
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
* Copyright (C) 2013 - ARM Ltd
|
||||
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
||||
*/
|
||||
/* Whole file is shared with s390 */
|
||||
|
||||
#ifndef __ASM_ESR_H
|
||||
#define __ASM_ESR_H
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/brk-imm.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
#define ESR_ELx_EC_UNKNOWN UL(0x00)
|
||||
|
|
@ -435,7 +436,7 @@
|
|||
#define ESR_ELx_IT_GCSPOPX 7
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <asm/types.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
static __always_inline bool esr_trap_is_iabt(unsigned long esr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@
|
|||
* Copyright (C) 2012,2013 - ARM Ltd
|
||||
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
||||
*/
|
||||
/* Whole file is shared with s390 */
|
||||
|
||||
#ifndef __ARM64_KVM_ARM_H__
|
||||
#define __ARM64_KVM_ARM_H__
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/esr.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
/*
|
||||
* Because I'm terribly lazy and that repainting the whole of the KVM
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ enum exception_type {
|
|||
bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
|
||||
void kvm_skip_instr32(struct kvm_vcpu *vcpu);
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
void kvm_inject_undefined(struct kvm_vcpu *vcpu);
|
||||
void kvm_inject_sync(struct kvm_vcpu *vcpu, u64 esr);
|
||||
int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr);
|
||||
|
|
@ -75,6 +76,8 @@ static inline int kvm_inject_serror(struct kvm_vcpu *vcpu)
|
|||
|
||||
void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
|
||||
int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
|
||||
int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
|
||||
|
|
@ -133,12 +136,37 @@ static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
|
|||
|
||||
static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (unsigned long *)&vcpu_gp_regs(vcpu)->pc;
|
||||
return (unsigned long *)&vcpu->arch.ctxt.regs.pc;
|
||||
}
|
||||
|
||||
static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (unsigned long *)&vcpu_gp_regs(vcpu)->pstate;
|
||||
return (unsigned long *)&vcpu->arch.ctxt.regs.pstate;
|
||||
}
|
||||
|
||||
static __always_inline unsigned long *vcpu_sp_el0(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (unsigned long *)&vcpu->arch.ctxt.regs.sp;
|
||||
}
|
||||
|
||||
static __always_inline u64 *vcpu_sp_el1(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return __ctxt_sys_reg(&vcpu->arch.ctxt, SP_EL1);
|
||||
}
|
||||
|
||||
static __always_inline __u128 *vcpu_vreg(struct kvm_vcpu *vcpu, int n)
|
||||
{
|
||||
return &vcpu->arch.ctxt.fp_regs.vregs[n];
|
||||
}
|
||||
|
||||
static __always_inline __u32 *vcpu_fpsr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return &vcpu->arch.ctxt.fp_regs.fpsr;
|
||||
}
|
||||
|
||||
static __always_inline __u32 *vcpu_fpcr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return &vcpu->arch.ctxt.fp_regs.fpcr;
|
||||
}
|
||||
|
||||
static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
|
||||
|
|
@ -159,6 +187,7 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
|
|||
*vcpu_cpsr(vcpu) |= PSR_AA32_T_BIT;
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
/*
|
||||
* vcpu_get_reg and vcpu_set_reg should always be passed a register number
|
||||
* coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
|
||||
|
|
@ -167,16 +196,18 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
|
|||
static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
|
||||
u8 reg_num)
|
||||
{
|
||||
return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs[reg_num];
|
||||
return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)[reg_num];
|
||||
}
|
||||
|
||||
static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
|
||||
unsigned long val)
|
||||
{
|
||||
if (reg_num != 31)
|
||||
vcpu_gp_regs(vcpu)->regs[reg_num] = val;
|
||||
vcpu_gp_regs(vcpu)[reg_num] = val;
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
static inline bool vcpu_is_el2_ctxt(const struct kvm_cpu_context *ctxt)
|
||||
{
|
||||
switch (ctxt->regs.pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
|
||||
|
|
@ -336,16 +367,6 @@ static __always_inline u64 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu)
|
|||
return vcpu->arch.fault.esr_el2;
|
||||
}
|
||||
|
||||
static __always_inline bool esr_abt_is_s1ptw(unsigned long esr)
|
||||
{
|
||||
return esr & ESR_ELx_S1PTW;
|
||||
}
|
||||
|
||||
static __always_inline bool esr_abt_is_exec_fault(unsigned long esr)
|
||||
{
|
||||
return esr_trap_is_iabt(esr) && !esr_abt_is_s1ptw(esr);
|
||||
}
|
||||
|
||||
static inline bool guest_hyp_wfx_traps_enabled(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 esr = kvm_vcpu_get_esr(vcpu);
|
||||
|
|
@ -389,6 +410,12 @@ static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
|
|||
return vcpu->arch.fault.disr_el1;
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static __always_inline bool esr_abt_is_s1ptw(unsigned long esr)
|
||||
{
|
||||
return esr & ESR_ELx_S1PTW;
|
||||
}
|
||||
|
||||
static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_vcpu_get_esr(vcpu) & ESR_ELx_xVC_IMM_MASK;
|
||||
|
|
@ -456,6 +483,13 @@ static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
|
|||
return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC;
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
static __always_inline bool esr_abt_is_exec_fault(unsigned long esr)
|
||||
{
|
||||
return esr_trap_is_iabt(esr) && !esr_abt_is_s1ptw(esr);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool kvm_vcpu_trap_is_permission_fault(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
|
@ -479,6 +513,7 @@ static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
|
|||
return ESR_ELx_SYS64_ISS_RT(esr);
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static inline bool esr_abt_is_write_fault(unsigned long esr)
|
||||
{
|
||||
if (esr_abt_is_s1ptw(esr)) {
|
||||
|
|
@ -508,6 +543,8 @@ static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
|
|||
return esr_abt_is_write_fault(kvm_vcpu_get_esr(vcpu));
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return __vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
|
||||
|
|
@ -549,6 +586,7 @@ static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
|
|||
return vcpu_read_sys_reg(vcpu, r) & bit;
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
|
||||
unsigned long data,
|
||||
unsigned int len)
|
||||
|
|
@ -624,6 +662,8 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
|
|||
vcpu_set_flag((v), e); \
|
||||
} while (0)
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
/*
|
||||
* Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
|
||||
* format if E2H isn't set.
|
||||
|
|
@ -725,6 +765,12 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void kvm_reset_fpsimd(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
/* Reset a vcpu's core registers. */
|
||||
static inline void kvm_reset_vcpu_core(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
|
@ -738,15 +784,19 @@ static inline void kvm_reset_vcpu_core(struct kvm_vcpu *vcpu)
|
|||
pstate = VCPU_RESET_PSTATE_EL1;
|
||||
|
||||
/* Reset core registers */
|
||||
memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));
|
||||
memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
|
||||
memset(vcpu_gp_regs(vcpu), 0, sizeof(vcpu_gp_regs(vcpu)));
|
||||
*vcpu_pc(vcpu) = 0;
|
||||
*vcpu_sp_el0(vcpu) = 0;
|
||||
kvm_reset_fpsimd(vcpu);
|
||||
vcpu->arch.ctxt.spsr_abt = 0;
|
||||
vcpu->arch.ctxt.spsr_und = 0;
|
||||
vcpu->arch.ctxt.spsr_irq = 0;
|
||||
vcpu->arch.ctxt.spsr_fiq = 0;
|
||||
vcpu_gp_regs(vcpu)->pstate = pstate;
|
||||
*vcpu_cpsr(vcpu) = pstate;
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
/* PSCI reset handling for a vcpu. */
|
||||
static inline void kvm_reset_vcpu_psci(struct kvm_vcpu *vcpu,
|
||||
struct vcpu_reset_state *reset_state)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
#define KVM_VCPU_MAX_FEATURES 10
|
||||
#define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
|
||||
|
||||
|
|
@ -59,6 +60,50 @@
|
|||
#define KVM_REQ_VGIC_PROCESS_UPDATE KVM_ARCH_REQ(11)
|
||||
#define KVM_REQ_RELOAD_GICv5 KVM_ARCH_REQ(12)
|
||||
|
||||
/* Bit indices for kvm_arch::flags */
|
||||
enum {
|
||||
/*
|
||||
* If we encounter a data abort without valid instruction syndrome
|
||||
* information, report this to user space. User space can (and
|
||||
* should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
|
||||
* supported.
|
||||
*/
|
||||
KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
|
||||
/* Memory Tagging Extension enabled for the guest */
|
||||
KVM_ARCH_FLAG_MTE_ENABLED,
|
||||
/* At least one vCPU has ran in the VM */
|
||||
KVM_ARCH_FLAG_HAS_RAN_ONCE,
|
||||
/* The vCPU feature set for the VM is configured */
|
||||
KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED,
|
||||
/* PSCI SYSTEM_SUSPEND enabled for the guest */
|
||||
KVM_ARCH_FLAG_SYSTEM_SUSPEND_ENABLED,
|
||||
/* VM counter offset */
|
||||
KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
|
||||
/* Timer PPIs made immutable */
|
||||
KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE,
|
||||
/* Initial ID reg values loaded */
|
||||
KVM_ARCH_FLAG_ID_REGS_INITIALIZED,
|
||||
/* Fine-Grained UNDEF initialised */
|
||||
KVM_ARCH_FLAG_FGU_INITIALIZED,
|
||||
/* SVE exposed to guest */
|
||||
KVM_ARCH_FLAG_GUEST_HAS_SVE,
|
||||
/* MIDR_EL1, REVIDR_EL1, and AIDR_EL1 are writable from userspace */
|
||||
KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS,
|
||||
/* Unhandled SEAs are taken to userspace */
|
||||
KVM_ARCH_FLAG_EXIT_SEA,
|
||||
/* No further ID register changes possible */
|
||||
KVM_ARCH_FLAG_ID_REGS_FINAL,
|
||||
};
|
||||
|
||||
struct vcpu_reset_state {
|
||||
unsigned long pc;
|
||||
unsigned long r0;
|
||||
bool be;
|
||||
bool reset;
|
||||
};
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
|
||||
KVM_DIRTY_LOG_INITIALLY_SET)
|
||||
|
||||
|
|
@ -357,37 +402,6 @@ struct kvm_arch {
|
|||
/* Protects VM-scoped configuration data */
|
||||
struct mutex config_lock;
|
||||
|
||||
/*
|
||||
* If we encounter a data abort without valid instruction syndrome
|
||||
* information, report this to user space. User space can (and
|
||||
* should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
|
||||
* supported.
|
||||
*/
|
||||
#define KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER 0
|
||||
/* Memory Tagging Extension enabled for the guest */
|
||||
#define KVM_ARCH_FLAG_MTE_ENABLED 1
|
||||
/* At least one vCPU has ran in the VM */
|
||||
#define KVM_ARCH_FLAG_HAS_RAN_ONCE 2
|
||||
/* The vCPU feature set for the VM is configured */
|
||||
#define KVM_ARCH_FLAG_VCPU_FEATURES_CONFIGURED 3
|
||||
/* PSCI SYSTEM_SUSPEND enabled for the guest */
|
||||
#define KVM_ARCH_FLAG_SYSTEM_SUSPEND_ENABLED 4
|
||||
/* VM counter offset */
|
||||
#define KVM_ARCH_FLAG_VM_COUNTER_OFFSET 5
|
||||
/* Timer PPIs made immutable */
|
||||
#define KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE 6
|
||||
/* Initial ID reg values loaded */
|
||||
#define KVM_ARCH_FLAG_ID_REGS_INITIALIZED 7
|
||||
/* Fine-Grained UNDEF initialised */
|
||||
#define KVM_ARCH_FLAG_FGU_INITIALIZED 8
|
||||
/* SVE exposed to guest */
|
||||
#define KVM_ARCH_FLAG_GUEST_HAS_SVE 9
|
||||
/* MIDR_EL1, REVIDR_EL1, and AIDR_EL1 are writable from userspace */
|
||||
#define KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS 10
|
||||
/* Unhandled SEAs are taken to userspace */
|
||||
#define KVM_ARCH_FLAG_EXIT_SEA 11
|
||||
/* No further ID register changes possible */
|
||||
#define KVM_ARCH_FLAG_ID_REGS_FINAL 12
|
||||
unsigned long flags;
|
||||
|
||||
/* VM-wide vCPU feature set */
|
||||
|
|
@ -856,13 +870,6 @@ extern s64 kvm_nvhe_sym(hyp_physvirt_offset);
|
|||
extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS];
|
||||
#define hyp_cpu_logical_map CHOOSE_NVHE_SYM(hyp_cpu_logical_map)
|
||||
|
||||
struct vcpu_reset_state {
|
||||
unsigned long pc;
|
||||
unsigned long r0;
|
||||
bool be;
|
||||
bool reset;
|
||||
};
|
||||
|
||||
struct vncr_tlb;
|
||||
|
||||
struct kvm_vcpu_arch {
|
||||
|
|
@ -972,6 +979,7 @@ struct kvm_vcpu_arch {
|
|||
pid_t pid;
|
||||
};
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
/*
|
||||
* Each 'flag' is composed of a comma-separated triplet:
|
||||
*
|
||||
|
|
@ -1067,6 +1075,11 @@ struct kvm_vcpu_arch {
|
|||
/* pKVM VCPU setup completed */
|
||||
#define VCPU_PKVM_FINALIZED __vcpu_single_flag(cflags, BIT(2))
|
||||
|
||||
int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
|
||||
bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
|
||||
|
||||
#define kvm_arm_vcpu_sve_finalized(vcpu) vcpu_get_flag(vcpu, VCPU_SVE_FINALIZED)
|
||||
|
||||
/* Exception pending */
|
||||
#define PENDING_EXCEPTION __vcpu_single_flag(iflags, BIT(0))
|
||||
/*
|
||||
|
|
@ -1125,6 +1138,8 @@ struct kvm_vcpu_arch {
|
|||
/* KVM is currently emulating an L2 to L1 exception */
|
||||
#define IN_NESTED_EXCEPTION __vcpu_single_flag(sflags, BIT(9))
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#define vcpu_sve_max_vq(vcpu) sve_vq_from_vl((vcpu)->arch.sve_max_vl)
|
||||
|
||||
#define vcpu_sve_zcr_elx(vcpu) \
|
||||
|
|
@ -1182,7 +1197,7 @@ struct kvm_vcpu_arch {
|
|||
#define vcpu_clear_on_unsupported_cpu(vcpu) \
|
||||
vcpu_clear_flag(vcpu, ON_UNSUPPORTED_CPU)
|
||||
|
||||
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.regs)
|
||||
#define vcpu_gp_regs(v) ((v)->arch.ctxt.regs.regs)
|
||||
|
||||
/*
|
||||
* Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
|
||||
|
|
@ -1263,14 +1278,6 @@ struct kvm_vcpu_stat {
|
|||
u64 exits;
|
||||
};
|
||||
|
||||
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
|
||||
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
|
||||
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
|
||||
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
|
||||
|
||||
unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu);
|
||||
int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
|
||||
|
||||
int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
|
||||
struct kvm_vcpu_events *events);
|
||||
|
||||
|
|
@ -1304,6 +1311,15 @@ int __init populate_nv_trap_config(void);
|
|||
|
||||
void kvm_calculate_traps(struct kvm_vcpu *vcpu);
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
|
||||
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
|
||||
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
|
||||
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
|
||||
|
||||
unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu);
|
||||
int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
|
||||
|
||||
/* MMIO helpers */
|
||||
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
|
||||
unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
|
||||
|
|
@ -1311,6 +1327,8 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
|
|||
int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
|
||||
int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
/*
|
||||
* Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
|
||||
* arrived in guest context. For arm64, any event that arrives while a vCPU is
|
||||
|
|
@ -1487,11 +1505,6 @@ struct kvm *kvm_arch_alloc_vm(void);
|
|||
|
||||
#define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm)
|
||||
|
||||
int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
|
||||
bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
|
||||
|
||||
#define kvm_arm_vcpu_sve_finalized(vcpu) vcpu_get_flag(vcpu, VCPU_SVE_FINALIZED)
|
||||
|
||||
#define kvm_has_mte(kvm) \
|
||||
(system_supports_mte() && \
|
||||
test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags))
|
||||
|
|
@ -1508,11 +1521,15 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
|
|||
return test_bit(feature, ka->vcpu_features);
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
|
||||
#define kvm_vcpu_has_feature(k, f) __vcpu_has_feature(&(k)->arch, (f))
|
||||
#define vcpu_has_feature(v, f) __vcpu_has_feature(&(v)->kvm->arch, (f))
|
||||
|
||||
#define kvm_vcpu_initialized(v) vcpu_get_flag(v, VCPU_INITIALIZED)
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
int kvm_trng_call(struct kvm_vcpu *vcpu);
|
||||
#ifdef CONFIG_KVM
|
||||
extern phys_addr_t hyp_mem_base;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#define GIC_PRIO_PSR_I_SET GICV3_PRIO_PSR_I_SET
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
|
||||
/* Additional SPSR bits not exposed in the UABI */
|
||||
#define PSR_MODE_THREAD_BIT (1 << 0)
|
||||
#define PSR_IL_BIT (1 << 20)
|
||||
|
|
@ -66,6 +68,8 @@
|
|||
#define PSR_AA32_IT_MASK 0x0600fc00 /* If-Then execution state mask */
|
||||
#define PSR_AA32_GE_MASK 0x000f0000
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define PSR_AA32_ENDSTATE PSR_AA32_E_BIT
|
||||
#else
|
||||
|
|
@ -102,26 +106,48 @@
|
|||
#define COMPAT_USER_SZ 296
|
||||
|
||||
/* Architecturally defined mapping between AArch32 and AArch64 registers */
|
||||
enum {
|
||||
__compat_fp = 11,
|
||||
__compat_sp = 13,
|
||||
__compat_lr = 14,
|
||||
__compat_sp_hyp = 15,
|
||||
__compat_lr_irq = 16,
|
||||
__compat_sp_irq = 17,
|
||||
__compat_lr_svc = 18,
|
||||
__compat_sp_svc = 19,
|
||||
__compat_lr_abt = 20,
|
||||
__compat_sp_abt = 21,
|
||||
__compat_lr_und = 22,
|
||||
__compat_sp_und = 23,
|
||||
__compat_r8_fiq = 24,
|
||||
__compat_r9_fiq = 25,
|
||||
__compat_r10_fiq = 26,
|
||||
__compat_r11_fiq = 27,
|
||||
__compat_r12_fiq = 28,
|
||||
__compat_sp_fiq = 29,
|
||||
__compat_lr_fiq = 30,
|
||||
};
|
||||
|
||||
#define compat_usr(x) regs[(x)]
|
||||
#define compat_fp regs[11]
|
||||
#define compat_sp regs[13]
|
||||
#define compat_lr regs[14]
|
||||
#define compat_sp_hyp regs[15]
|
||||
#define compat_lr_irq regs[16]
|
||||
#define compat_sp_irq regs[17]
|
||||
#define compat_lr_svc regs[18]
|
||||
#define compat_sp_svc regs[19]
|
||||
#define compat_lr_abt regs[20]
|
||||
#define compat_sp_abt regs[21]
|
||||
#define compat_lr_und regs[22]
|
||||
#define compat_sp_und regs[23]
|
||||
#define compat_r8_fiq regs[24]
|
||||
#define compat_r9_fiq regs[25]
|
||||
#define compat_r10_fiq regs[26]
|
||||
#define compat_r11_fiq regs[27]
|
||||
#define compat_r12_fiq regs[28]
|
||||
#define compat_sp_fiq regs[29]
|
||||
#define compat_lr_fiq regs[30]
|
||||
#define compat_fp regs[__compat_fp]
|
||||
#define compat_sp regs[__compat_sp]
|
||||
#define compat_lr regs[__compat_lr]
|
||||
#define compat_sp_hyp regs[__compat_sp_hyp]
|
||||
#define compat_lr_irq regs[__compat_lr_irq]
|
||||
#define compat_sp_irq regs[__compat_sp_irq]
|
||||
#define compat_lr_svc regs[__compat_lr_svc]
|
||||
#define compat_sp_svc regs[__compat_sp_svc]
|
||||
#define compat_lr_abt regs[__compat_lr_abt]
|
||||
#define compat_sp_abt regs[__compat_sp_abt]
|
||||
#define compat_lr_und regs[__compat_lr_und]
|
||||
#define compat_sp_und regs[__compat_sp_und]
|
||||
#define compat_r8_fiq regs[__compat_r8_fiq]
|
||||
#define compat_r9_fiq regs[__compat_r9_fiq]
|
||||
#define compat_r10_fiq regs[__compat_r10_fiq]
|
||||
#define compat_r11_fiq regs[__compat_r11_fiq]
|
||||
#define compat_r12_fiq regs[__compat_r12_fiq]
|
||||
#define compat_sp_fiq regs[__compat_sp_fiq]
|
||||
#define compat_lr_fiq regs[__compat_lr_fiq]
|
||||
|
||||
static inline unsigned long compat_psr_to_pstate(const unsigned long psr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <asm/gpr-num.h>
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
|
||||
/*
|
||||
* ARMv8 ARM reserves the following encoding for system registers:
|
||||
* (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
|
||||
|
|
@ -50,6 +52,8 @@
|
|||
#define sys_reg_CRm(id) (((id) >> CRm_shift) & CRm_mask)
|
||||
#define sys_reg_Op2(id) (((id) >> Op2_shift) & Op2_mask)
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#ifndef CONFIG_BROKEN_GAS_INST
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
|
|
@ -123,6 +127,8 @@
|
|||
#define GSB_SYS_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 0, 31)
|
||||
#define GSB_ACK_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 1, 31)
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
|
||||
/* Data cache zero operations */
|
||||
#define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2)
|
||||
#define SYS_DC_IGSW sys_insn(1, 0, 7, 6, 4)
|
||||
|
|
@ -295,7 +301,6 @@
|
|||
#define SYS_APGAKEYLO_EL1 sys_reg(3, 0, 2, 3, 0)
|
||||
#define SYS_APGAKEYHI_EL1 sys_reg(3, 0, 2, 3, 1)
|
||||
|
||||
#define SYS_SPSR_EL1 sys_reg(3, 0, 4, 0, 0)
|
||||
#define SYS_ELR_EL1 sys_reg(3, 0, 4, 0, 1)
|
||||
|
||||
#define SYS_ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0)
|
||||
|
|
@ -518,7 +523,6 @@
|
|||
#define SYS_VTTBR_EL2 sys_reg(3, 4, 2, 1, 0)
|
||||
|
||||
#define SYS_HAFGRTR_EL2 sys_reg(3, 4, 3, 1, 6)
|
||||
#define SYS_SPSR_EL2 sys_reg(3, 4, 4, 0, 0)
|
||||
#define SYS_ELR_EL2 sys_reg(3, 4, 4, 0, 1)
|
||||
#define SYS_SP_EL1 sys_reg(3, 4, 4, 1, 0)
|
||||
#define SYS_SPSR_irq sys_reg(3, 4, 4, 3, 0)
|
||||
|
|
@ -604,7 +608,6 @@
|
|||
#define SYS_BRBCR_EL12 sys_reg(2, 5, 9, 0, 0)
|
||||
#define SYS_TTBR0_EL12 sys_reg(3, 5, 2, 0, 0)
|
||||
#define SYS_TTBR1_EL12 sys_reg(3, 5, 2, 0, 1)
|
||||
#define SYS_SPSR_EL12 sys_reg(3, 5, 4, 0, 0)
|
||||
#define SYS_ELR_EL12 sys_reg(3, 5, 4, 0, 1)
|
||||
#define SYS_AFSR0_EL12 sys_reg(3, 5, 5, 1, 0)
|
||||
#define SYS_AFSR1_EL12 sys_reg(3, 5, 5, 1, 1)
|
||||
|
|
@ -835,6 +838,8 @@
|
|||
#define SCTLR_ELx_A (BIT(1))
|
||||
#define SCTLR_ELx_M (BIT(0))
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define ENDIAN_SET_EL2 SCTLR_ELx_EE
|
||||
#else
|
||||
|
|
@ -869,6 +874,7 @@
|
|||
SCTLR_EL1_LSMAOE | SCTLR_EL1_nTLSMD | SCTLR_EL1_EIS | \
|
||||
SCTLR_EL1_TSCXT | SCTLR_EL1_EOS)
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
/* MAIR_ELx memory attributes (used by Linux) */
|
||||
#define MAIR_ATTR_DEVICE_nGnRnE UL(0x00)
|
||||
#define MAIR_ATTR_DEVICE_nGnRE UL(0x04)
|
||||
|
|
@ -1116,6 +1122,8 @@
|
|||
#define GICV5_GIC_VDPEND_TYPE_MASK GENMASK_ULL(31, 29)
|
||||
#define GICV5_GIC_VDPEND_ID_MASK GENMASK_ULL(23, 0)
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#define gicr_insn(insn) read_sysreg_s(GICV5_OP_GICR_##insn)
|
||||
#define gic_insn(v, insn) write_sysreg_s(v, GICV5_OP_GIC_##insn)
|
||||
|
||||
|
|
@ -1265,6 +1273,8 @@
|
|||
par; \
|
||||
})
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
|
||||
#define SYS_FIELD_VALUE(reg, field, val) reg##_##field##_##val
|
||||
|
||||
#define SYS_FIELD_GET(reg, field, val) \
|
||||
|
|
@ -1277,6 +1287,8 @@
|
|||
FIELD_PREP(reg##_##field##_MASK, \
|
||||
SYS_FIELD_VALUE(reg, field, val))
|
||||
|
||||
#endif
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* __ASM_SYSREG_H */
|
||||
|
|
|
|||
|
|
@ -1616,6 +1616,7 @@ static unsigned long system_supported_vcpu_features(void)
|
|||
return features;
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_vcpu_init *init)
|
||||
{
|
||||
|
|
@ -1669,6 +1670,8 @@ static bool kvm_vcpu_init_changed(struct kvm_vcpu *vcpu,
|
|||
KVM_VCPU_MAX_FEATURES);
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
static int kvm_setup_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ const struct kvm_stats_header kvm_vcpu_stats_header = {
|
|||
sizeof(kvm_vcpu_stats_desc),
|
||||
};
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static bool core_reg_offset_is_vreg(u64 off)
|
||||
{
|
||||
return off >= KVM_REG_ARM_CORE_REG(fp_regs.vregs) &&
|
||||
|
|
@ -134,19 +135,19 @@ static void *core_reg_addr(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
|||
KVM_REG_ARM_CORE_REG(regs.regs[30]):
|
||||
off -= KVM_REG_ARM_CORE_REG(regs.regs[0]);
|
||||
off /= 2;
|
||||
return &vcpu->arch.ctxt.regs.regs[off];
|
||||
return &vcpu_gp_regs(vcpu)[off];
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(regs.sp):
|
||||
return &vcpu->arch.ctxt.regs.sp;
|
||||
return vcpu_sp_el0(vcpu);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(regs.pc):
|
||||
return &vcpu->arch.ctxt.regs.pc;
|
||||
return vcpu_pc(vcpu);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(regs.pstate):
|
||||
return &vcpu->arch.ctxt.regs.pstate;
|
||||
return vcpu_cpsr(vcpu);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(sp_el1):
|
||||
return __ctxt_sys_reg(&vcpu->arch.ctxt, SP_EL1);
|
||||
return vcpu_sp_el1(vcpu);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(elr_el1):
|
||||
return __ctxt_sys_reg(&vcpu->arch.ctxt, ELR_EL1);
|
||||
|
|
@ -170,13 +171,13 @@ static void *core_reg_addr(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
|||
KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]):
|
||||
off -= KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]);
|
||||
off /= 4;
|
||||
return &vcpu->arch.ctxt.fp_regs.vregs[off];
|
||||
return vcpu_vreg(vcpu, off);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(fp_regs.fpsr):
|
||||
return &vcpu->arch.ctxt.fp_regs.fpsr;
|
||||
return vcpu_fpsr(vcpu);
|
||||
|
||||
case KVM_REG_ARM_CORE_REG(fp_regs.fpcr):
|
||||
return &vcpu->arch.ctxt.fp_regs.fpcr;
|
||||
return vcpu_fpcr(vcpu);
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
|
|
@ -306,6 +307,8 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
|||
return err;
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
#define vq_word(vq) (((vq) - SVE_VQ_MIN) / 64)
|
||||
#define vq_mask(vq) ((u64)1 << ((vq) - SVE_VQ_MIN) % 64)
|
||||
#define vq_present(vqs, vq) (!!((vqs)[vq_word(vq)] & vq_mask(vq)))
|
||||
|
|
@ -543,6 +546,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
static int copy_core_reg_indices(const struct kvm_vcpu *vcpu,
|
||||
u64 __user *uindices)
|
||||
{
|
||||
|
|
@ -591,6 +595,8 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
|
|||
return copy_core_reg_indices(vcpu, NULL);
|
||||
}
|
||||
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
||||
static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
const unsigned int slices = vcpu_sve_slices(vcpu);
|
||||
|
|
|
|||
|
|
@ -276,12 +276,12 @@ static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
|
|||
switch(mode) {
|
||||
case PSR_AA32_MODE_ABT:
|
||||
__vcpu_write_spsr_abt(vcpu, host_spsr_to_spsr32(spsr));
|
||||
vcpu_gp_regs(vcpu)->compat_lr_abt = return_address;
|
||||
vcpu_gp_regs(vcpu)[__compat_lr_abt] = return_address;
|
||||
break;
|
||||
|
||||
case PSR_AA32_MODE_UND:
|
||||
__vcpu_write_spsr_und(vcpu, host_spsr_to_spsr32(spsr));
|
||||
vcpu_gp_regs(vcpu)->compat_lr_und = return_address;
|
||||
vcpu_gp_regs(vcpu)[__compat_lr_und] = return_address;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ static inline void kvm_skip_instr(struct kvm_vcpu *vcpu)
|
|||
static inline void __kvm_skip_instr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
|
||||
vcpu_gp_regs(vcpu)->pstate = read_sysreg_el2(SYS_SPSR);
|
||||
*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
|
||||
|
||||
kvm_skip_instr(vcpu);
|
||||
|
||||
write_sysreg_el2(vcpu_gp_regs(vcpu)->pstate, SYS_SPSR);
|
||||
write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
|
||||
write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
|
|||
u64 spsr;
|
||||
|
||||
*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
|
||||
arm64_mops_reset_regs(vcpu_gp_regs(vcpu), vcpu->arch.fault.esr_el2);
|
||||
arm64_mops_reset_regs(&vcpu->arch.ctxt.regs, vcpu->arch.fault.esr_el2);
|
||||
write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
|
||||
|
||||
/*
|
||||
|
|
@ -902,7 +902,7 @@ static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu)
|
|||
/*
|
||||
* Check for the conditions of Cortex-A510's #2077057. When these occur
|
||||
* SPSR_EL2 can't be trusted, but isn't needed either as it is
|
||||
* unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
|
||||
* unchanged from the value in vcpu_cpsr(vcpu).
|
||||
* Are we single-stepping the guest, and took a PAC exception from the
|
||||
* active-not-pending state?
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "trace.h"
|
||||
|
||||
#if ARM64_S390_COMMON == 1
|
||||
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data)
|
||||
{
|
||||
void *datap = NULL;
|
||||
|
|
@ -258,3 +259,4 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
|
|||
run->exit_reason = KVM_EXIT_MMIO;
|
||||
return 0;
|
||||
}
|
||||
#endif /* ARM64_S390_COMMON == 1 */
|
||||
|
|
|
|||
|
|
@ -401,6 +401,57 @@ Res0 3:1
|
|||
Field 0 SO
|
||||
EndSysreg
|
||||
|
||||
SysregFields SPSR_ELx
|
||||
Res0 63:37
|
||||
Field 36 UINJ
|
||||
Field 35 PACM
|
||||
Field 34 EXLOCK
|
||||
Res0 33
|
||||
Field 32 PM
|
||||
Field 31 N
|
||||
Field 30 Z
|
||||
Field 29 C
|
||||
Field 28 V
|
||||
Res0 27:26
|
||||
Field 25 TCO
|
||||
Field 24 DIT
|
||||
Field 23 UAO
|
||||
Field 22 PAN
|
||||
Field 21 SS
|
||||
Field 20 IL
|
||||
Res0 19:14
|
||||
Field 13 ALLINT
|
||||
Field 12 SSBS
|
||||
Field 11:10 BTYPE
|
||||
Field 9 D
|
||||
Field 8 A
|
||||
Field 7 I
|
||||
Field 6 F
|
||||
Res0 5
|
||||
Field 4 M4
|
||||
Enum 3:0 M
|
||||
0b0000 EL0
|
||||
0b0100 EL1t
|
||||
0b0101 EL1h
|
||||
0b1000 EL2t
|
||||
0b1001 EL2h
|
||||
0b1100 EL3t
|
||||
0b1101 EL3h
|
||||
EndEnum
|
||||
EndSysregFields
|
||||
|
||||
Sysreg SPSR_EL1 3 0 4 0 0
|
||||
Fields SPSR_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg SPSR_EL2 3 4 4 0 0
|
||||
Fields SPSR_ELx
|
||||
EndSysreg
|
||||
|
||||
Sysreg SPSR_EL12 3 5 4 0 0
|
||||
Mapping SPSR_EL1
|
||||
EndSysreg
|
||||
|
||||
Sysreg ID_PFR0_EL1 3 0 0 1 0
|
||||
Res0 63:32
|
||||
UnsignedEnum 31:28 RAS
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user