Skip to content

Commit

Permalink
KVM/X86: Use kvm_vcpu_map in emulator_cmpxchg_emulated
Browse files Browse the repository at this point in the history
Use kvm_vcpu_map in emulator_cmpxchg_emulated since using
kvm_vcpu_gpa_to_page() and kmap() will only work for guest memory that has
a "struct page".

Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
Reviewed-by: Konrad Rzeszutek Wilk <kjonrad.wilk@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
KarimAllah Ahmed authored and Paolo Bonzini committed Apr 30, 2019
1 parent 3278e04 commit 42e35f8
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -5557,9 +5557,9 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
unsigned int bytes,
struct x86_exception *exception)
{
struct kvm_host_map map;
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
gpa_t gpa;
struct page *page;
char *kaddr;
bool exchanged;

Expand All @@ -5576,12 +5576,11 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK))
goto emul_write;

page = kvm_vcpu_gfn_to_page(vcpu, gpa >> PAGE_SHIFT);
if (is_error_page(page))
if (kvm_vcpu_map(vcpu, gpa_to_gfn(gpa), &map))
goto emul_write;

kaddr = kmap_atomic(page);
kaddr += offset_in_page(gpa);
kaddr = map.hva + offset_in_page(gpa);

switch (bytes) {
case 1:
exchanged = CMPXCHG_TYPE(u8, kaddr, old, new);
Expand All @@ -5598,13 +5597,12 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
default:
BUG();
}
kunmap_atomic(kaddr);
kvm_release_page_dirty(page);

kvm_vcpu_unmap(vcpu, &map, true);

if (!exchanged)
return X86EMUL_CMPXCHG_FAILED;

kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
kvm_page_track_write(vcpu, gpa, new, bytes);

return X86EMUL_CONTINUE;
Expand Down

0 comments on commit 42e35f8

Please sign in to comment.