diff mbox series

[v2,2/6] selftests: kvm: s390: Add ucontrol flic attr selftests

Message ID 20241216092140.329196-3-schlameuss@linux.ibm.com (mailing list archive)
State New
Headers show
Series selftests: kvm: s390: Reject invalid ioctls on ucontrol VMs | expand

Commit Message

Christoph Schlameuss Dec. 16, 2024, 9:21 a.m. UTC
Add some superficial selftests for the floating interrupt controller
when using ucontrol VMs. These tests are intended to cover very basic
calls only.

Some of the calls may trigger null pointer dereferences on kernels not
containing the fixes in this patch series.

Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
---
 .../selftests/kvm/s390x/ucontrol_test.c       | 148 ++++++++++++++++++
 1 file changed, 148 insertions(+)

Comments

Hariharan Mari Dec. 18, 2024, 3:07 p.m. UTC | #1
On 2024-12-16 10:21, Christoph Schlameuss wrote:
> Add some superficial selftests for the floating interrupt controller
> when using ucontrol VMs. These tests are intended to cover very basic
> calls only.
> 
> Some of the calls may trigger null pointer dereferences on kernels not
> containing the fixes in this patch series.
> 
> Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>

Tested-by: Hariharan Mari <hari55@linux.ibm.com>
> ---
>  .../selftests/kvm/s390x/ucontrol_test.c       | 148 ++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> index 0c112319dab1..b003abda8495 100644
> --- a/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> +++ b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> @@ -635,4 +635,152 @@ TEST_F(uc_kvm, uc_skey)
>  	uc_assert_diag44(self);
>  }
> 
> +static char uc_flic_b[PAGE_SIZE];
> +static struct kvm_s390_io_adapter uc_flic_ioa = { .id = 0 };
> +static struct kvm_s390_io_adapter_req uc_flic_ioam = { .id = 0 };
> +static struct kvm_s390_ais_req uc_flic_asim = { .isc = 0 };
> +static struct kvm_s390_ais_all uc_flic_asima = { .simm = 0 };
> +static struct uc_flic_attr_test {
> +	char *name;
> +	struct kvm_device_attr a;
> +	int hasrc;
> +	int geterrno;
> +	int seterrno;
> +} uc_flic_attr_tests[] = {
> +	{
> +		.name = "KVM_DEV_FLIC_GET_ALL_IRQS",
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_GET_ALL_IRQS,
> +			.addr = (u64)&uc_flic_b,
> +			.attr = PAGE_SIZE,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ENQUEUE",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_ENQUEUE, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_CLEAR_IRQS",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_CLEAR_IRQS, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ADAPTER_REGISTER",
> +		.geterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_ADAPTER_REGISTER,
> +			.addr = (u64)&uc_flic_ioa,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ADAPTER_MODIFY",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_ADAPTER_MODIFY,
> +			.addr = (u64)&uc_flic_ioam,
> +			.attr = sizeof(uc_flic_ioam),
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_CLEAR_IO_IRQ",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_CLEAR_IO_IRQ,
> +			.attr = 32,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AISM",
> +		.geterrno = EINVAL,
> +		.seterrno = ENOTSUP,
> +		.a = {
> +			.group = KVM_DEV_FLIC_AISM,
> +			.addr = (u64)&uc_flic_asim,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AIRQ_INJECT",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_AIRQ_INJECT, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AISM_ALL",
> +		.geterrno = ENOTSUP,
> +		.seterrno = ENOTSUP,
> +		.a = {
> +			.group = KVM_DEV_FLIC_AISM_ALL,
> +			.addr = (u64)&uc_flic_asima,
> +			.attr = sizeof(uc_flic_asima),
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_APF_ENABLE",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_APF_ENABLE, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_APF_DISABLE_WAIT",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_APF_DISABLE_WAIT, },
> +	},
> +};
> +
> +TEST_F(uc_kvm, uc_flic_attrs)
> +{
> +	struct kvm_create_device cd = { .type = KVM_DEV_TYPE_FLIC };
> +	struct kvm_device_attr attr;
> +	u64 value;
> +	int rc, i;
> +
> +	rc = ioctl(self->vm_fd, KVM_CREATE_DEVICE, &cd);
> +	ASSERT_EQ(0, rc) TH_LOG("create device failed with err %s (%i)",
> +				strerror(errno), errno);
> +
> +	for (i = 0; i < ARRAY_SIZE(uc_flic_attr_tests); i++) {
> +		TH_LOG("test %s", uc_flic_attr_tests[i].name);
> +		attr = (struct kvm_device_attr) {
> +			.group = uc_flic_attr_tests[i].a.group,
> +			.attr = uc_flic_attr_tests[i].a.attr,
> +			.addr = uc_flic_attr_tests[i].a.addr,
> +		};
> +		if (attr.addr == 0)
> +			attr.addr = (u64)&value;
> +
> +		rc = ioctl(cd.fd, KVM_HAS_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(uc_flic_attr_tests[i].hasrc, !!rc)
> +			TH_LOG("expected dev attr missing %s",
> +			       uc_flic_attr_tests[i].name);
> +
> +		rc = ioctl(cd.fd, KVM_GET_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(!!uc_flic_attr_tests[i].geterrno, !!rc)
> +			TH_LOG("get dev attr rc not expected on %s %s (%i)",
> +			       uc_flic_attr_tests[i].name,
> +			       strerror(errno), errno);
> +		if (uc_flic_attr_tests[i].geterrno)
> +			EXPECT_EQ(uc_flic_attr_tests[i].geterrno, errno)
> +				TH_LOG("get dev attr errno not expected on %s %s (%i)",
> +				       uc_flic_attr_tests[i].name,
> +				       strerror(errno), errno);
> +
> +		rc = ioctl(cd.fd, KVM_SET_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(!!uc_flic_attr_tests[i].seterrno, !!rc)
> +			TH_LOG("set sev attr rc not expected on %s %s (%i)",
> +			       uc_flic_attr_tests[i].name,
> +			       strerror(errno), errno);
> +		if (uc_flic_attr_tests[i].seterrno)
> +			EXPECT_EQ(uc_flic_attr_tests[i].seterrno, errno)
> +				TH_LOG("set dev attr errno not expected on %s %s (%i)",
> +				       uc_flic_attr_tests[i].name,
> +				       strerror(errno), errno);
> +	}
> +
> +	close(cd.fd);
> +}
> +
>  TEST_HARNESS_MAIN
Hariharan Mari Dec. 19, 2024, 3:52 p.m. UTC | #2
On 2024-12-16 10:21, Christoph Schlameuss wrote:
> Add some superficial selftests for the floating interrupt controller
> when using ucontrol VMs. These tests are intended to cover very basic
> calls only.
> 
> Some of the calls may trigger null pointer dereferences on kernels not
> containing the fixes in this patch series.
> 
> Signed-off-by: Christoph Schlameuss <schlameuss@linux.ibm.com>

Reviewed-by: Hariharan Mari <hari55@linux.ibm.com>
> ---
>  .../selftests/kvm/s390x/ucontrol_test.c       | 148 ++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> index 0c112319dab1..b003abda8495 100644
> --- a/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> +++ b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
> @@ -635,4 +635,152 @@ TEST_F(uc_kvm, uc_skey)
>  	uc_assert_diag44(self);
>  }
> 
> +static char uc_flic_b[PAGE_SIZE];
> +static struct kvm_s390_io_adapter uc_flic_ioa = { .id = 0 };
> +static struct kvm_s390_io_adapter_req uc_flic_ioam = { .id = 0 };
> +static struct kvm_s390_ais_req uc_flic_asim = { .isc = 0 };
> +static struct kvm_s390_ais_all uc_flic_asima = { .simm = 0 };
> +static struct uc_flic_attr_test {
> +	char *name;
> +	struct kvm_device_attr a;
> +	int hasrc;
> +	int geterrno;
> +	int seterrno;
> +} uc_flic_attr_tests[] = {
> +	{
> +		.name = "KVM_DEV_FLIC_GET_ALL_IRQS",
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_GET_ALL_IRQS,
> +			.addr = (u64)&uc_flic_b,
> +			.attr = PAGE_SIZE,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ENQUEUE",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_ENQUEUE, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_CLEAR_IRQS",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_CLEAR_IRQS, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ADAPTER_REGISTER",
> +		.geterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_ADAPTER_REGISTER,
> +			.addr = (u64)&uc_flic_ioa,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_ADAPTER_MODIFY",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_ADAPTER_MODIFY,
> +			.addr = (u64)&uc_flic_ioam,
> +			.attr = sizeof(uc_flic_ioam),
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_CLEAR_IO_IRQ",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = {
> +			.group = KVM_DEV_FLIC_CLEAR_IO_IRQ,
> +			.attr = 32,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AISM",
> +		.geterrno = EINVAL,
> +		.seterrno = ENOTSUP,
> +		.a = {
> +			.group = KVM_DEV_FLIC_AISM,
> +			.addr = (u64)&uc_flic_asim,
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AIRQ_INJECT",
> +		.geterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_AIRQ_INJECT, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_AISM_ALL",
> +		.geterrno = ENOTSUP,
> +		.seterrno = ENOTSUP,
> +		.a = {
> +			.group = KVM_DEV_FLIC_AISM_ALL,
> +			.addr = (u64)&uc_flic_asima,
> +			.attr = sizeof(uc_flic_asima),
> +		},
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_APF_ENABLE",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_APF_ENABLE, },
> +	},
> +	{
> +		.name = "KVM_DEV_FLIC_APF_DISABLE_WAIT",
> +		.geterrno = EINVAL,
> +		.seterrno = EINVAL,
> +		.a = { .group = KVM_DEV_FLIC_APF_DISABLE_WAIT, },
> +	},
> +};
> +
> +TEST_F(uc_kvm, uc_flic_attrs)
> +{
> +	struct kvm_create_device cd = { .type = KVM_DEV_TYPE_FLIC };
> +	struct kvm_device_attr attr;
> +	u64 value;
> +	int rc, i;
> +
> +	rc = ioctl(self->vm_fd, KVM_CREATE_DEVICE, &cd);
> +	ASSERT_EQ(0, rc) TH_LOG("create device failed with err %s (%i)",
> +				strerror(errno), errno);
> +
> +	for (i = 0; i < ARRAY_SIZE(uc_flic_attr_tests); i++) {
> +		TH_LOG("test %s", uc_flic_attr_tests[i].name);
> +		attr = (struct kvm_device_attr) {
> +			.group = uc_flic_attr_tests[i].a.group,
> +			.attr = uc_flic_attr_tests[i].a.attr,
> +			.addr = uc_flic_attr_tests[i].a.addr,
> +		};
> +		if (attr.addr == 0)
> +			attr.addr = (u64)&value;
> +
> +		rc = ioctl(cd.fd, KVM_HAS_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(uc_flic_attr_tests[i].hasrc, !!rc)
> +			TH_LOG("expected dev attr missing %s",
> +			       uc_flic_attr_tests[i].name);
> +
> +		rc = ioctl(cd.fd, KVM_GET_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(!!uc_flic_attr_tests[i].geterrno, !!rc)
> +			TH_LOG("get dev attr rc not expected on %s %s (%i)",
> +			       uc_flic_attr_tests[i].name,
> +			       strerror(errno), errno);
> +		if (uc_flic_attr_tests[i].geterrno)
> +			EXPECT_EQ(uc_flic_attr_tests[i].geterrno, errno)
> +				TH_LOG("get dev attr errno not expected on %s %s (%i)",
> +				       uc_flic_attr_tests[i].name,
> +				       strerror(errno), errno);
> +
> +		rc = ioctl(cd.fd, KVM_SET_DEVICE_ATTR, &attr);
> +		EXPECT_EQ(!!uc_flic_attr_tests[i].seterrno, !!rc)
> +			TH_LOG("set sev attr rc not expected on %s %s (%i)",
> +			       uc_flic_attr_tests[i].name,
> +			       strerror(errno), errno);
> +		if (uc_flic_attr_tests[i].seterrno)
> +			EXPECT_EQ(uc_flic_attr_tests[i].seterrno, errno)
> +				TH_LOG("set dev attr errno not expected on %s %s (%i)",
> +				       uc_flic_attr_tests[i].name,
> +				       strerror(errno), errno);
> +	}
> +
> +	close(cd.fd);
> +}
> +
>  TEST_HARNESS_MAIN
diff mbox series

Patch

diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
index 0c112319dab1..b003abda8495 100644
--- a/tools/testing/selftests/kvm/s390x/ucontrol_test.c
+++ b/tools/testing/selftests/kvm/s390x/ucontrol_test.c
@@ -635,4 +635,152 @@  TEST_F(uc_kvm, uc_skey)
 	uc_assert_diag44(self);
 }
 
+static char uc_flic_b[PAGE_SIZE];
+static struct kvm_s390_io_adapter uc_flic_ioa = { .id = 0 };
+static struct kvm_s390_io_adapter_req uc_flic_ioam = { .id = 0 };
+static struct kvm_s390_ais_req uc_flic_asim = { .isc = 0 };
+static struct kvm_s390_ais_all uc_flic_asima = { .simm = 0 };
+static struct uc_flic_attr_test {
+	char *name;
+	struct kvm_device_attr a;
+	int hasrc;
+	int geterrno;
+	int seterrno;
+} uc_flic_attr_tests[] = {
+	{
+		.name = "KVM_DEV_FLIC_GET_ALL_IRQS",
+		.seterrno = EINVAL,
+		.a = {
+			.group = KVM_DEV_FLIC_GET_ALL_IRQS,
+			.addr = (u64)&uc_flic_b,
+			.attr = PAGE_SIZE,
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_ENQUEUE",
+		.geterrno = EINVAL,
+		.a = { .group = KVM_DEV_FLIC_ENQUEUE, },
+	},
+	{
+		.name = "KVM_DEV_FLIC_CLEAR_IRQS",
+		.geterrno = EINVAL,
+		.a = { .group = KVM_DEV_FLIC_CLEAR_IRQS, },
+	},
+	{
+		.name = "KVM_DEV_FLIC_ADAPTER_REGISTER",
+		.geterrno = EINVAL,
+		.a = {
+			.group = KVM_DEV_FLIC_ADAPTER_REGISTER,
+			.addr = (u64)&uc_flic_ioa,
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_ADAPTER_MODIFY",
+		.geterrno = EINVAL,
+		.seterrno = EINVAL,
+		.a = {
+			.group = KVM_DEV_FLIC_ADAPTER_MODIFY,
+			.addr = (u64)&uc_flic_ioam,
+			.attr = sizeof(uc_flic_ioam),
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_CLEAR_IO_IRQ",
+		.geterrno = EINVAL,
+		.seterrno = EINVAL,
+		.a = {
+			.group = KVM_DEV_FLIC_CLEAR_IO_IRQ,
+			.attr = 32,
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_AISM",
+		.geterrno = EINVAL,
+		.seterrno = ENOTSUP,
+		.a = {
+			.group = KVM_DEV_FLIC_AISM,
+			.addr = (u64)&uc_flic_asim,
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_AIRQ_INJECT",
+		.geterrno = EINVAL,
+		.a = { .group = KVM_DEV_FLIC_AIRQ_INJECT, },
+	},
+	{
+		.name = "KVM_DEV_FLIC_AISM_ALL",
+		.geterrno = ENOTSUP,
+		.seterrno = ENOTSUP,
+		.a = {
+			.group = KVM_DEV_FLIC_AISM_ALL,
+			.addr = (u64)&uc_flic_asima,
+			.attr = sizeof(uc_flic_asima),
+		},
+	},
+	{
+		.name = "KVM_DEV_FLIC_APF_ENABLE",
+		.geterrno = EINVAL,
+		.seterrno = EINVAL,
+		.a = { .group = KVM_DEV_FLIC_APF_ENABLE, },
+	},
+	{
+		.name = "KVM_DEV_FLIC_APF_DISABLE_WAIT",
+		.geterrno = EINVAL,
+		.seterrno = EINVAL,
+		.a = { .group = KVM_DEV_FLIC_APF_DISABLE_WAIT, },
+	},
+};
+
+TEST_F(uc_kvm, uc_flic_attrs)
+{
+	struct kvm_create_device cd = { .type = KVM_DEV_TYPE_FLIC };
+	struct kvm_device_attr attr;
+	u64 value;
+	int rc, i;
+
+	rc = ioctl(self->vm_fd, KVM_CREATE_DEVICE, &cd);
+	ASSERT_EQ(0, rc) TH_LOG("create device failed with err %s (%i)",
+				strerror(errno), errno);
+
+	for (i = 0; i < ARRAY_SIZE(uc_flic_attr_tests); i++) {
+		TH_LOG("test %s", uc_flic_attr_tests[i].name);
+		attr = (struct kvm_device_attr) {
+			.group = uc_flic_attr_tests[i].a.group,
+			.attr = uc_flic_attr_tests[i].a.attr,
+			.addr = uc_flic_attr_tests[i].a.addr,
+		};
+		if (attr.addr == 0)
+			attr.addr = (u64)&value;
+
+		rc = ioctl(cd.fd, KVM_HAS_DEVICE_ATTR, &attr);
+		EXPECT_EQ(uc_flic_attr_tests[i].hasrc, !!rc)
+			TH_LOG("expected dev attr missing %s",
+			       uc_flic_attr_tests[i].name);
+
+		rc = ioctl(cd.fd, KVM_GET_DEVICE_ATTR, &attr);
+		EXPECT_EQ(!!uc_flic_attr_tests[i].geterrno, !!rc)
+			TH_LOG("get dev attr rc not expected on %s %s (%i)",
+			       uc_flic_attr_tests[i].name,
+			       strerror(errno), errno);
+		if (uc_flic_attr_tests[i].geterrno)
+			EXPECT_EQ(uc_flic_attr_tests[i].geterrno, errno)
+				TH_LOG("get dev attr errno not expected on %s %s (%i)",
+				       uc_flic_attr_tests[i].name,
+				       strerror(errno), errno);
+
+		rc = ioctl(cd.fd, KVM_SET_DEVICE_ATTR, &attr);
+		EXPECT_EQ(!!uc_flic_attr_tests[i].seterrno, !!rc)
+			TH_LOG("set sev attr rc not expected on %s %s (%i)",
+			       uc_flic_attr_tests[i].name,
+			       strerror(errno), errno);
+		if (uc_flic_attr_tests[i].seterrno)
+			EXPECT_EQ(uc_flic_attr_tests[i].seterrno, errno)
+				TH_LOG("set dev attr errno not expected on %s %s (%i)",
+				       uc_flic_attr_tests[i].name,
+				       strerror(errno), errno);
+	}
+
+	close(cd.fd);
+}
+
 TEST_HARNESS_MAIN