summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichiro Den <den@valinux.co.jp>2026-05-13 11:49:16 +0900
committerBjorn Helgaas <bhelgaas@google.com>2026-06-22 15:31:11 -0500
commit6c39350aaa2d6338ec30ef0a5632b0d6dad856ec (patch)
tree2f58815e1828f127568351b84dae5f2d688e7113
parentf417c400a6683c62cdead42013f60872fda84013 (diff)
PCI: endpoint: pci-epf-vntb: Guard configfs writes after EPC attach
db_count controls how many doorbell slots are allocated and exposed. It is also used by the doorbell mask helpers. After an EPC has been attached, changing it from configfs can leave runtime paths using a different count than the one used to set up the doorbell resources. Reject db_count writes after EPC attach, and reject values outside MIN_DB_COUNT..MAX_DB_COUNT before attach. Now that MIN_DB_COUNT documents the usable doorbell floor, use it in the store path too. While at it, apply the same after-attach guard to the other vNTB configfs knobs. BAR choices, spad_count, memory-window counts and sizes, and the virtual PCI IDs are also consumed during bind, so changing them later at runtime is meaningless and unsafe. Return -EOPNOTSUPP for after-attach writes. The value itself may be valid, but changing it in that state is not supported. Signed-off-by: Koichiro Den <den@valinux.co.jp> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260513024923.451765-6-den@valinux.co.jp
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-vntb.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 818ae5999976..524355a8b4be 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -1020,6 +1020,11 @@ static void epf_ntb_epc_cleanup(struct epf_ntb *ntb)
epf_ntb_config_sspad_bar_clear(ntb);
}
+static bool epf_ntb_epc_attached(struct epf_ntb *ntb)
+{
+ return ntb->epf->epc || ntb->epf->sec_epc;
+}
+
#define EPF_NTB_R(_name) \
static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
char *page) \
@@ -1039,6 +1044,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
u32 val; \
int ret; \
\
+ if (epf_ntb_epc_attached(ntb)) \
+ return -EOPNOTSUPP; \
+ \
ret = kstrtou32(page, 0, &val); \
if (ret) \
return ret; \
@@ -1081,6 +1089,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
u64 val; \
int ret; \
\
+ if (epf_ntb_epc_attached(ntb)) \
+ return -EOPNOTSUPP; \
+ \
ret = kstrtou64(page, 0, &val); \
if (ret) \
return ret; \
@@ -1119,6 +1130,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
int val; \
int ret; \
\
+ if (epf_ntb_epc_attached(ntb)) \
+ return -EOPNOTSUPP; \
+ \
ret = kstrtoint(page, 0, &val); \
if (ret) \
return ret; \
@@ -1139,6 +1153,9 @@ static ssize_t epf_ntb_num_mws_store(struct config_item *item,
u32 val;
int ret;
+ if (epf_ntb_epc_attached(ntb))
+ return -EOPNOTSUPP;
+
ret = kstrtou32(page, 0, &val);
if (ret)
return ret;
@@ -1151,10 +1168,32 @@ static ssize_t epf_ntb_num_mws_store(struct config_item *item,
return len;
}
+static ssize_t epf_ntb_db_count_store(struct config_item *item,
+ const char *page, size_t len)
+{
+ struct config_group *group = to_config_group(item);
+ struct epf_ntb *ntb = to_epf_ntb(group);
+ u32 val;
+ int ret;
+
+ if (epf_ntb_epc_attached(ntb))
+ return -EOPNOTSUPP;
+
+ ret = kstrtou32(page, 0, &val);
+ if (ret)
+ return ret;
+
+ if (val < MIN_DB_COUNT || val > MAX_DB_COUNT)
+ return -EINVAL;
+
+ WRITE_ONCE(ntb->db_count, val);
+
+ return len;
+}
+
EPF_NTB_R(spad_count)
EPF_NTB_W(spad_count)
EPF_NTB_R(db_count)
-EPF_NTB_W(db_count)
EPF_NTB_R(num_mws)
EPF_NTB_R(vbus_number)
EPF_NTB_W(vbus_number)