aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/vmx.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index b353eaa0a441..e39ebe0b6958 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1042,23 +1042,11 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
1042 var->unusable = (ar >> 16) & 1; 1042 var->unusable = (ar >> 16) & 1;
1043} 1043}
1044 1044
1045static void vmx_set_segment(struct kvm_vcpu *vcpu, 1045static u32 vmx_segment_access_rights(struct kvm_segment *var)
1046 struct kvm_segment *var, int seg)
1047{ 1046{
1048 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1049 u32 ar; 1047 u32 ar;
1050 1048
1051 vmcs_writel(sf->base, var->base); 1049 if (var->unusable)
1052 vmcs_write32(sf->limit, var->limit);
1053 vmcs_write16(sf->selector, var->selector);
1054 if (vcpu->rmode.active && var->s) {
1055 /*
1056 * Hack real-mode segments into vm86 compatibility.
1057 */
1058 if (var->base == 0xffff0000 && var->selector == 0xf000)
1059 vmcs_writel(sf->base, 0xf0000);
1060 ar = 0xf3;
1061 } else if (var->unusable)
1062 ar = 1 << 16; 1050 ar = 1 << 16;
1063 else { 1051 else {
1064 ar = var->type & 15; 1052 ar = var->type & 15;
@@ -1072,6 +1060,35 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
1072 } 1060 }
1073 if (ar == 0) /* a 0 value means unusable */ 1061 if (ar == 0) /* a 0 value means unusable */
1074 ar = AR_UNUSABLE_MASK; 1062 ar = AR_UNUSABLE_MASK;
1063
1064 return ar;
1065}
1066
1067static void vmx_set_segment(struct kvm_vcpu *vcpu,
1068 struct kvm_segment *var, int seg)
1069{
1070 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1071 u32 ar;
1072
1073 if (vcpu->rmode.active && seg == VCPU_SREG_TR) {
1074 vcpu->rmode.tr.selector = var->selector;
1075 vcpu->rmode.tr.base = var->base;
1076 vcpu->rmode.tr.limit = var->limit;
1077 vcpu->rmode.tr.ar = vmx_segment_access_rights(var);
1078 return;
1079 }
1080 vmcs_writel(sf->base, var->base);
1081 vmcs_write32(sf->limit, var->limit);
1082 vmcs_write16(sf->selector, var->selector);
1083 if (vcpu->rmode.active && var->s) {
1084 /*
1085 * Hack real-mode segments into vm86 compatibility.
1086 */
1087 if (var->base == 0xffff0000 && var->selector == 0xf000)
1088 vmcs_writel(sf->base, 0xf0000);
1089 ar = 0xf3;
1090 } else
1091 ar = vmx_segment_access_rights(var);
1075 vmcs_write32(sf->ar_bytes, ar); 1092 vmcs_write32(sf->ar_bytes, ar);
1076} 1093}
1077 1094