1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef __S390_ARM64_KVM_EMULATE_H__ 4 #define __S390_ARM64_KVM_EMULATE_H__ 5 6 #include <asm/fault.h> 7 #include <linux/kvm_host.h> 8 9 #include <arm64/kvm_nested.h> 10 #include <arm64/ptrace.h> 11 #include <arm64/kvm_arm.h> 12 #include <arm64/sysreg.h> 13 14 static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) 15 { 16 return (unsigned long *)&vcpu->arch.sae_block.pc; 17 } 18 19 static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu) 20 { 21 return (unsigned long *)&vcpu->arch.sae_block.pstate; 22 } 23 24 static __always_inline unsigned long *vcpu_sp_el0(const struct kvm_vcpu *vcpu) 25 { 26 return (unsigned long *)&vcpu->arch.sae_block.sp_el0; 27 } 28 29 static __always_inline u64 *vcpu_sp_el1(struct kvm_vcpu *vcpu) 30 { 31 return &vcpu->arch.sae_block.sp_el1; 32 } 33 34 static __always_inline __vector128 *vcpu_vreg(struct kvm_vcpu *vcpu, int off) 35 { 36 return &vcpu->arch.ctxt.vregs[off]; 37 } 38 39 static __always_inline u32 *vcpu_fpsr(struct kvm_vcpu *vcpu) 40 { 41 return &vcpu->arch.sae_block.fpsr; 42 } 43 44 static __always_inline u32 *vcpu_fpcr(struct kvm_vcpu *vcpu) 45 { 46 return &vcpu->arch.sae_block.fpcr; 47 } 48 49 static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu) 50 { 51 return false; 52 } 53 54 static __always_inline u64 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu) 55 { 56 return vcpu->arch.sae_block.hai.esr_el2; 57 } 58 59 static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu) 60 { 61 return (unsigned long *)&vcpu->arch.hcr_el2; 62 } 63 64 static __always_inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vcpu) 65 { 66 return vcpu->arch.sae_block.hai.far_el2; 67 } 68 69 static __always_inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu) 70 { 71 return gfn_to_gpa(vcpu->arch.sae_block.hai.teid.addr); 72 } 73 74 static inline u16 kvm_vcpu_fault_pic(const struct kvm_vcpu *vcpu) 75 { 76 return vcpu->arch.sae_block.hai.pic & PGM_INT_CODE_MASK; 77 } 78 79 static __always_inline 80 bool kvm_vcpu_trap_is_permission_fault(const struct kvm_vcpu *vcpu) 81 { 82 return kvm_vcpu_fault_pic(vcpu) == PGM_PROTECTION; 83 } 84 85 static __always_inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu) 86 { 87 return true; 88 } 89 90 static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu) 91 { 92 return false; 93 } 94 95 static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu) 96 { 97 return false; 98 } 99 100 static inline int kvm_vcpu_abt_gltl(struct kvm_vcpu *vcpu) 101 { 102 return vcpu->arch.sae_block.hai.gltl; 103 } 104 105 static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu) 106 { 107 u32 mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK; 108 109 return mode != PSR_MODE_EL0t; 110 } 111 112 static inline void kvm_skip_instr(struct kvm_vcpu *vcpu) 113 { 114 *vcpu_pc(vcpu) += 4; 115 *vcpu_cpsr(vcpu) &= ~PSR_BTYPE_MASK; 116 117 /* advance the singlestep state machine */ 118 *vcpu_cpsr(vcpu) &= ~SPSR_ELx_SS; 119 } 120 121 static inline void kvm_reset_fpsimd(struct kvm_vcpu *vcpu) 122 { 123 memset(vcpu->arch.ctxt.vregs, 0, sizeof(vcpu->arch.ctxt.vregs)); 124 vcpu->arch.sae_block.fpsr = 0; 125 vcpu->arch.sae_block.fpcr = 0; 126 } 127 128 #include <arm64/kvm_emulate-gen.h> 129 130 #endif /* __S390_ARM64_KVM_EMULATE_H__ */ 131