diff options
author | Avi Kivity <avi@qumranet.com> | 2008-08-20 08:51:42 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:15:21 -0400 |
commit | f4bbd9aaaae23007e4d79536d35a30cbbb11d407 (patch) | |
tree | 95d1624fb9847b246a806ddedca38d00de08f56d /arch/x86/kvm/x86.c | |
parent | a16b20da879430fdf245ed45461ed40ffef8db3c (diff) |
KVM: Load real mode segments correctly
Real mode segments to not reference the GDT or LDT; they simply compute
base = selector * 16.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 22edd95712ee..bfc7c332c5d7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3588,11 +3588,33 @@ static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu, | |||
3588 | return 0; | 3588 | return 0; |
3589 | } | 3589 | } |
3590 | 3590 | ||
3591 | int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) | ||
3592 | { | ||
3593 | struct kvm_segment segvar = { | ||
3594 | .base = selector << 4, | ||
3595 | .limit = 0xffff, | ||
3596 | .selector = selector, | ||
3597 | .type = 3, | ||
3598 | .present = 1, | ||
3599 | .dpl = 3, | ||
3600 | .db = 0, | ||
3601 | .s = 1, | ||
3602 | .l = 0, | ||
3603 | .g = 0, | ||
3604 | .avl = 0, | ||
3605 | .unusable = 0, | ||
3606 | }; | ||
3607 | kvm_x86_ops->set_segment(vcpu, &segvar, seg); | ||
3608 | return 0; | ||
3609 | } | ||
3610 | |||
3591 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 3611 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
3592 | int type_bits, int seg) | 3612 | int type_bits, int seg) |
3593 | { | 3613 | { |
3594 | struct kvm_segment kvm_seg; | 3614 | struct kvm_segment kvm_seg; |
3595 | 3615 | ||
3616 | if (!(vcpu->arch.cr0 & X86_CR0_PE)) | ||
3617 | return kvm_load_realmode_segment(vcpu, selector, seg); | ||
3596 | if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) | 3618 | if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) |
3597 | return 1; | 3619 | return 1; |
3598 | kvm_seg.type |= type_bits; | 3620 | kvm_seg.type |= type_bits; |