Alexander Graf wrote:
This adds the #VMEXIT intercept, so we return to the level 1 guest
when something happens in the level 2 guest that should return to
the level 1 guest.

@@ -223,6 +228,21 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, 
unsigned nr,
 {
        struct vcpu_svm *svm = to_svm(vcpu);
+ /* If we are within a nested VM we'd better #VMEXIT and let the
+          guest handle the exception */
+       if (is_nested(svm)) {
+               svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
+               svm->vmcb->control.exit_code_hi = 0;
+               svm->vmcb->control.exit_info_1 = error_code;
+               svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;

#vmexit isn't supposed to modify cr2, but we've corrupted it here.

+               if (nested_svm_exit_handled(svm, false)) {
+                       nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
+
+                       nested_svm_vmexit(svm);
+                       return;
+               }
+       }
+

Please move the entire block into a separate function.


+static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
+                                 void *arg2, void *opaque)
+{
+       struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+       struct vmcb *hsave = (struct vmcb *)arg2;
+       u64 nested_save[] = { nested_vmcb->save.cr0,
+                             nested_vmcb->save.cr3,
+                             nested_vmcb->save.cr4,
+                             nested_vmcb->save.efer,
+                             nested_vmcb->control.intercept_cr_read,
+                             nested_vmcb->control.intercept_cr_write,
+                             nested_vmcb->control.intercept_dr_read,
+                             nested_vmcb->control.intercept_dr_write,
+                             nested_vmcb->control.intercept_exceptions,
+                             nested_vmcb->control.intercept,
+                             nested_vmcb->control.msrpm_base_pa,
+                             nested_vmcb->control.iopm_base_pa,
+                             nested_vmcb->control.tsc_offset };
+
+       /* Give the current vmcb to the guest */
+       memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb));
+       nested_vmcb->save.cr0 = nested_save[0];
+       if (!npt_enabled)
+               nested_vmcb->save.cr3 = nested_save[1];
+       nested_vmcb->save.cr4 = nested_save[2];
+       nested_vmcb->save.efer = nested_save[3];
+       nested_vmcb->control.intercept_cr_read = nested_save[4];
+       nested_vmcb->control.intercept_cr_write = nested_save[5];
+       nested_vmcb->control.intercept_dr_read = nested_save[6];
+       nested_vmcb->control.intercept_dr_write = nested_save[7];
+       nested_vmcb->control.intercept_exceptions = nested_save[8];
+       nested_vmcb->control.intercept = nested_save[9];
+       nested_vmcb->control.msrpm_base_pa = nested_save[10];
+       nested_vmcb->control.iopm_base_pa = nested_save[11];
+       nested_vmcb->control.tsc_offset = nested_save[12];
+
+       if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) &&
+           (nested_vmcb->control.int_vector)) {
+               nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n",
+                               nested_vmcb->control.int_vector);
+       }
+
+       /* Restore the original control entries */
+       memcpy(&svm->vmcb->control, &hsave->control,
+              sizeof(struct vmcb_control_area));
+       force_new_asid(&svm->vcpu);
+       /* Kill any pending exceptions */
+       if (svm->vcpu.arch.exception.pending == true)
+               nsvm_printk("WARNING: Pending Exception\n");

This should set control.exit_int_info.

--
error compiling committee.c: too many arguments to function

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to