Message ID | 20240723093126.285319-4-schlameuss@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | selftests: kvm: s390: Add s390x ucontrol selftests | expand |
On 7/23/24 11:31, Christoph Schlameuss wrote: > Add test suite to validate the s390x architecture specific ucontrol KVM > interface. > > Make use of the selftest test harness. > > * uc_cap_hpage testcase verifies that a ucontrol VM cannot be run with > hugepages. > > To allow testing of the ucontrol interface the kernel needs a > non-default config containing CONFIG_KVM_S390_UCONTROL. > This config needs to be set to built-in (y) as this cannot be built as > module. > > Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com> > Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> > --- [...] > +#include "kselftest_harness.h" > +#include "kvm_util.h" > + > +#include <linux/capability.h> > +#include <linux/sizes.h> > + > +#define SYS_ADMIN_CAP 0x200000 This looked suspicious to me. Surely this would be available in some form in capability.h since CAP_SYS_ADMIN is something that's regularly checked. [...] > + > +/* so directly declare capget to check caps without libcap */ > +int capget(cap_user_header_t header, cap_user_data_t data); > + > +/** > + * In order to create user controlled virtual machines on S390, > + * check KVM_CAP_S390_UCONTROL and use the flag KVM_VM_S390_UCONTROL > + * as privileged user (SYS_ADMIN). > + */ > +void require_ucontrol_admin(void) > +{ > + struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; > + struct __user_cap_header_struct hdr = { > + .version = _LINUX_CAPABILITY_VERSION_3, > + }; > + int rc; > + > + rc = capget(&hdr, data); > + TEST_ASSERT_EQ(0, rc); > + TEST_REQUIRE((data->effective & SYS_ADMIN_CAP) > 0); And in fact capability.h does have defines which hide the magic constant: data->effective & CAP_TO_MASK(CAP_SYS_ADMIN) > + > + TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_UCONTROL)); > +} > +
On Wed, 24 Jul 2024 16:52:00 +0200 Janosch Frank <frankja@linux.ibm.com> wrote: > On 7/23/24 11:31, Christoph Schlameuss wrote: > > Add test suite to validate the s390x architecture specific ucontrol KVM > > interface. > > > > Make use of the selftest test harness. > > > > * uc_cap_hpage testcase verifies that a ucontrol VM cannot be run with > > hugepages. > > > > To allow testing of the ucontrol interface the kernel needs a > > non-default config containing CONFIG_KVM_S390_UCONTROL. > > This config needs to be set to built-in (y) as this cannot be built as > > module. > > > > Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com> > > Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> > > --- > > [...] > > > +#include "kselftest_harness.h" > > +#include "kvm_util.h" > > + > > +#include <linux/capability.h> > > +#include <linux/sizes.h> > > + > > +#define SYS_ADMIN_CAP 0x200000 > > This looked suspicious to me. > Surely this would be available in some form in capability.h since > CAP_SYS_ADMIN is something that's regularly checked. > > [...] > > > + > > +/* so directly declare capget to check caps without libcap */ > > +int capget(cap_user_header_t header, cap_user_data_t data); > > + > > +/** > > + * In order to create user controlled virtual machines on S390, > > + * check KVM_CAP_S390_UCONTROL and use the flag KVM_VM_S390_UCONTROL > > + * as privileged user (SYS_ADMIN). > > + */ > > +void require_ucontrol_admin(void) > > +{ > > + struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; > > + struct __user_cap_header_struct hdr = { > > + .version = _LINUX_CAPABILITY_VERSION_3, > > + }; > > + int rc; > > + > > + rc = capget(&hdr, data); > > + TEST_ASSERT_EQ(0, rc); > > + TEST_REQUIRE((data->effective & SYS_ADMIN_CAP) > 0); > > And in fact capability.h does have defines which hide the magic constant: > data->effective & CAP_TO_MASK(CAP_SYS_ADMIN) > Yes, thank you, that is much better. Will use that instead and remove the custom SYS_ADMIN_CAP define above. > > + > > + TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_UCONTROL)); > > +} > > + >
diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 6d9381d60172..f2a30a58cd71 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -5,3 +5,4 @@ !*.h !*.S !*.sh +!config diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 48d32c5aa3eb..b3dc0a5bf0d4 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -186,6 +186,7 @@ TEST_GEN_PROGS_s390x += s390x/tprot TEST_GEN_PROGS_s390x += s390x/cmma_test TEST_GEN_PROGS_s390x += s390x/debug_test TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test +TEST_GEN_PROGS_s390x += s390x/ucontrol_test TEST_GEN_PROGS_s390x += demand_paging_test TEST_GEN_PROGS_s390x += dirty_log_test TEST_GEN_PROGS_s390x += guest_print_test diff --git a/tools/testing/selftests/kvm/s390x/config b/tools/testing/selftests/kvm/s390x/config new file mode 100644 index 000000000000..23270f2d679f --- /dev/null +++ b/tools/testing/selftests/kvm/s390x/config @@ -0,0 +1,2 @@ +CONFIG_KVM=y +CONFIG_KVM_S390_UCONTROL=y diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c b/tools/testing/selftests/kvm/s390x/ucontrol_test.c new file mode 100644 index 000000000000..a706a9f2b9ea --- /dev/null +++ b/tools/testing/selftests/kvm/s390x/ucontrol_test.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test code for the s390x kvm ucontrol interface + * + * Copyright IBM Corp. 2024 + * + * Authors: + * Christoph Schlameuss <schlameuss@linux.ibm.com> + */ +#include "kselftest_harness.h" +#include "kvm_util.h" + +#include <linux/capability.h> +#include <linux/sizes.h> + +#define SYS_ADMIN_CAP 0x200000 + +/* so directly declare capget to check caps without libcap */ +int capget(cap_user_header_t header, cap_user_data_t data); + +/** + * In order to create user controlled virtual machines on S390, + * check KVM_CAP_S390_UCONTROL and use the flag KVM_VM_S390_UCONTROL + * as privileged user (SYS_ADMIN). + */ +void require_ucontrol_admin(void) +{ + struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; + struct __user_cap_header_struct hdr = { + .version = _LINUX_CAPABILITY_VERSION_3, + }; + int rc; + + rc = capget(&hdr, data); + TEST_ASSERT_EQ(0, rc); + TEST_REQUIRE((data->effective & SYS_ADMIN_CAP) > 0); + + TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_UCONTROL)); +} + +/** + * Assert HPAGE CAP cannot be enabled on UCONTROL VM + */ +TEST(uc_cap_hpage) +{ + int rc, kvm_fd, vm_fd, vcpu_fd; + struct kvm_enable_cap cap = { + .cap = KVM_CAP_S390_HPAGE_1M, + }; + + require_ucontrol_admin(); + + kvm_fd = open_kvm_dev_path_or_exit(); + vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, KVM_VM_S390_UCONTROL); + ASSERT_GE(vm_fd, 0); + + /* assert hpages are not supported on ucontrol vm */ + rc = ioctl(vm_fd, KVM_CHECK_EXTENSION, KVM_CAP_S390_HPAGE_1M); + EXPECT_EQ(0, rc); + + /* Test that KVM_CAP_S390_HPAGE_1M can't be enabled for a ucontrol vm */ + rc = ioctl(vm_fd, KVM_ENABLE_CAP, cap); + EXPECT_EQ(-1, rc); + EXPECT_EQ(EINVAL, errno); + + /* assert HPAGE CAP is rejected after vCPU creation */ + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0); + ASSERT_GE(vcpu_fd, 0); + rc = ioctl(vm_fd, KVM_ENABLE_CAP, cap); + EXPECT_EQ(-1, rc); + EXPECT_EQ(EBUSY, errno); + + close(vcpu_fd); + close(vm_fd); + close(kvm_fd); +} + +TEST_HARNESS_MAIN