Skip to content

Commit

Permalink
KVM: x86: emulate #UD while in guest mode
Browse files Browse the repository at this point in the history
This reverts commits ae1f576
and ac9b305.

If the hardware doesn't support MOVBE, but L0 sets CPUID.01H:ECX.MOVBE
in L1's emulated CPUID information, then L1 is likely to pass that
CPUID bit through to L2. L2 will expect MOVBE to work, but if L1
doesn't intercept #UD, then any MOVBE instruction executed in L2 will
raise #UD, and the exception will be delivered in L2.

Commit ac9b305 is a better and more
complete version of ae1f576 ("KVM: nVMX: Do not emulate #UD while
in guest mode"); however, neither considers the above case.

Suggested-by: Jim Mattson <jmattson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Paolo Bonzini committed Jan 11, 2018
1 parent ab271bd commit bd89525
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 12 deletions.
9 changes: 1 addition & 8 deletions arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,6 @@ static void recalc_intercepts(struct vcpu_svm *svm)
{
struct vmcb_control_area *c, *h;
struct nested_state *g;
u32 h_intercept_exceptions;

mark_dirty(svm->vmcb, VMCB_INTERCEPTS);

Expand All @@ -372,14 +371,9 @@ static void recalc_intercepts(struct vcpu_svm *svm)
h = &svm->nested.hsave->control;
g = &svm->nested;

/* No need to intercept #UD if L1 doesn't intercept it */
h_intercept_exceptions =
h->intercept_exceptions & ~(1U << UD_VECTOR);

c->intercept_cr = h->intercept_cr | g->intercept_cr;
c->intercept_dr = h->intercept_dr | g->intercept_dr;
c->intercept_exceptions =
h_intercept_exceptions | g->intercept_exceptions;
c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions;
c->intercept = h->intercept | g->intercept;
}

Expand Down Expand Up @@ -2202,7 +2196,6 @@ static int ud_interception(struct vcpu_svm *svm)
{
int er;

WARN_ON_ONCE(is_guest_mode(&svm->vcpu));
er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD);
if (er == EMULATE_USER_EXIT)
return 0;
Expand Down
5 changes: 1 addition & 4 deletions arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1887,7 +1887,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
{
u32 eb;

eb = (1u << PF_VECTOR) | (1u << MC_VECTOR) |
eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
(1u << DB_VECTOR) | (1u << AC_VECTOR);
if ((vcpu->guest_debug &
(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
Expand All @@ -1905,8 +1905,6 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
*/
if (is_guest_mode(vcpu))
eb |= get_vmcs12(vcpu)->exception_bitmap;
else
eb |= 1u << UD_VECTOR;

vmcs_write32(EXCEPTION_BITMAP, eb);
}
Expand Down Expand Up @@ -5917,7 +5915,6 @@ static int handle_exception(struct kvm_vcpu *vcpu)
return 1; /* already handled by vmx_vcpu_run() */

if (is_invalid_opcode(intr_info)) {
WARN_ON_ONCE(is_guest_mode(vcpu));
er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD);
if (er == EMULATE_USER_EXIT)
return 0;
Expand Down

0 comments on commit bd89525

Please sign in to comment.