aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-07-16 18:07:10 -0400
committerAvi Kivity <avi@qumranet.com>2008-07-27 04:34:09 -0400
commit98899aa0e0bf5de05850082be0eb837058c09ea5 (patch)
tree9e38ae09572b56749c868746fd306dbe6778f3cc /arch/x86/kvm/x86.c
parent5f4cb662a0a2533b45656607471571460310a5ca (diff)
KVM: task switch: segment base is linear address
The segment base is always a linear address, so translate before accessing guest memory. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9f1cdb011cff..cd687395e4e7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3223,6 +3223,7 @@ static void get_segment_descritptor_dtable(struct kvm_vcpu *vcpu,
3223static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, 3223static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3224 struct desc_struct *seg_desc) 3224 struct desc_struct *seg_desc)
3225{ 3225{
3226 gpa_t gpa;
3226 struct descriptor_table dtable; 3227 struct descriptor_table dtable;
3227 u16 index = selector >> 3; 3228 u16 index = selector >> 3;
3228 3229
@@ -3232,13 +3233,16 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3232 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); 3233 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
3233 return 1; 3234 return 1;
3234 } 3235 }
3235 return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); 3236 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
3237 gpa += index * 8;
3238 return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
3236} 3239}
3237 3240
3238/* allowed just for 8 bytes segments */ 3241/* allowed just for 8 bytes segments */
3239static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, 3242static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3240 struct desc_struct *seg_desc) 3243 struct desc_struct *seg_desc)
3241{ 3244{
3245 gpa_t gpa;
3242 struct descriptor_table dtable; 3246 struct descriptor_table dtable;
3243 u16 index = selector >> 3; 3247 u16 index = selector >> 3;
3244 3248
@@ -3246,7 +3250,9 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3246 3250
3247 if (dtable.limit < index * 8 + 7) 3251 if (dtable.limit < index * 8 + 7)
3248 return 1; 3252 return 1;
3249 return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8); 3253 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
3254 gpa += index * 8;
3255 return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
3250} 3256}
3251 3257
3252static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, 3258static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
@@ -3258,7 +3264,7 @@ static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
3258 base_addr |= (seg_desc->base1 << 16); 3264 base_addr |= (seg_desc->base1 << 16);
3259 base_addr |= (seg_desc->base2 << 24); 3265 base_addr |= (seg_desc->base2 << 24);
3260 3266
3261 return base_addr; 3267 return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
3262} 3268}
3263 3269
3264static int load_tss_segment32(struct kvm_vcpu *vcpu, 3270static int load_tss_segment32(struct kvm_vcpu *vcpu,