Re: [Rusty Russell] [PATCH] ARM: KVM: kvm_condition_valid()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux