From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: [patch 3/3] KVM: task switch: check for segment base translation failure Date: Sat, 19 Jul 2008 19:08:09 -0300 Message-ID: <20080719220933.000583030@localhost.localdomain> References: <20080719220806.152409866@localhost.localdomain> Cc: kvm@vger.kernel.org, Marcelo Tosatti To: Avi Kivity Return-path: Received: from mx1.redhat.com ([66.187.233.31]:56841 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751604AbYGSWKJ (ORCPT ); Sat, 19 Jul 2008 18:10:09 -0400 Content-Disposition: inline; filename=task-switch-checks-2 Sender: kvm-owner@vger.kernel.org List-ID: Subject says it all. Signed-off-by: Marcelo Tosatti Index: kvm-vmx-checks/arch/x86/kvm/x86.c =================================================================== --- kvm-vmx-checks.orig/arch/x86/kvm/x86.c +++ kvm-vmx-checks/arch/x86/kvm/x86.c @@ -3253,6 +3253,8 @@ static int load_guest_segment_descriptor return 1; } gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); + if (gpa == UNMAPPED_GVA) + return 1; gpa += index * 8; return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8); } @@ -3270,11 +3272,13 @@ static int save_guest_segment_descriptor if (dtable.limit < index * 8 + 7) return 1; gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); + if (gpa == UNMAPPED_GVA) + return 1; gpa += index * 8; return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8); } -static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, +static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu, struct desc_struct *seg_desc) { u32 base_addr; @@ -3446,8 +3450,13 @@ static int kvm_task_switch_16(struct kvm struct desc_struct *nseg_desc) { struct tss_segment_16 tss_segment_16; + gpa_t tss_base; int ret = 0; + tss_base = get_tss_base_addr(vcpu, nseg_desc); + if (tss_base == UNMAPPED_GVA) + goto out; + if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16, sizeof tss_segment_16)) goto out; @@ -3458,8 +3467,8 @@ static int kvm_task_switch_16(struct kvm sizeof tss_segment_16)) goto out; - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), - &tss_segment_16, sizeof tss_segment_16)) + if (kvm_read_guest(vcpu->kvm, tss_base, &tss_segment_16, + sizeof tss_segment_16)) goto out; if (load_state_from_tss16(vcpu, &tss_segment_16)) @@ -3475,8 +3484,13 @@ static int kvm_task_switch_32(struct kvm struct desc_struct *nseg_desc) { struct tss_segment_32 tss_segment_32; + gpa_t tss_base; int ret = 0; + tss_base = get_tss_base_addr(vcpu, nseg_desc); + if (tss_base == UNMAPPED_GVA) + goto out; + if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32, sizeof tss_segment_32)) goto out; @@ -3487,7 +3501,7 @@ static int kvm_task_switch_32(struct kvm sizeof tss_segment_32)) goto out; - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), + if (kvm_read_guest(vcpu->kvm, tss_base, &tss_segment_32, sizeof tss_segment_32)) goto out; @@ -3509,6 +3523,8 @@ int kvm_task_switch(struct kvm_vcpu *vcp u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base); + if (old_tss_base == UNMAPPED_GVA) + return 1; /* FIXME: Handle errors. Failure to read either TSS or their * descriptors should generate a pagefault. --