@@ -36,6 +36,7 @@
#include <asm/xstate.h>
#include <asm/debugger.h>
#include <asm/psr.h>
+#include <asm/cpuid.h>
static int gdbsx_guest_mem_io(domid_t domid, struct xen_domctl_gdbsx_memio *iop)
{
@@ -87,6 +88,93 @@ static void update_domain_cpuid_info(struct domain *d,
d->arch.x86_model = (ctl->eax >> 4) & 0xf;
if ( d->arch.x86 >= 0x6 )
d->arch.x86_model |= (ctl->eax >> 12) & 0xf0;
+
+ if ( is_pv_domain(d) )
+ {
+ uint64_t mask = cpuidmask_defaults._1cd;
+ uint32_t ecx = ctl->ecx & pv_featureset[FEATURESET_1c];
+ uint32_t edx = ctl->edx & pv_featureset[FEATURESET_1d];
+
+ switch ( boot_cpu_data.x86_vendor )
+ {
+ case X86_VENDOR_INTEL:
+ mask &= ((uint64_t)edx << 32) | ecx;
+ break;
+
+ case X86_VENDOR_AMD:
+ mask &= ((uint64_t)ecx << 32) | edx;
+ break;
+ }
+
+ d->arch.pv_domain.cpuidmasks->_1cd = mask;
+ }
+ break;
+
+ case 6:
+ if ( is_pv_domain(d) )
+ {
+ uint64_t mask = cpuidmask_defaults._6c;
+
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ mask &= (~0ULL << 32) | ctl->ecx;
+
+ d->arch.pv_domain.cpuidmasks->_6c = mask;
+ }
+ break;
+
+ case 7:
+ if ( ctl->input[1] != 0 )
+ break;
+
+ if ( is_pv_domain(d) )
+ {
+ uint64_t mask = cpuidmask_defaults._7ab0;
+ uint32_t eax = ctl->eax;
+ uint32_t ebx = ctl->ebx & pv_featureset[FEATURESET_7b0];
+
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ mask &= ((uint64_t)eax << 32) | ebx;
+
+ d->arch.pv_domain.cpuidmasks->_7ab0 = mask;
+ }
+ break;
+
+ case 0xd:
+ if ( ctl->input[1] != 1 )
+ break;
+
+ if ( is_pv_domain(d) )
+ {
+ uint64_t mask = cpuidmask_defaults.Da1;
+ uint32_t eax = ctl->eax & pv_featureset[FEATURESET_Da1];
+
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+ mask &= (~0ULL << 32) | eax;
+
+ d->arch.pv_domain.cpuidmasks->Da1 = mask;
+ }
+ break;
+
+ case 0x80000001:
+ if ( is_pv_domain(d) )
+ {
+ uint64_t mask = cpuidmask_defaults.e1cd;
+ uint32_t ecx = ctl->ecx & pv_featureset[FEATURESET_e1c];
+ uint32_t edx = ctl->edx & pv_featureset[FEATURESET_e1d];
+
+ switch ( boot_cpu_data.x86_vendor )
+ {
+ case X86_VENDOR_INTEL:
+ mask &= ((uint64_t)edx << 32) | ecx;
+ break;
+
+ case X86_VENDOR_AMD:
+ mask &= ((uint64_t)ecx << 32) | edx;
+ break;
+ }
+
+ d->arch.pv_domain.cpuidmasks->e1cd = mask;
+ }
break;
}
}