diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-07-16 18:07:10 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-27 04:34:09 -0400 |
commit | 98899aa0e0bf5de05850082be0eb837058c09ea5 (patch) | |
tree | 9e38ae09572b56749c868746fd306dbe6778f3cc /arch/x86/kvm/x86.c | |
parent | 5f4cb662a0a2533b45656607471571460310a5ca (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.c | 12 |
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, | |||
3223 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 3223 | static 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 */ |
3239 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 3242 | static 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 | ||
3252 | static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, | 3258 | static 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 | ||
3264 | static int load_tss_segment32(struct kvm_vcpu *vcpu, | 3270 | static int load_tss_segment32(struct kvm_vcpu *vcpu, |