Skip to content

Commit

Permalink
ARM: KVM: move kvm_condition_valid to emulate.c
Browse files Browse the repository at this point in the history
This is really hardware emulation, and as such it better be with
its little friends.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
  • Loading branch information
Marc Zyngier authored and Christoffer Dall committed Mar 6, 2013
1 parent 52d1dba commit c599756
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 45 deletions.
1 change: 1 addition & 0 deletions arch/arm/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);

int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run);
bool kvm_condition_valid(struct kvm_vcpu *vcpu);
void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr);
void kvm_inject_undefined(struct kvm_vcpu *vcpu);
void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
Expand Down
45 changes: 0 additions & 45 deletions arch/arm/kvm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_psci.h>
#include <asm/opcodes.h>

#ifdef REQUIRES_VIRT
__asm__(".arch_extension virt");
Expand Down Expand Up @@ -545,50 +544,6 @@ static exit_handle_fn arm_exit_handlers[] = {
[HSR_EC_DABT_HYP] = handle_dabt_hyp,
};

/*
* A conditional instruction is allowed to trap, even though it
* wouldn't be executed. So let's re-implement the hardware, in
* software!
*/
static bool kvm_condition_valid(struct kvm_vcpu *vcpu)
{
unsigned long cpsr, cond, insn;

/*
* Exception Code 0 can only happen if we set HCR.TGE to 1, to
* catch undefined instructions, and then we won't get past
* the arm_exit_handlers test anyway.
*/
BUG_ON(!kvm_vcpu_trap_get_class(vcpu));

/* Top two bits non-zero? Unconditional. */
if (kvm_vcpu_get_hsr(vcpu) >> 30)
return true;

cpsr = *vcpu_cpsr(vcpu);

/* Is condition field valid? */
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;

it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);

/* it == 0 => unconditional. */
if (it == 0)
return true;

/* The cond for this insn works out as the top 4 bits. */
cond = (it >> 4);
}

/* Shift makes it look like an ARM-mode instruction */
insn = cond << 28;
return arm_check_condition(insn, cpsr) != ARM_OPCODE_CONDTEST_FAIL;
}

/*
* Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
* proper exit to QEMU.
Expand Down
45 changes: 45 additions & 0 deletions arch/arm/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/kvm_host.h>
#include <asm/kvm_arm.h>
#include <asm/kvm_emulate.h>
#include <asm/opcodes.h>
#include <trace/events/kvm.h>

#include "trace.h"
Expand Down Expand Up @@ -176,6 +177,50 @@ int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run)
return 1;
}

/*
* A conditional instruction is allowed to trap, even though it
* wouldn't be executed. So let's re-implement the hardware, in
* software!
*/
bool kvm_condition_valid(struct kvm_vcpu *vcpu)
{
unsigned long cpsr, cond, insn;

/*
* Exception Code 0 can only happen if we set HCR.TGE to 1, to
* catch undefined instructions, and then we won't get past
* the arm_exit_handlers test anyway.
*/
BUG_ON(!kvm_vcpu_trap_get_class(vcpu));

/* Top two bits non-zero? Unconditional. */
if (kvm_vcpu_get_hsr(vcpu) >> 30)
return true;

cpsr = *vcpu_cpsr(vcpu);

/* Is condition field valid? */
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;

it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);

/* it == 0 => unconditional. */
if (it == 0)
return true;

/* The cond for this insn works out as the top 4 bits. */
cond = (it >> 4);
}

/* Shift makes it look like an ARM-mode instruction */
insn = cond << 28;
return arm_check_condition(insn, cpsr) != ARM_OPCODE_CONDTEST_FAIL;
}

/**
* adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
* @vcpu: The VCPU pointer
Expand Down

0 comments on commit c599756

Please sign in to comment.