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
guest_code(void)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
main(int argc,char * argv[])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