From c5bf8a0423325b96d7ede271965c117cd3790cde Mon Sep 17 00:00:00 2001
From: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Date: Mon, 1 Feb 2021 07:32:46 -0500
Subject: [PATCH 13/15] lib/vhost: force cpumask to be subset of application's
 CPU mask

Documentation for vhost target states that CPU mask must be a subset
of application CPU mask. This wasn't enforced right now and allowed
the cpumask on controller creation so long as at least single
CPU core overlapped with application's CPU mask.

This might have been misleading and covered up user configuration errors.

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6212 (master)

(cherry picked from commit b74363bcdfb6c0925dd01a24574c4fc82b22e58f)
Change-Id: I03f959ec37efd0be9b98cff9c93c5f996b04af35
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6390
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
---
 lib/vhost/vhost.c                      | 11 +++++++++++
 test/unit/lib/vhost/vhost.c/vhost_ut.c |  4 ++++
 test/vhost/other/negative.sh           | 10 ++++++++++
 3 files changed, 25 insertions(+)

diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
index b3aee72..18c17b3 100644
--- a/lib/vhost/vhost.c
+++ b/lib/vhost/vhost.c
@@ -888,6 +888,7 @@ static int
 vhost_parse_core_mask(const char *mask, struct spdk_cpuset *cpumask)
 {
 	int rc;
+	struct spdk_cpuset negative_vhost_mask;
 
 	if (cpumask == NULL) {
 		return -1;
@@ -904,6 +905,16 @@ vhost_parse_core_mask(const char *mask, struct spdk_cpuset *cpumask)
 		return -1;
 	}
 
+	spdk_cpuset_copy(&negative_vhost_mask, &g_vhost_core_mask);
+	spdk_cpuset_negate(&negative_vhost_mask);
+	spdk_cpuset_and(&negative_vhost_mask, cpumask);
+
+	if (spdk_cpuset_count(&negative_vhost_mask) != 0) {
+		SPDK_ERRLOG("one of selected cpu is outside of core mask(=%s)\n",
+			    spdk_cpuset_fmt(&g_vhost_core_mask));
+		return -1;
+	}
+
 	spdk_cpuset_and(cpumask, &g_vhost_core_mask);
 
 	if (spdk_cpuset_count(cpumask) == 0) {
diff --git a/test/unit/lib/vhost/vhost.c/vhost_ut.c b/test/unit/lib/vhost/vhost.c/vhost_ut.c
index 79a6d20..45ce0a4 100644
--- a/test/unit/lib/vhost/vhost.c/vhost_ut.c
+++ b/test/unit/lib/vhost/vhost.c/vhost_ut.c
@@ -269,6 +269,10 @@ create_controller_test(void)
 
 	spdk_cpuset_set_cpu(&g_vhost_core_mask, 0, true);
 
+ 	/* Create device with incorrect cpumask partially outside of application cpumask */
+ 	ret = alloc_vdev(&vdev, "vdev_name_0", "0xff");
+ 	SPDK_CU_ASSERT_FATAL(ret != 0);
+
 	/* Create device with no name */
 	ret = alloc_vdev(&vdev, NULL, "0x1");
 	CU_ASSERT(ret != 0);
diff --git a/test/vhost/other/negative.sh b/test/vhost/other/negative.sh
index ab7fa9d..2c219e7 100755
--- a/test/vhost/other/negative.sh
+++ b/test/vhost/other/negative.sh
@@ -93,6 +93,11 @@ if $rpc_py vhost_create_scsi_controller vhost.invalid.cpumask --cpumask 0x2; the
 	error "Creating scsi controller with incorrect cpumask succeeded, but it shouldn't"
 fi
 
+notice "Trying to create scsi controller with incorrect cpumask partially outside of application cpumask"
+if $rpc_py vhost_create_scsi_controller vhost.invalid.cpumask --cpumask 0xff; then
+	error "Creating scsi controller with incorrect cpumask succeeded, but it shouldn't"
+fi
+
 notice "Trying to remove device from nonexistent scsi controller"
 if $rpc_py vhost_scsi_controller_remove_target vhost.nonexistent.name 0; then
 	error "Removing device from nonexistent scsi controller succeeded, but it shouldn't"
@@ -172,6 +177,11 @@ if $rpc_py vhost_create_blk_controller vhost.invalid.cpumask Malloc0 --cpumask 0
 	error "Creating block controller with incorrect cpumask succeeded, but it shouldn't"
 fi
 
+notice "Trying to create block controller with incorrect cpumask partially outside of application cpumask"
+if $rpc_py vhost_create_blk_controller vhost.invalid.cpumask Malloc0 --cpumask 0xff; then
+	error "Creating block controller with incorrect cpumask succeeded, but it shouldn't"
+fi
+
 notice "Trying to remove nonexistent block controller"
 if $rpc_py vhost_delete_controller vhost.nonexistent.name; then
 	error "Removing nonexistent block controller succeeded, but it shouldn't"
-- 
1.8.3.1

