Created
May 2, 2022 15:14
-
-
Save moio/cab4b5d0f05128ec1a6b8b4be94cafa0 to your computer and use it in GitHub Desktop.
Small program to check effect of https://lore.kernel.org/qemu-devel/20211101054836.21471-1-dirty@apple.com/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// run with | |
// gcc -framework Hypervisor rdtscp_check.c | |
// codesign --force// run with | |
// gcc -framework Hypervisor rdtscp_check.c | |
// codesign --force --sign - --entitlements ./app.entitlements ./a.out | |
// ./a.out | |
// where app.entitlement contains | |
// <?xml version="1.0" encoding="UTF-8"?> | |
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
// <plist version="1.0"> | |
// <dict> | |
// <key>com.apple.security.hypervisor</key> | |
// <true/> | |
// </dict> | |
// </plist> | |
#include <inttypes.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <Hypervisor/hv.h> | |
#include <Hypervisor/hv_vmx.h> | |
#define req(x) { \ | |
hv_return_t ret = (x); \ | |
if (ret != HV_SUCCESS) { \ | |
printf("%s exited with code %d\n", #x, (int)ret); \ | |
exit(1); \ | |
} \ | |
} | |
/* desired control word constrained by hardware/hypervisor capabilities */ | |
static inline uint64_t cap2ctrl(uint64_t cap, uint64_t ctrl) | |
{ | |
return (ctrl | (cap & 0xffffffff)) & (cap >> 32); | |
} | |
int main() { | |
hv_vcpuid_t hvid; | |
req(hv_vm_create(HV_VM_DEFAULT)); | |
printf("Current detection algorithm:\n"); | |
uint64_t cap; | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap)); | |
if (!(cap & CPU_BASED2_RDTSCP)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED2_RDTSCP bit not set)\n"); | |
} | |
else | |
{ | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap)); | |
if (!(cap & CPU_BASED_TSC_OFFSET)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED_TSC_OFFSET bit not set)\n"); | |
} | |
else | |
{ | |
printf("RDTSCP is supported\n"); | |
} | |
} | |
printf("Proposed detection algorithm:\n"); | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap)); | |
if (!(cap2ctrl(cap, CPU_BASED2_RDTSCP) & CPU_BASED2_RDTSCP)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED2_RDTSCP bit not set)\n"); | |
} | |
else | |
{ | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap)); | |
if (!(cap2ctrl(cap, CPU_BASED_TSC_OFFSET) & CPU_BASED_TSC_OFFSET)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED_TSC_OFFSET bit not set)\n"); | |
} | |
else | |
{ | |
printf("RDTSCP is supported\n"); | |
} | |
} | |
return 0; | |
} | |
--sign - --entitlements ./app.entitlements ./a.out | |
// ./a.out | |
// where app.entitlement contains | |
// <?xml version="1.0" encoding="UTF-8"?> | |
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
// <plist version="1.0"> | |
// <dict> | |
// <key>com.apple.security.hypervisor</key> | |
// <true/> | |
// </dict> | |
// </plist> | |
#include <inttypes.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <Hypervisor/hv.h> | |
#include <Hypervisor/hv_vmx.h> | |
#define req(x) { \ | |
hv_return_t ret = (x); \ | |
if (ret != HV_SUCCESS) { \ | |
printf("%s exited with code %d\n", #x, (int)ret); \ | |
exit(1); \ | |
} \ | |
} | |
/* desired control word constrained by hardware/hypervisor capabilities */ | |
static inline uint64_t cap2ctrl(uint64_t cap, uint64_t ctrl) | |
{ | |
return (ctrl | (cap & 0xffffffff)) & (cap >> 32); | |
} | |
int main() { | |
hv_vcpuid_t hvid; | |
req(hv_vm_create(HV_VM_DEFAULT)); | |
printf("Current detection algorithm:\n"); | |
uint64_t cap; | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap)); | |
if (!(cap & CPU_BASED2_RDTSCP)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED2_RDTSCP bit not set)\n"); | |
} | |
else | |
{ | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap)); | |
if (!(cap & CPU_BASED_TSC_OFFSET)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED_TSC_OFFSET bit not set)\n"); | |
} | |
else | |
{ | |
printf("RDTSCP is supported\n"); | |
} | |
} | |
printf("Proposed detection algorithm:\n"); | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap)); | |
if (!(cap2ctrl(cap, CPU_BASED2_RDTSCP) & CPU_BASED2_RDTSCP)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED2_RDTSCP bit not set)\n"); | |
} | |
else | |
{ | |
req(hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap)); | |
if (!(cap2ctrl(cap, CPU_BASED_TSC_OFFSET) & CPU_BASED_TSC_OFFSET)) | |
{ | |
printf("RDTSCP is NOT supported (CPU_BASED_TSC_OFFSET bit not set)\n"); | |
} | |
else | |
{ | |
printf("RDTSCP is supported\n"); | |
} | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment