diff mbox

[2/4] Rewrite twisted maze of if() statements with more straightforward switch()

Message ID 20090329141207.30481.33603.stgit@trex.usersys.redhat.com (mailing list archive)
State Accepted
Headers show

Commit Message

Gleb Natapov March 29, 2009, 2:12 p.m. UTC
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---

 arch/x86/kvm/vmx.c |   43 +++++++++++++++++++++++++------------------
 1 files changed, 25 insertions(+), 18 deletions(-)


--
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

Comments

Avi Kivity March 30, 2009, 7:35 a.m. UTC | #1
Gleb Natapov wrote:
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>   

This is actually not just a rewrite, but also a bugfix:

> INTR_INFO);
> @@ -3289,34 +3288,42 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
>  		vmx->vnmi_blocked_time +=
>  			ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
>  
> +	vmx->vcpu.arch.nmi_injected = false;
> +	kvm_clear_exception_queue(&vmx->vcpu);
> +	kvm_clear_interrupt_queue(&vmx->vcpu);
> +
> +	if (!idtv_info_valid)
> +		return;
> +
>  	vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
>  	type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
> -	if (vmx->vcpu.arch.nmi_injected) {
> +	
> +	switch(type) {
> +	case INTR_TYPE_NMI_INTR:
> +		vmx->vcpu.arch.nmi_injected = true;
>  		/*
>   

The existing code would leave nmi_injected == false if we exit on 
NMI_INTR, so we drop an NMI here.
Jan Kiszka March 30, 2009, 4:03 p.m. UTC | #2
Avi Kivity wrote:
> Gleb Natapov wrote:
>> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>>   
> 
> This is actually not just a rewrite, but also a bugfix:
> 
>> INTR_INFO);
>> @@ -3289,34 +3288,42 @@ static void vmx_complete_interrupts(struct
>> vcpu_vmx *vmx)
>>          vmx->vnmi_blocked_time +=
>>              ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
>>  
>> +    vmx->vcpu.arch.nmi_injected = false;
>> +    kvm_clear_exception_queue(&vmx->vcpu);
>> +    kvm_clear_interrupt_queue(&vmx->vcpu);
>> +
>> +    if (!idtv_info_valid)
>> +        return;
>> +
>>      vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
>>      type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
>> -    if (vmx->vcpu.arch.nmi_injected) {
>> +   
>> +    switch(type) {
>> +    case INTR_TYPE_NMI_INTR:
>> +        vmx->vcpu.arch.nmi_injected = true;
>>          /*
>>   
> 
> The existing code would leave nmi_injected == false if we exit on
> NMI_INTR, so we drop an NMI here.
> 

I think NMI_INTR and nmi_injected always go together. However, the
rework looks good and more logical to me, too. Will see that I can give
this (more precisely -v2) a try with our scenarios ASAP.

Jan
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 14e3f48..1017544 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3264,7 +3264,6 @@  static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
 	u8 vector;
 	int type;
 	bool idtv_info_valid;
-	u32 error;
 
 	idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 	exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
@@ -3289,34 +3288,42 @@  static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
 		vmx->vnmi_blocked_time +=
 			ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
 
+	vmx->vcpu.arch.nmi_injected = false;
+	kvm_clear_exception_queue(&vmx->vcpu);
+	kvm_clear_interrupt_queue(&vmx->vcpu);
+
+	if (!idtv_info_valid)
+		return;
+
 	vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
 	type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
-	if (vmx->vcpu.arch.nmi_injected) {
+	
+	switch(type) {
+	case INTR_TYPE_NMI_INTR:
+		vmx->vcpu.arch.nmi_injected = true;
 		/*
 		 * SDM 3: 27.7.1.2 (September 2008)
-		 * Clear bit "block by NMI" before VM entry if a NMI delivery
-		 * faulted.
+		 * Clear bit "block by NMI" before VM entry if a NMI
+		 * delivery faulted.
 		 */
-		if (idtv_info_valid && type == INTR_TYPE_NMI_INTR)
-			vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
-					GUEST_INTR_STATE_NMI);
-		else
-			vmx->vcpu.arch.nmi_injected = false;
-	}
-	kvm_clear_exception_queue(&vmx->vcpu);
-	if (idtv_info_valid && (type == INTR_TYPE_HARD_EXCEPTION ||
-				type == INTR_TYPE_SOFT_EXCEPTION)) {
+		vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+				GUEST_INTR_STATE_NMI);
+		break;
+	case INTR_TYPE_HARD_EXCEPTION:
+	case INTR_TYPE_SOFT_EXCEPTION:
 		if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
-			error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
-			kvm_queue_exception_e(&vmx->vcpu, vector, error);
+			u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE);
+			kvm_queue_exception_e(&vmx->vcpu, vector, err);
 		} else
 			kvm_queue_exception(&vmx->vcpu, vector);
 		vmx->idt_vectoring_info = 0;
-	}
-	kvm_clear_interrupt_queue(&vmx->vcpu);
-	if (idtv_info_valid && type == INTR_TYPE_EXT_INTR) {
+		break;
+	case INTR_TYPE_EXT_INTR:
 		kvm_queue_interrupt(&vmx->vcpu, vector);
 		vmx->idt_vectoring_info = 0;
+		break;
+	default:
+		break;
 	}
 }