|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* |
| 3 | + * Test code for the s390x kvm ucontrol interface |
| 4 | + * |
| 5 | + * Copyright IBM Corp. 2024 |
| 6 | + * |
| 7 | + * Authors: |
| 8 | + * Christoph Schlameuss <[email protected]> |
| 9 | + */ |
| 10 | +#include "kselftest_harness.h" |
| 11 | +#include "kvm_util.h" |
| 12 | + |
| 13 | +#include <linux/capability.h> |
| 14 | +#include <linux/sizes.h> |
| 15 | + |
| 16 | +/* so directly declare capget to check caps without libcap */ |
| 17 | +int capget(cap_user_header_t header, cap_user_data_t data); |
| 18 | + |
| 19 | +/** |
| 20 | + * In order to create user controlled virtual machines on S390, |
| 21 | + * check KVM_CAP_S390_UCONTROL and use the flag KVM_VM_S390_UCONTROL |
| 22 | + * as privileged user (SYS_ADMIN). |
| 23 | + */ |
| 24 | +void require_ucontrol_admin(void) |
| 25 | +{ |
| 26 | + struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; |
| 27 | + struct __user_cap_header_struct hdr = { |
| 28 | + .version = _LINUX_CAPABILITY_VERSION_3, |
| 29 | + }; |
| 30 | + int rc; |
| 31 | + |
| 32 | + rc = capget(&hdr, data); |
| 33 | + TEST_ASSERT_EQ(0, rc); |
| 34 | + TEST_REQUIRE((data->effective & CAP_TO_MASK(CAP_SYS_ADMIN)) > 0); |
| 35 | + |
| 36 | + TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_UCONTROL)); |
| 37 | +} |
| 38 | + |
| 39 | +/** |
| 40 | + * Assert HPAGE CAP cannot be enabled on UCONTROL VM |
| 41 | + */ |
| 42 | +TEST(uc_cap_hpage) |
| 43 | +{ |
| 44 | + int rc, kvm_fd, vm_fd, vcpu_fd; |
| 45 | + struct kvm_enable_cap cap = { |
| 46 | + .cap = KVM_CAP_S390_HPAGE_1M, |
| 47 | + }; |
| 48 | + |
| 49 | + require_ucontrol_admin(); |
| 50 | + |
| 51 | + kvm_fd = open_kvm_dev_path_or_exit(); |
| 52 | + vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, KVM_VM_S390_UCONTROL); |
| 53 | + ASSERT_GE(vm_fd, 0); |
| 54 | + |
| 55 | + /* assert hpages are not supported on ucontrol vm */ |
| 56 | + rc = ioctl(vm_fd, KVM_CHECK_EXTENSION, KVM_CAP_S390_HPAGE_1M); |
| 57 | + EXPECT_EQ(0, rc); |
| 58 | + |
| 59 | + /* Test that KVM_CAP_S390_HPAGE_1M can't be enabled for a ucontrol vm */ |
| 60 | + rc = ioctl(vm_fd, KVM_ENABLE_CAP, cap); |
| 61 | + EXPECT_EQ(-1, rc); |
| 62 | + EXPECT_EQ(EINVAL, errno); |
| 63 | + |
| 64 | + /* assert HPAGE CAP is rejected after vCPU creation */ |
| 65 | + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0); |
| 66 | + ASSERT_GE(vcpu_fd, 0); |
| 67 | + rc = ioctl(vm_fd, KVM_ENABLE_CAP, cap); |
| 68 | + EXPECT_EQ(-1, rc); |
| 69 | + EXPECT_EQ(EBUSY, errno); |
| 70 | + |
| 71 | + close(vcpu_fd); |
| 72 | + close(vm_fd); |
| 73 | + close(kvm_fd); |
| 74 | +} |
| 75 | + |
| 76 | +TEST_HARNESS_MAIN |
0 commit comments