ARM: KVM: abstract fault register accesses
Instead of directly accessing the fault registers, use proper accessors
so the core code can be shared.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 5a93698..6626c7e 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -492,7 +492,7 @@
static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
- vcpu->arch.hsr & HSR_HVC_IMM_MASK);
+ kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK);
if (kvm_psci_call(vcpu))
return 1;
@@ -513,16 +513,16 @@
static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
/* The hypervisor should never cause aborts */
- kvm_err("Prefetch Abort taken from Hyp mode at %#08x (HSR: %#08x)\n",
- vcpu->arch.hxfar, vcpu->arch.hsr);
+ kvm_err("Prefetch Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
+ kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
return -EFAULT;
}
static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
/* This is either an error in the ws. code or an external abort */
- kvm_err("Data Abort taken from Hyp mode at %#08x (HSR: %#08x)\n",
- vcpu->arch.hxfar, vcpu->arch.hsr);
+ kvm_err("Data Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
+ kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
return -EFAULT;
}
@@ -559,17 +559,17 @@
* catch undefined instructions, and then we won't get past
* the arm_exit_handlers test anyway.
*/
- BUG_ON(((vcpu->arch.hsr & HSR_EC) >> HSR_EC_SHIFT) == 0);
+ BUG_ON(((kvm_vcpu_get_hsr(vcpu) & HSR_EC) >> HSR_EC_SHIFT) == 0);
/* Top two bits non-zero? Unconditional. */
- if (vcpu->arch.hsr >> 30)
+ if (kvm_vcpu_get_hsr(vcpu) >> 30)
return true;
cpsr = *vcpu_cpsr(vcpu);
/* Is condition field valid? */
- if ((vcpu->arch.hsr & HSR_CV) >> HSR_CV_SHIFT)
- cond = (vcpu->arch.hsr & HSR_COND) >> HSR_COND_SHIFT;
+ if ((kvm_vcpu_get_hsr(vcpu) & HSR_CV) >> HSR_CV_SHIFT)
+ cond = (kvm_vcpu_get_hsr(vcpu) & HSR_COND) >> HSR_COND_SHIFT;
else {
/* This can happen in Thumb mode: examine IT state. */
unsigned long it;
@@ -602,20 +602,20 @@
case ARM_EXCEPTION_IRQ:
return 1;
case ARM_EXCEPTION_UNDEFINED:
- kvm_err("Undefined exception in Hyp mode at: %#08x\n",
- vcpu->arch.hyp_pc);
+ kvm_err("Undefined exception in Hyp mode at: %#08lx\n",
+ kvm_vcpu_get_hyp_pc(vcpu));
BUG();
panic("KVM: Hypervisor undefined exception!\n");
case ARM_EXCEPTION_DATA_ABORT:
case ARM_EXCEPTION_PREF_ABORT:
case ARM_EXCEPTION_HVC:
- hsr_ec = (vcpu->arch.hsr & HSR_EC) >> HSR_EC_SHIFT;
+ hsr_ec = (kvm_vcpu_get_hsr(vcpu) & HSR_EC) >> HSR_EC_SHIFT;
if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers)
|| !arm_exit_handlers[hsr_ec]) {
kvm_err("Unkown exception class: %#08lx, "
"hsr: %#08x\n", hsr_ec,
- (unsigned int)vcpu->arch.hsr);
+ (unsigned int)kvm_vcpu_get_hsr(vcpu));
BUG();
}
@@ -624,7 +624,7 @@
* that fail their condition code check"
*/
if (!kvm_condition_valid(vcpu)) {
- bool is_wide = vcpu->arch.hsr & HSR_IL;
+ bool is_wide = kvm_vcpu_get_hsr(vcpu) & HSR_IL;
kvm_skip_instr(vcpu, is_wide);
return 1;
}
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 38e76bc..b305916 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -293,7 +293,7 @@
if (likely(r->access(vcpu, params, r))) {
/* Skip instruction, since it was emulated */
- kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1);
+ kvm_skip_instr(vcpu, (kvm_vcpu_get_hsr(vcpu) >> 25) & 1);
return 1;
}
/* If access function fails, it should complain. */
@@ -315,14 +315,14 @@
{
struct coproc_params params;
- params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
- params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
- params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf;
+ params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf;
+ params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0);
params.is_64bit = true;
- params.Op1 = (vcpu->arch.hsr >> 16) & 0xf;
+ params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 16) & 0xf;
params.Op2 = 0;
- params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf;
+ params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
params.CRn = 0;
return emulate_cp15(vcpu, ¶ms);
@@ -347,14 +347,14 @@
{
struct coproc_params params;
- params.CRm = (vcpu->arch.hsr >> 1) & 0xf;
- params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf;
- params.is_write = ((vcpu->arch.hsr & 1) == 0);
+ params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf;
+ params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf;
+ params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0);
params.is_64bit = false;
- params.CRn = (vcpu->arch.hsr >> 10) & 0xf;
- params.Op1 = (vcpu->arch.hsr >> 14) & 0x7;
- params.Op2 = (vcpu->arch.hsr >> 17) & 0x7;
+ params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
+ params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 14) & 0x7;
+ params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
params.Rt2 = 0;
return emulate_cp15(vcpu, ¶ms);
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index c186bc9..ce63f39 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -65,19 +65,19 @@
unsigned long rt, len;
bool is_write, sign_extend;
- if ((vcpu->arch.hsr >> 8) & 1) {
+ if ((kvm_vcpu_get_hsr(vcpu) >> 8) & 1) {
/* cache operation on I/O addr, tell guest unsupported */
- kvm_inject_dabt(vcpu, vcpu->arch.hxfar);
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
return 1;
}
- if ((vcpu->arch.hsr >> 7) & 1) {
+ if ((kvm_vcpu_get_hsr(vcpu) >> 7) & 1) {
/* page table accesses IO mem: tell guest to fix its TTBR */
- kvm_inject_dabt(vcpu, vcpu->arch.hxfar);
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
return 1;
}
- switch ((vcpu->arch.hsr >> 22) & 0x3) {
+ switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) {
case 0:
len = 1;
break;
@@ -92,13 +92,13 @@
return -EFAULT;
}
- is_write = vcpu->arch.hsr & HSR_WNR;
- sign_extend = vcpu->arch.hsr & HSR_SSE;
- rt = (vcpu->arch.hsr & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
+ is_write = kvm_vcpu_get_hsr(vcpu) & HSR_WNR;
+ sign_extend = kvm_vcpu_get_hsr(vcpu) & HSR_SSE;
+ rt = (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
if (kvm_vcpu_reg_is_pc(vcpu, rt)) {
/* IO memory trying to read/write pc */
- kvm_inject_pabt(vcpu, vcpu->arch.hxfar);
+ kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu));
return 1;
}
@@ -112,7 +112,7 @@
* The MMIO instruction is emulated and should not be re-executed
* in the guest.
*/
- kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1);
+ kvm_skip_instr(vcpu, (kvm_vcpu_get_hsr(vcpu) >> 25) & 1);
return 0;
}
@@ -130,7 +130,7 @@
* space do its magic.
*/
- if (vcpu->arch.hsr & HSR_ISV) {
+ if (kvm_vcpu_get_hsr(vcpu) & HSR_ISV) {
ret = decode_hsr(vcpu, fault_ipa, &mmio);
if (ret)
return ret;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 99e07c7..d0f5f52 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -526,7 +526,7 @@
unsigned long mmu_seq;
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
- write_fault = kvm_is_write_fault(vcpu->arch.hsr);
+ write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu));
if (fault_status == FSC_PERM && !write_fault) {
kvm_err("Unexpected L2 read permission error\n");
return -EFAULT;
@@ -593,15 +593,15 @@
gfn_t gfn;
int ret, idx;
- hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT;
+ hsr_ec = kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT;
is_iabt = (hsr_ec == HSR_EC_IABT);
- fault_ipa = ((phys_addr_t)vcpu->arch.hpfar & HPFAR_MASK) << 8;
+ fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
- trace_kvm_guest_fault(*vcpu_pc(vcpu), vcpu->arch.hsr,
- vcpu->arch.hxfar, fault_ipa);
+ trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
+ kvm_vcpu_get_hfar(vcpu), fault_ipa);
/* Check the stage-2 fault is trans. fault or write fault */
- fault_status = (vcpu->arch.hsr & HSR_FSC_TYPE);
+ fault_status = (kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE);
if (fault_status != FSC_FAULT && fault_status != FSC_PERM) {
kvm_err("Unsupported fault status: EC=%#lx DFCS=%#lx\n",
hsr_ec, fault_status);
@@ -614,7 +614,7 @@
if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) {
if (is_iabt) {
/* Prefetch Abort on I/O address */
- kvm_inject_pabt(vcpu, vcpu->arch.hxfar);
+ kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu));
ret = 1;
goto out_unlock;
}
@@ -627,7 +627,7 @@
}
/* Adjust page offset */
- fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK;
+ fault_ipa |= kvm_vcpu_get_hfar(vcpu) & ~PAGE_MASK;
ret = io_mem_abort(vcpu, run, fault_ipa);
goto out_unlock;
}