diff options
Diffstat (limited to 'arch/arm/include/asm/kvm_emulate.h')
| -rw-r--r-- | arch/arm/include/asm/kvm_emulate.h | 107 |
1 files changed, 100 insertions, 7 deletions
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index fd611996bfb5..82b4babead2c 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h | |||
| @@ -22,11 +22,12 @@ | |||
| 22 | #include <linux/kvm_host.h> | 22 | #include <linux/kvm_host.h> |
| 23 | #include <asm/kvm_asm.h> | 23 | #include <asm/kvm_asm.h> |
| 24 | #include <asm/kvm_mmio.h> | 24 | #include <asm/kvm_mmio.h> |
| 25 | #include <asm/kvm_arm.h> | ||
| 25 | 26 | ||
| 26 | u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); | 27 | unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); |
| 27 | u32 *vcpu_spsr(struct kvm_vcpu *vcpu); | 28 | unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu); |
| 28 | 29 | ||
| 29 | int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run); | 30 | bool kvm_condition_valid(struct kvm_vcpu *vcpu); |
| 30 | void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); | 31 | void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); |
| 31 | void kvm_inject_undefined(struct kvm_vcpu *vcpu); | 32 | void kvm_inject_undefined(struct kvm_vcpu *vcpu); |
| 32 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); | 33 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); |
| @@ -37,14 +38,14 @@ static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) | |||
| 37 | return 1; | 38 | return 1; |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | static inline u32 *vcpu_pc(struct kvm_vcpu *vcpu) | 41 | static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu) |
| 41 | { | 42 | { |
| 42 | return (u32 *)&vcpu->arch.regs.usr_regs.ARM_pc; | 43 | return &vcpu->arch.regs.usr_regs.ARM_pc; |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | static inline u32 *vcpu_cpsr(struct kvm_vcpu *vcpu) | 46 | static inline unsigned long *vcpu_cpsr(struct kvm_vcpu *vcpu) |
| 46 | { | 47 | { |
| 47 | return (u32 *)&vcpu->arch.regs.usr_regs.ARM_cpsr; | 48 | return &vcpu->arch.regs.usr_regs.ARM_cpsr; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu) | 51 | static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu) |
| @@ -69,4 +70,96 @@ static inline bool kvm_vcpu_reg_is_pc(struct kvm_vcpu *vcpu, int reg) | |||
| 69 | return reg == 15; | 70 | return reg == 15; |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 73 | static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu) | ||
| 74 | { | ||
| 75 | return vcpu->arch.fault.hsr; | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline unsigned long kvm_vcpu_get_hfar(struct kvm_vcpu *vcpu) | ||
| 79 | { | ||
| 80 | return vcpu->arch.fault.hxfar; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline phys_addr_t kvm_vcpu_get_fault_ipa(struct kvm_vcpu *vcpu) | ||
| 84 | { | ||
| 85 | return ((phys_addr_t)vcpu->arch.fault.hpfar & HPFAR_MASK) << 8; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline unsigned long kvm_vcpu_get_hyp_pc(struct kvm_vcpu *vcpu) | ||
| 89 | { | ||
| 90 | return vcpu->arch.fault.hyp_pc; | ||
| 91 | } | ||
| 92 | |||
| 93 | static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu) | ||
| 94 | { | ||
| 95 | return kvm_vcpu_get_hsr(vcpu) & HSR_ISV; | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu) | ||
| 99 | { | ||
| 100 | return kvm_vcpu_get_hsr(vcpu) & HSR_WNR; | ||
| 101 | } | ||
| 102 | |||
| 103 | static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu) | ||
| 104 | { | ||
| 105 | return kvm_vcpu_get_hsr(vcpu) & HSR_SSE; | ||
| 106 | } | ||
| 107 | |||
| 108 | static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) | ||
| 109 | { | ||
| 110 | return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) | ||
| 114 | { | ||
| 115 | return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA; | ||
| 116 | } | ||
| 117 | |||
| 118 | static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) | ||
| 119 | { | ||
| 120 | return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Get Access Size from a data abort */ | ||
| 124 | static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu) | ||
| 125 | { | ||
| 126 | switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) { | ||
| 127 | case 0: | ||
| 128 | return 1; | ||
| 129 | case 1: | ||
| 130 | return 2; | ||
| 131 | case 2: | ||
| 132 | return 4; | ||
| 133 | default: | ||
| 134 | kvm_err("Hardware is weird: SAS 0b11 is reserved\n"); | ||
| 135 | return -EFAULT; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | /* This one is not specific to Data Abort */ | ||
| 140 | static inline bool kvm_vcpu_trap_il_is32bit(struct kvm_vcpu *vcpu) | ||
| 141 | { | ||
| 142 | return kvm_vcpu_get_hsr(vcpu) & HSR_IL; | ||
| 143 | } | ||
| 144 | |||
| 145 | static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu) | ||
| 146 | { | ||
| 147 | return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT; | ||
| 148 | } | ||
| 149 | |||
| 150 | static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu) | ||
| 151 | { | ||
| 152 | return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT; | ||
| 153 | } | ||
| 154 | |||
| 155 | static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu) | ||
| 156 | { | ||
| 157 | return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE; | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) | ||
| 161 | { | ||
| 162 | return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; | ||
| 163 | } | ||
| 164 | |||
| 72 | #endif /* __ARM_KVM_EMULATE_H__ */ | 165 | #endif /* __ARM_KVM_EMULATE_H__ */ |
