aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2010-02-18 05:15:00 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:36:13 -0500
commit6f550484a15ea1b468665cdf59f020bf08ccb292 (patch)
treed4088b1aa157dca4dadc2a99969299dc46098148 /arch/x86/kvm/x86.c
parent8b9f44140bc4afd2698413cd9960c3912168ee91 (diff)
KVM: Fix load_guest_segment_descriptor() to inject page fault
This patch injects page fault when reading descriptor in load_guest_segment_descriptor() fails with FAULT. Effects of this injection: This function is used by kvm_load_segment_descriptor() which is necessary for the following instructions: - mov seg,r/m16 - jmp far - pop ?s This patch makes it possible to emulate the page faults generated by these instructions. But be sure that unless we change the kvm_load_segment_descriptor()'s ret value propagation this patch has no effect. Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f6ae4875d9d0..203ee7d0ed58 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4713,6 +4713,9 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
4713{ 4713{
4714 struct descriptor_table dtable; 4714 struct descriptor_table dtable;
4715 u16 index = selector >> 3; 4715 u16 index = selector >> 3;
4716 int ret;
4717 u32 err;
4718 gva_t addr;
4716 4719
4717 get_segment_descriptor_dtable(vcpu, selector, &dtable); 4720 get_segment_descriptor_dtable(vcpu, selector, &dtable);
4718 4721
@@ -4720,9 +4723,13 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
4720 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); 4723 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
4721 return X86EMUL_PROPAGATE_FAULT; 4724 return X86EMUL_PROPAGATE_FAULT;
4722 } 4725 }
4723 return kvm_read_guest_virt_system(dtable.base + index*8, 4726 addr = dtable.base + index * 8;
4724 seg_desc, sizeof(*seg_desc), 4727 ret = kvm_read_guest_virt_system(addr, seg_desc, sizeof(*seg_desc),
4725 vcpu, NULL); 4728 vcpu, &err);
4729 if (ret == X86EMUL_PROPAGATE_FAULT)
4730 kvm_inject_page_fault(vcpu, addr, err);
4731
4732 return ret;
4726} 4733}
4727 4734
4728/* allowed just for 8 bytes segments */ 4735/* allowed just for 8 bytes segments */