diff mbox

[11/11] nEPT: Provide the correct exit qualification upon EPT

Message ID 1366958611-6935-11-git-send-email-jun.nakajima@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nakajima, Jun April 26, 2013, 6:43 a.m. UTC
Save [2:0] of exit qualificaiton at EPT violation, and use the information when injecting EPT violation.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Xinhao Xu <xinhao.xu@intel.com>
---
 arch/x86/include/asm/kvm_host.h | 2 ++
 arch/x86/kvm/paging_tmpl.h      | 5 +++++
 arch/x86/kvm/vmx.c              | 3 +++
 3 files changed, 10 insertions(+)

Comments

Paolo Bonzini April 29, 2013, 3:37 p.m. UTC | #1
Il 26/04/2013 08:43, Jun Nakajima ha scritto:
> diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
> index e13b6c5..bd370e7 100644
> --- a/arch/x86/kvm/paging_tmpl.h
> +++ b/arch/x86/kvm/paging_tmpl.h
> @@ -349,7 +349,12 @@ error:
>  
>  	walker->fault.vector = PF_VECTOR;
>  	walker->fault.error_code_valid = true;
> +#if PTTYPE != PTTYPE_EPT
>  	walker->fault.error_code = errcode;
> +#else
> +	/* Reuse bits [2:0] of EPT violation */
> +	walker->fault.error_code = vcpu->arch.exit_qualification & 0x7;
> +#endif
>  	walker->fault.address = addr;
>  	walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu;
>  

I'm not sure that this is a step in the right direction.

errcode is dropped completely, but it would be needed to rebuild bits
3:5 of the exit qualification.

Perhaps it is better to access vcpu->arch.exit_qualification in
nested_ept_inject_page_fault, and mix it with the error code from
walker->fault to compute bits 3:5?

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nakajima, Jun April 29, 2013, 3:50 p.m. UTC | #2
On Mon, Apr 29, 2013 at 8:37 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Il 26/04/2013 08:43, Jun Nakajima ha scritto:
>> diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
>> index e13b6c5..bd370e7 100644
>> --- a/arch/x86/kvm/paging_tmpl.h
>> +++ b/arch/x86/kvm/paging_tmpl.h
>> @@ -349,7 +349,12 @@ error:
>>
>>       walker->fault.vector = PF_VECTOR;
>>       walker->fault.error_code_valid = true;
>> +#if PTTYPE != PTTYPE_EPT
>>       walker->fault.error_code = errcode;
>> +#else
>> +     /* Reuse bits [2:0] of EPT violation */
>> +     walker->fault.error_code = vcpu->arch.exit_qualification & 0x7;
>> +#endif
>>       walker->fault.address = addr;
>>       walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu;
>>
>
> I'm not sure that this is a step in the right direction.
>
> errcode is dropped completely, but it would be needed to rebuild bits
> 3:5 of the exit qualification.
>
> Perhaps it is better to access vcpu->arch.exit_qualification in
> nested_ept_inject_page_fault, and mix it with the error code from
> walker->fault to compute bits 3:5?

Yes. We need to generate those bits from the walk of the guest EPT
page tables, and combine them.

I'll update the patches, fixing the issues in Xinhao's patch.

--
Jun
Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4979778..e029bba 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -504,6 +504,8 @@  struct kvm_vcpu_arch {
 	 * instruction.
 	 */
 	bool write_fault_to_shadow_pgtable;
+
+	unsigned long exit_qualification; /* set at EPT violation at this point */
 };
 
 struct kvm_lpage_info {
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index e13b6c5..bd370e7 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -349,7 +349,12 @@  error:
 
 	walker->fault.vector = PF_VECTOR;
 	walker->fault.error_code_valid = true;
+#if PTTYPE != PTTYPE_EPT
 	walker->fault.error_code = errcode;
+#else
+	/* Reuse bits [2:0] of EPT violation */
+	walker->fault.error_code = vcpu->arch.exit_qualification & 0x7;
+#endif
 	walker->fault.address = addr;
 	walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu;
 
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 95304cc..61e2853 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -425,6 +425,7 @@  struct vcpu_vmx {
 	ktime_t entry_time;
 	s64 vnmi_blocked_time;
 	u32 exit_reason;
+	unsigned long exit_qualification;
 
 	bool rdtscp_enabled;
 
@@ -5074,6 +5075,8 @@  static int handle_ept_violation(struct kvm_vcpu *vcpu)
 	/* ept page table is present? */
 	error_code |= (exit_qualification >> 3) & 0x1;
 
+    vcpu->arch.exit_qualification = exit_qualification;
+
 	return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
 }