zero_leaves(p->extd.raw, 0xb, 0x18);
p->extd.raw[0x1b] = EMPTY_LEAF; /* IBS - not supported. */
+
+ p->extd.raw[0x1c].a = 0; /* LWP.a entirely dynamic. */
break;
}
}
if ( !p->extd.page1gb )
p->extd.raw[0x19] = EMPTY_LEAF;
+
+ if ( p->extd.lwp )
+ p->extd.raw[0x1c].d &= max->extd.raw[0x1c].d;
+ else
+ p->extd.raw[0x1c] = EMPTY_LEAF;
}
int init_domain_cpuid_policy(struct domain *d)
case 0x00000005: /* MONITOR/MWAIT */
case 0x0000000b: /* Extended Topology Enumeration */
- case 0x8000001c: /* Light Weight Profiling */
unsupported:
*res = EMPTY_LEAF;
break;
case 0x2 ... 0x3:
case 0x7 ... 0x9:
case 0xc ... XSTATE_CPUID:
- case 0x80000000 ... 0x8000001b:
+ case 0x80000000 ... 0x8000001c:
ASSERT_UNREACHABLE();
/* Now handled in guest_cpuid(). */
}
res->a = (res->a & ~0xff) | 3;
break;
- case 0x8000001c:
- if ( !cpu_has_svm )
- {
- *res = EMPTY_LEAF;
- break;
- }
-
- if ( cpu_has_lwp && (v->arch.xcr0 & XSTATE_LWP) )
- /* Turn on available bit and other features specified in lwp_cfg. */
- res->a = (res->d & v->arch.hvm_svm.guest_lwp_cfg) | 1;
- else
- res->a = 0;
- break;
-
case 0x0:
case 0x2 ... 0x3:
case 0x7 ... 0x9:
case 0xc ... XSTATE_CPUID:
- case 0x80000000 ... 0x8000001b:
+ case 0x80000000 ... 0x8000001c:
ASSERT_UNREACHABLE();
/* Now handled in guest_cpuid(). */
}
default:
goto legacy;
- case 0x80000000 ... 0x8000001b:
+ case 0x80000000 ... 0x8000001c:
*res = p->extd.raw[leaf & 0xffff];
break;
}
res->d |= cpufeat_mask(X86_FEATURE_MTRR);
}
break;
+
+ case 0x8000001c:
+ if ( (v->arch.xcr0 & XSTATE_LWP) && cpu_has_svm )
+ /* Turn on available bit and other features specified in lwp_cfg. */
+ res->a = (res->d & v->arch.hvm_svm.guest_lwp_cfg) | 1;
+ break;
}
/* Done. */
if ( xsave_enabled(v) && cpu_has_lwp )
{
- struct cpuid_leaf res;
-
- guest_cpuid(v, 0x8000001c, 0, &res);
msr_low = (uint32_t)msr_content;
/* generate #GP if guest tries to turn on unsupported features. */
- if ( msr_low & ~res.d)
+ if ( msr_low & ~v->domain->arch.cpuid->extd.raw[0x1c].d )
return -1;
v->arch.hvm_svm.guest_lwp_cfg = msr_content;