|
@@ -1974,10 +1974,26 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
|
|
|
{
|
|
|
struct vcpu_svm *svm = to_svm(vcpu);
|
|
|
|
|
|
- svm->vmcb->control.exit_code = SVM_EXIT_NPF;
|
|
|
- svm->vmcb->control.exit_code_hi = 0;
|
|
|
- svm->vmcb->control.exit_info_1 = fault->error_code;
|
|
|
- svm->vmcb->control.exit_info_2 = fault->address;
|
|
|
+ if (svm->vmcb->control.exit_code != SVM_EXIT_NPF) {
|
|
|
+ /*
|
|
|
+ * TODO: track the cause of the nested page fault, and
|
|
|
+ * correctly fill in the high bits of exit_info_1.
|
|
|
+ */
|
|
|
+ svm->vmcb->control.exit_code = SVM_EXIT_NPF;
|
|
|
+ svm->vmcb->control.exit_code_hi = 0;
|
|
|
+ svm->vmcb->control.exit_info_1 = (1ULL << 32);
|
|
|
+ svm->vmcb->control.exit_info_2 = fault->address;
|
|
|
+ }
|
|
|
+
|
|
|
+ svm->vmcb->control.exit_info_1 &= ~0xffffffffULL;
|
|
|
+ svm->vmcb->control.exit_info_1 |= fault->error_code;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The present bit is always zero for page structure faults on real
|
|
|
+ * hardware.
|
|
|
+ */
|
|
|
+ if (svm->vmcb->control.exit_info_1 & (2ULL << 32))
|
|
|
+ svm->vmcb->control.exit_info_1 &= ~1;
|
|
|
|
|
|
nested_svm_vmexit(svm);
|
|
|
}
|