0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #define _GNU_SOURCE
0014 #include <fcntl.h>
0015 #include <stdio.h>
0016 #include <stdlib.h>
0017 #include <string.h>
0018 #include <sys/ioctl.h>
0019
0020 #include "test_util.h"
0021
0022 #include "kvm_util.h"
0023 #include "processor.h"
0024
0025 static void test_cr4_feature_bit(struct kvm_vcpu *vcpu, struct kvm_sregs *orig,
0026 uint64_t feature_bit)
0027 {
0028 struct kvm_sregs sregs;
0029 int rc;
0030
0031
0032 if (orig->cr4 & feature_bit)
0033 return;
0034
0035 memcpy(&sregs, orig, sizeof(sregs));
0036 sregs.cr4 |= feature_bit;
0037
0038 rc = _vcpu_sregs_set(vcpu, &sregs);
0039 TEST_ASSERT(rc, "KVM allowed unsupported CR4 bit (0x%lx)", feature_bit);
0040
0041
0042 vcpu_sregs_get(vcpu, &sregs);
0043 TEST_ASSERT(!memcmp(&sregs, orig, sizeof(sregs)), "KVM modified sregs");
0044 }
0045
0046 static uint64_t calc_supported_cr4_feature_bits(void)
0047 {
0048 uint64_t cr4;
0049
0050 cr4 = X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE |
0051 X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE | X86_CR4_PGE |
0052 X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT;
0053 if (kvm_cpu_has(X86_FEATURE_UMIP))
0054 cr4 |= X86_CR4_UMIP;
0055 if (kvm_cpu_has(X86_FEATURE_LA57))
0056 cr4 |= X86_CR4_LA57;
0057 if (kvm_cpu_has(X86_FEATURE_VMX))
0058 cr4 |= X86_CR4_VMXE;
0059 if (kvm_cpu_has(X86_FEATURE_SMX))
0060 cr4 |= X86_CR4_SMXE;
0061 if (kvm_cpu_has(X86_FEATURE_FSGSBASE))
0062 cr4 |= X86_CR4_FSGSBASE;
0063 if (kvm_cpu_has(X86_FEATURE_PCID))
0064 cr4 |= X86_CR4_PCIDE;
0065 if (kvm_cpu_has(X86_FEATURE_XSAVE))
0066 cr4 |= X86_CR4_OSXSAVE;
0067 if (kvm_cpu_has(X86_FEATURE_SMEP))
0068 cr4 |= X86_CR4_SMEP;
0069 if (kvm_cpu_has(X86_FEATURE_SMAP))
0070 cr4 |= X86_CR4_SMAP;
0071 if (kvm_cpu_has(X86_FEATURE_PKU))
0072 cr4 |= X86_CR4_PKE;
0073
0074 return cr4;
0075 }
0076
0077 int main(int argc, char *argv[])
0078 {
0079 struct kvm_sregs sregs;
0080 struct kvm_vcpu *vcpu;
0081 struct kvm_vm *vm;
0082 uint64_t cr4;
0083 int rc;
0084
0085
0086 setbuf(stdout, NULL);
0087
0088
0089
0090
0091
0092
0093 vm = vm_create_barebones();
0094 vcpu = __vm_vcpu_add(vm, 0);
0095
0096 vcpu_sregs_get(vcpu, &sregs);
0097
0098 sregs.cr4 |= calc_supported_cr4_feature_bits();
0099 cr4 = sregs.cr4;
0100
0101 rc = _vcpu_sregs_set(vcpu, &sregs);
0102 TEST_ASSERT(!rc, "Failed to set supported CR4 bits (0x%lx)", cr4);
0103
0104 vcpu_sregs_get(vcpu, &sregs);
0105 TEST_ASSERT(sregs.cr4 == cr4, "sregs.CR4 (0x%llx) != CR4 (0x%lx)",
0106 sregs.cr4, cr4);
0107
0108
0109 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_UMIP);
0110 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_LA57);
0111 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_VMXE);
0112 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMXE);
0113 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_FSGSBASE);
0114 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_PCIDE);
0115 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_OSXSAVE);
0116 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMEP);
0117 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMAP);
0118 test_cr4_feature_bit(vcpu, &sregs, X86_CR4_PKE);
0119 kvm_vm_free(vm);
0120
0121
0122 vm = vm_create_with_one_vcpu(&vcpu, NULL);
0123
0124 vcpu_sregs_get(vcpu, &sregs);
0125 sregs.apic_base = 1 << 10;
0126 rc = _vcpu_sregs_set(vcpu, &sregs);
0127 TEST_ASSERT(rc, "Set IA32_APIC_BASE to %llx (invalid)",
0128 sregs.apic_base);
0129 sregs.apic_base = 1 << 11;
0130 rc = _vcpu_sregs_set(vcpu, &sregs);
0131 TEST_ASSERT(!rc, "Couldn't set IA32_APIC_BASE to %llx (valid)",
0132 sregs.apic_base);
0133
0134 kvm_vm_free(vm);
0135
0136 return 0;
0137 }