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>
This commit is contained in:
@@ -3588,11 +3588,33 @@ static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg)
|
||||||
|
{
|
||||||
|
struct kvm_segment segvar = {
|
||||||
|
.base = selector << 4,
|
||||||
|
.limit = 0xffff,
|
||||||
|
.selector = selector,
|
||||||
|
.type = 3,
|
||||||
|
.present = 1,
|
||||||
|
.dpl = 3,
|
||||||
|
.db = 0,
|
||||||
|
.s = 1,
|
||||||
|
.l = 0,
|
||||||
|
.g = 0,
|
||||||
|
.avl = 0,
|
||||||
|
.unusable = 0,
|
||||||
|
};
|
||||||
|
kvm_x86_ops->set_segment(vcpu, &segvar, seg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
|
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
|
||||||
int type_bits, int seg)
|
int type_bits, int seg)
|
||||||
{
|
{
|
||||||
struct kvm_segment kvm_seg;
|
struct kvm_segment kvm_seg;
|
||||||
|
|
||||||
|
if (!(vcpu->arch.cr0 & X86_CR0_PE))
|
||||||
|
return kvm_load_realmode_segment(vcpu, selector, seg);
|
||||||
if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
|
if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
|
||||||
return 1;
|
return 1;
|
||||||
kvm_seg.type |= type_bits;
|
kvm_seg.type |= type_bits;
|
||||||
|
Reference in New Issue
Block a user