|
@@ -1415,7 +1415,16 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
|
|
|
var->avl = (s->attrib >> SVM_SELECTOR_AVL_SHIFT) & 1;
|
|
|
var->l = (s->attrib >> SVM_SELECTOR_L_SHIFT) & 1;
|
|
|
var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
|
|
|
- var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * AMD CPUs circa 2014 track the G bit for all segments except CS.
|
|
|
+ * However, the SVM spec states that the G bit is not observed by the
|
|
|
+ * CPU, and some VMware virtual CPUs drop the G bit for all segments.
|
|
|
+ * So let's synthesize a legal G bit for all segments, this helps
|
|
|
+ * running KVM nested. It also helps cross-vendor migration, because
|
|
|
+ * Intel's vmentry has a check on the 'G' bit.
|
|
|
+ */
|
|
|
+ var->g = s->limit > 0xfffff;
|
|
|
|
|
|
/*
|
|
|
* AMD's VMCB does not have an explicit unusable field, so emulate it
|
|
@@ -1424,14 +1433,6 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
|
|
|
var->unusable = !var->present || (var->type == 0);
|
|
|
|
|
|
switch (seg) {
|
|
|
- case VCPU_SREG_CS:
|
|
|
- /*
|
|
|
- * SVM always stores 0 for the 'G' bit in the CS selector in
|
|
|
- * the VMCB on a VMEXIT. This hurts cross-vendor migration:
|
|
|
- * Intel's VMENTRY has a check on the 'G' bit.
|
|
|
- */
|
|
|
- var->g = s->limit > 0xfffff;
|
|
|
- break;
|
|
|
case VCPU_SREG_TR:
|
|
|
/*
|
|
|
* Work around a bug where the busy flag in the tr selector
|