aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2011-03-07 07:55:06 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2011-03-17 12:08:33 -0400
commit5601d05b8c340ee2643febc146099325eff187eb (patch)
tree61fb3298bb267eecfd899621cc852114d636de52 /arch/x86/kvm/x86.c
parent831ca6093ca486060721f5c3c74f97b10f3172b9 (diff)
KVM: emulator: Fix io permission checking for 64bit guest
Current implementation truncates upper 32bit of TR base address during IO permission bitmap check. The patch fixes this. Reported-and-tested-by: Francis Moreau <francis.moro@gmail.com> 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.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b9c2b8e6c70c..01f08a65d09b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4162,8 +4162,8 @@ static unsigned long emulator_get_cached_segment_base(int seg,
4162 return get_segment_base(vcpu, seg); 4162 return get_segment_base(vcpu, seg);
4163} 4163}
4164 4164
4165static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg, 4165static bool emulator_get_cached_descriptor(struct desc_struct *desc, u32 *base3,
4166 struct kvm_vcpu *vcpu) 4166 int seg, struct kvm_vcpu *vcpu)
4167{ 4167{
4168 struct kvm_segment var; 4168 struct kvm_segment var;
4169 4169
@@ -4176,6 +4176,10 @@ static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg,
4176 var.limit >>= 12; 4176 var.limit >>= 12;
4177 set_desc_limit(desc, var.limit); 4177 set_desc_limit(desc, var.limit);
4178 set_desc_base(desc, (unsigned long)var.base); 4178 set_desc_base(desc, (unsigned long)var.base);
4179#ifdef CONFIG_X86_64
4180 if (base3)
4181 *base3 = var.base >> 32;
4182#endif
4179 desc->type = var.type; 4183 desc->type = var.type;
4180 desc->s = var.s; 4184 desc->s = var.s;
4181 desc->dpl = var.dpl; 4185 desc->dpl = var.dpl;
@@ -4188,8 +4192,8 @@ static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg,
4188 return true; 4192 return true;
4189} 4193}
4190 4194
4191static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg, 4195static void emulator_set_cached_descriptor(struct desc_struct *desc, u32 base3,
4192 struct kvm_vcpu *vcpu) 4196 int seg, struct kvm_vcpu *vcpu)
4193{ 4197{
4194 struct kvm_segment var; 4198 struct kvm_segment var;
4195 4199
@@ -4197,6 +4201,9 @@ static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg,
4197 kvm_get_segment(vcpu, &var, seg); 4201 kvm_get_segment(vcpu, &var, seg);
4198 4202
4199 var.base = get_desc_base(desc); 4203 var.base = get_desc_base(desc);
4204#ifdef CONFIG_X86_64
4205 var.base |= ((u64)base3) << 32;
4206#endif
4200 var.limit = get_desc_limit(desc); 4207 var.limit = get_desc_limit(desc);
4201 if (desc->g) 4208 if (desc->g)
4202 var.limit = (var.limit << 12) | 0xfff; 4209 var.limit = (var.limit << 12) | 0xfff;