1*85acc29fSMarc Zyngier // SPDX-License-Identifier: GPL-2.0 2*85acc29fSMarc Zyngier 3*85acc29fSMarc Zyngier // Check that nobody has tampered with KVM's UID 4*85acc29fSMarc Zyngier 5*85acc29fSMarc Zyngier #include <errno.h> 6*85acc29fSMarc Zyngier #include <linux/arm-smccc.h> 7*85acc29fSMarc Zyngier #include <asm/kvm.h> 8*85acc29fSMarc Zyngier #include <kvm_util.h> 9*85acc29fSMarc Zyngier 10*85acc29fSMarc Zyngier #include "processor.h" 11*85acc29fSMarc Zyngier 12*85acc29fSMarc Zyngier /* 13*85acc29fSMarc Zyngier * Do NOT redefine these constants, or try to replace them with some 14*85acc29fSMarc Zyngier * "common" version. They are hardcoded here to detect any potential 15*85acc29fSMarc Zyngier * breakage happening in the rest of the kernel. 16*85acc29fSMarc Zyngier * 17*85acc29fSMarc Zyngier * KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 18*85acc29fSMarc Zyngier */ 19*85acc29fSMarc Zyngier #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U 20*85acc29fSMarc Zyngier #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU 21*85acc29fSMarc Zyngier #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U 22*85acc29fSMarc Zyngier #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU 23*85acc29fSMarc Zyngier 24*85acc29fSMarc Zyngier static void guest_code(void) 25*85acc29fSMarc Zyngier { 26*85acc29fSMarc Zyngier struct arm_smccc_res res = {}; 27*85acc29fSMarc Zyngier 28*85acc29fSMarc Zyngier smccc_hvc(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, 0, 0, 0, 0, 0, 0, 0, &res); 29*85acc29fSMarc Zyngier 30*85acc29fSMarc Zyngier __GUEST_ASSERT(res.a0 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 && 31*85acc29fSMarc Zyngier res.a1 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 && 32*85acc29fSMarc Zyngier res.a2 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 && 33*85acc29fSMarc Zyngier res.a3 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3, 34*85acc29fSMarc Zyngier "Unexpected KVM-specific UID %lx %lx %lx %lx\n", res.a0, res.a1, res.a2, res.a3); 35*85acc29fSMarc Zyngier GUEST_DONE(); 36*85acc29fSMarc Zyngier } 37*85acc29fSMarc Zyngier 38*85acc29fSMarc Zyngier int main (int argc, char *argv[]) 39*85acc29fSMarc Zyngier { 40*85acc29fSMarc Zyngier struct kvm_vcpu *vcpu; 41*85acc29fSMarc Zyngier struct kvm_vm *vm; 42*85acc29fSMarc Zyngier struct ucall uc; 43*85acc29fSMarc Zyngier bool guest_done = false; 44*85acc29fSMarc Zyngier 45*85acc29fSMarc Zyngier vm = vm_create_with_one_vcpu(&vcpu, guest_code); 46*85acc29fSMarc Zyngier 47*85acc29fSMarc Zyngier while (!guest_done) { 48*85acc29fSMarc Zyngier vcpu_run(vcpu); 49*85acc29fSMarc Zyngier 50*85acc29fSMarc Zyngier switch (get_ucall(vcpu, &uc)) { 51*85acc29fSMarc Zyngier case UCALL_SYNC: 52*85acc29fSMarc Zyngier break; 53*85acc29fSMarc Zyngier case UCALL_DONE: 54*85acc29fSMarc Zyngier guest_done = true; 55*85acc29fSMarc Zyngier break; 56*85acc29fSMarc Zyngier case UCALL_ABORT: 57*85acc29fSMarc Zyngier REPORT_GUEST_ASSERT(uc); 58*85acc29fSMarc Zyngier break; 59*85acc29fSMarc Zyngier case UCALL_PRINTF: 60*85acc29fSMarc Zyngier printf("%s", uc.buffer); 61*85acc29fSMarc Zyngier break; 62*85acc29fSMarc Zyngier default: 63*85acc29fSMarc Zyngier TEST_FAIL("Unexpected guest exit"); 64*85acc29fSMarc Zyngier } 65*85acc29fSMarc Zyngier } 66*85acc29fSMarc Zyngier 67*85acc29fSMarc Zyngier kvm_vm_free(vm); 68*85acc29fSMarc Zyngier 69*85acc29fSMarc Zyngier return 0; 70*85acc29fSMarc Zyngier } 71