On Wed, Aug 15, 2012 at 9:52 AM, Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> wrote: > On Wed, Aug 15, 2012 at 9:33 AM, Peter Maydell <peter.maydell@xxxxxxxxxx> wrote: >> On 15 August 2012 14:03, Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> wrote: >>> unfortunately it is complicated by the fact that we need to know how >>> long the instruction is to be able to skip it, which would mean that >>> we would have to do the VA to PA on every HVC exception and copy the >>> instruction from the guest check the length - unless we assume that >>> HSR.ISV == 1 whenever this happens...? >> >> You should always be able to get the instruction length via >> HSR.IL for ccode-failed cases, because they only apply for >> cases where a hyp trap has been set for a particular instruction >> or instruction class. In particular, if we have got past the >> assertion that EC is not zero and the check for top two bits >> nonzero, then we're definitely in one of the set of exception >> classes for which HSR.IL is valid. >> > that's true, > > thanks for working that out for me ;) > here's the fixup I applied: commit fb723a002b7fe71aec3b661f30e34218aa1e0959 Author: Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> Date: Mon Aug 13 22:55:14 2012 -0400 fixup! ARM: KVM: kvm_condition_valid() diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index bc63a5a..d899fbb 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -55,6 +55,7 @@ int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, unsigned long instr); void kvm_adjust_itstate(struct kvm_vcpu *vcpu); +void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); void kvm_inject_undefined(struct kvm_vcpu *vcpu); /* diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index fcfee4d..cbf3633 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -538,10 +538,15 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, BUG(); } - /* See ARM ARM B1.14.1: "Hyp traps on instructions - * that fail their condition code check" */ - if (!kvm_condition_valid(vcpu)) - return 0; + /* + * See ARM ARM B1.14.1: "Hyp traps on instructions + * that fail their condition code check" + */ + if (!kvm_condition_valid(vcpu)) { + bool is_wide = vcpu->arch.hsr & HSR_IL; + kvm_skip_instr(vcpu, is_wide); + return 1; + } return arm_exit_handlers[hsr_ec](vcpu, run); default: diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index c43b183..6cbdb08 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -378,9 +378,9 @@ static int kvm_ls_length(struct kvm_vcpu *vcpu, u32 instr) int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, unsigned long instr) { - unsigned long rd, rn, offset, len, instr_len; + unsigned long rd, rn, offset, len; int index; - bool is_write, is_thumb; + bool is_write; trace_kvm_mmio_emulate(vcpu->arch.regs.pc, instr, vcpu->arch.regs.cpsr); @@ -416,14 +416,7 @@ int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * The MMIO instruction is emulated and should not be re-executed * in the guest. */ - is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_T_BIT); - if (is_thumb && !is_wide_instruction(instr)) - instr_len = 2; - else - instr_len = 4; - - *vcpu_pc(vcpu) += instr_len; - kvm_adjust_itstate(vcpu); + kvm_skip_instr(vcpu, is_wide_instruction(instr)); vcpu->run->exit_reason = KVM_EXIT_MMIO; return 0; } @@ -466,6 +459,23 @@ void kvm_adjust_itstate(struct kvm_vcpu *vcpu) *vcpu_cpsr(vcpu) = cpsr; } +/** + * kvm_skip_instr - skip a trapped instruction and proceed to the next + * @vcpu: The vcpu pointer + */ +void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) +{ + bool is_thumb; + + is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_T_BIT); + if (is_thumb && !is_wide_instr) + *vcpu_pc(vcpu) += 2; + else + *vcpu_pc(vcpu) += 4; + kvm_adjust_itstate(vcpu); +} + + /****************************************************************************** * Inject exceptions into the guest */ _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm