1*753dcf7aSZeng Guang // SPDX-License-Identifier: GPL-2.0-only
2*753dcf7aSZeng Guang /*
3*753dcf7aSZeng Guang  * maximum APIC ID capability tests
4*753dcf7aSZeng Guang  *
5*753dcf7aSZeng Guang  * Copyright (C) 2022, Intel, Inc.
6*753dcf7aSZeng Guang  *
7*753dcf7aSZeng Guang  * Tests for getting/setting maximum APIC ID capability
8*753dcf7aSZeng Guang  */
9*753dcf7aSZeng Guang 
10*753dcf7aSZeng Guang #include "kvm_util.h"
11*753dcf7aSZeng Guang #include "../lib/kvm_util_internal.h"
12*753dcf7aSZeng Guang 
13*753dcf7aSZeng Guang #define MAX_VCPU_ID	2
14*753dcf7aSZeng Guang 
15*753dcf7aSZeng Guang int main(int argc, char *argv[])
16*753dcf7aSZeng Guang {
17*753dcf7aSZeng Guang 	struct kvm_vm *vm;
18*753dcf7aSZeng Guang 	struct kvm_enable_cap cap = { 0 };
19*753dcf7aSZeng Guang 	int ret;
20*753dcf7aSZeng Guang 
21*753dcf7aSZeng Guang 	vm = vm_create(VM_MODE_DEFAULT, 0, O_RDWR);
22*753dcf7aSZeng Guang 
23*753dcf7aSZeng Guang 	/* Get KVM_CAP_MAX_VCPU_ID cap supported in KVM */
24*753dcf7aSZeng Guang 	ret = vm_check_cap(vm, KVM_CAP_MAX_VCPU_ID);
25*753dcf7aSZeng Guang 
26*753dcf7aSZeng Guang 	/* Try to set KVM_CAP_MAX_VCPU_ID beyond KVM cap */
27*753dcf7aSZeng Guang 	cap.cap = KVM_CAP_MAX_VCPU_ID;
28*753dcf7aSZeng Guang 	cap.args[0] = ret + 1;
29*753dcf7aSZeng Guang 	ret = ioctl(vm->fd, KVM_ENABLE_CAP, &cap);
30*753dcf7aSZeng Guang 	TEST_ASSERT(ret < 0,
31*753dcf7aSZeng Guang 		    "Unexpected success to enable KVM_CAP_MAX_VCPU_ID"
32*753dcf7aSZeng Guang 		    "beyond KVM cap!\n");
33*753dcf7aSZeng Guang 
34*753dcf7aSZeng Guang 	/* Set KVM_CAP_MAX_VCPU_ID */
35*753dcf7aSZeng Guang 	cap.cap = KVM_CAP_MAX_VCPU_ID;
36*753dcf7aSZeng Guang 	cap.args[0] = MAX_VCPU_ID;
37*753dcf7aSZeng Guang 	ret = ioctl(vm->fd, KVM_ENABLE_CAP, &cap);
38*753dcf7aSZeng Guang 	TEST_ASSERT(ret == 0,
39*753dcf7aSZeng Guang 		    "Unexpected failure to enable KVM_CAP_MAX_VCPU_ID!\n");
40*753dcf7aSZeng Guang 
41*753dcf7aSZeng Guang 	/* Try to set KVM_CAP_MAX_VCPU_ID again */
42*753dcf7aSZeng Guang 	cap.args[0] = MAX_VCPU_ID + 1;
43*753dcf7aSZeng Guang 	ret = ioctl(vm->fd, KVM_ENABLE_CAP, &cap);
44*753dcf7aSZeng Guang 	TEST_ASSERT(ret < 0,
45*753dcf7aSZeng Guang 		    "Unexpected success to enable KVM_CAP_MAX_VCPU_ID again\n");
46*753dcf7aSZeng Guang 
47*753dcf7aSZeng Guang 	/* Create vCPU with id beyond KVM_CAP_MAX_VCPU_ID cap*/
48*753dcf7aSZeng Guang 	ret = ioctl(vm->fd, KVM_CREATE_VCPU, MAX_VCPU_ID);
49*753dcf7aSZeng Guang 	TEST_ASSERT(ret < 0,
50*753dcf7aSZeng Guang 		    "Unexpected success in creating a vCPU with VCPU ID out of range\n");
51*753dcf7aSZeng Guang 
52*753dcf7aSZeng Guang 	kvm_vm_free(vm);
53*753dcf7aSZeng Guang 	return 0;
54*753dcf7aSZeng Guang }
55