|
@@ -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;
|