Skip to content

Commit 91e86d2

Browse files
jsmattsonjrbonzini
authored andcommitted
kvm: x86: Add payload operands to kvm_multiple_exception
kvm_multiple_exception now takes two additional operands: has_payload and payload, so that updates to CR2 (and DR6 under VMX) can be delayed until the exception is delivered. This is necessary to properly emulate VMX or SVM hardware behavior for nested virtualization. The new behavior is triggered by vcpu->kvm->arch.exception_payload_enabled, which will (later) be set by a new per-VM capability, KVM_CAP_EXCEPTION_PAYLOAD. Reported-by: Jim Mattson <jmattson@google.com> Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Jim Mattson <jmattson@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 59073aa commit 91e86d2

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

arch/x86/kvm/x86.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ static int exception_type(int vector)
402402

403403
static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
404404
unsigned nr, bool has_error, u32 error_code,
405-
bool reinject)
405+
bool has_payload, unsigned long payload, bool reinject)
406406
{
407407
u32 prev_nr;
408408
int class1, class2;
@@ -424,15 +424,23 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
424424
*/
425425
WARN_ON_ONCE(vcpu->arch.exception.pending);
426426
vcpu->arch.exception.injected = true;
427+
if (WARN_ON_ONCE(has_payload)) {
428+
/*
429+
* A reinjected event has already
430+
* delivered its payload.
431+
*/
432+
has_payload = false;
433+
payload = 0;
434+
}
427435
} else {
428436
vcpu->arch.exception.pending = true;
429437
vcpu->arch.exception.injected = false;
430438
}
431439
vcpu->arch.exception.has_error_code = has_error;
432440
vcpu->arch.exception.nr = nr;
433441
vcpu->arch.exception.error_code = error_code;
434-
vcpu->arch.exception.has_payload = false;
435-
vcpu->arch.exception.payload = 0;
442+
vcpu->arch.exception.has_payload = has_payload;
443+
vcpu->arch.exception.payload = payload;
436444
return;
437445
}
438446

@@ -468,13 +476,13 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
468476

469477
void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
470478
{
471-
kvm_multiple_exception(vcpu, nr, false, 0, false);
479+
kvm_multiple_exception(vcpu, nr, false, 0, false, 0, false);
472480
}
473481
EXPORT_SYMBOL_GPL(kvm_queue_exception);
474482

475483
void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr)
476484
{
477-
kvm_multiple_exception(vcpu, nr, false, 0, true);
485+
kvm_multiple_exception(vcpu, nr, false, 0, false, 0, true);
478486
}
479487
EXPORT_SYMBOL_GPL(kvm_requeue_exception);
480488

@@ -521,13 +529,13 @@ EXPORT_SYMBOL_GPL(kvm_inject_nmi);
521529

522530
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
523531
{
524-
kvm_multiple_exception(vcpu, nr, true, error_code, false);
532+
kvm_multiple_exception(vcpu, nr, true, error_code, false, 0, false);
525533
}
526534
EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
527535

528536
void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
529537
{
530-
kvm_multiple_exception(vcpu, nr, true, error_code, true);
538+
kvm_multiple_exception(vcpu, nr, true, error_code, false, 0, true);
531539
}
532540
EXPORT_SYMBOL_GPL(kvm_requeue_exception_e);
533541

0 commit comments

Comments
 (0)