lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <27zubyj3yzf2mazuq3ub3xmysizbmlpbrnozi32ha2x2cijzhl@exh23bitrsio>
Date: Thu, 5 Feb 2026 16:01:46 +0900
From: Koichiro Den <den@...inux.co.jp>
To: Frank Li <Frank.li@....com>
Cc: vkoul@...nel.org, mani@...nel.org, jingoohan1@...il.com, 
	lpieralisi@...nel.org, kwilczynski@...nel.org, robh@...nel.org, bhelgaas@...gle.com, 
	dmaengine@...r.kernel.org, linux-pci@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 09/11] PCI: endpoint: pci-epf-test: Add smoke test for
 EPC remote resource API

On Wed, Feb 04, 2026 at 02:37:08PM -0500, Frank Li wrote:
> On Wed, Feb 04, 2026 at 11:54:37PM +0900, Koichiro Den wrote:
> > Add a new pci-epf-test command that exercises the newly added EPC API
> > pci_epc_get_remote_resources().
> >
> > The test is intentionally a smoke test. It verifies that the API either
> > returns -EOPNOTSUPP or a well-formed resource list (non-zero phys/size
> > and known resource types). The result is reported to the host via a
> > status bit and an interrupt, consistent with existing pci-epf-test
> > commands.
> >
> > Signed-off-by: Koichiro Den <den@...inux.co.jp>
> > ---
> >  drivers/pci/endpoint/functions/pci-epf-test.c | 88 +++++++++++++++++++
> >  1 file changed, 88 insertions(+)
> >
> > diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
> > index 6952ee418622..6446a0a23865 100644
> > --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> > @@ -35,6 +35,7 @@
> >  #define COMMAND_DISABLE_DOORBELL	BIT(7)
> >  #define COMMAND_BAR_SUBRANGE_SETUP	BIT(8)
> >  #define COMMAND_BAR_SUBRANGE_CLEAR	BIT(9)
> > +#define COMMAND_EPC_API			BIT(10)
> >
> >  #define STATUS_READ_SUCCESS		BIT(0)
> >  #define STATUS_READ_FAIL		BIT(1)
> > @@ -54,6 +55,8 @@
> >  #define STATUS_BAR_SUBRANGE_SETUP_FAIL		BIT(15)
> >  #define STATUS_BAR_SUBRANGE_CLEAR_SUCCESS	BIT(16)
> >  #define STATUS_BAR_SUBRANGE_CLEAR_FAIL		BIT(17)
> > +#define STATUS_EPC_API_SUCCESS		BIT(18)
> > +#define STATUS_EPC_API_FAIL		BIT(19)
> >
> >  #define FLAG_USE_DMA			BIT(0)
> >
> > @@ -967,6 +970,87 @@ static void pci_epf_test_bar_subrange_clear(struct pci_epf_test *epf_test,
> >  	reg->status = cpu_to_le32(status);
> >  }
> >
> > +static void pci_epf_test_epc_api(struct pci_epf_test *epf_test,
> > +				 struct pci_epf_test_reg *reg)
> > +{
> > +	struct pci_epc_remote_resource *resources = NULL;
> > +	u32 status = le32_to_cpu(reg->status);
> > +	struct pci_epf *epf = epf_test->epf;
> > +	struct device *dev = &epf->dev;
> > +	struct pci_epc *epc = epf->epc;
> > +	int num_resources;
> > +	int ret, i;
> > +
> > +	num_resources = pci_epc_get_remote_resources(epc, epf->func_no,
> > +						     epf->vfunc_no, NULL, 0);
> > +	if (num_resources == -EOPNOTSUPP || num_resources == 0)
> > +		goto out_success;
> > +	if (num_resources < 0)
> > +		goto err;
> > +
> > +	resources = kcalloc(num_resources, sizeof(*resources), GFP_KERNEL);
> 
> use auto cleanup
> 	struct pci_epc_remote_resource *resources __free(kfree) =
> 		kcalloc(num_resources, sizeof(*resources), GFP_KERNEL);

I'll update it, thanks for pointing that out.
> 
> > +	if (!resources)
> > +		goto err;
> > +
> > +	ret = pci_epc_get_remote_resources(epc, epf->func_no, epf->vfunc_no,
> > +					   resources, num_resources);
> > +	if (ret < 0) {
> > +		dev_err(dev, "EPC remote resource query failed: %d\n", ret);
> > +		goto err_free;
> > +	}
> > +	if (ret > num_resources) {
> > +		dev_err(dev, "EPC API returned %d resources (max %d)\n",
> > +			ret, num_resources);
> > +		goto err_free;
> > +	}
> > +
> > +	for (i = 0; i < ret; i++) {
> > +		struct pci_epc_remote_resource *res = &resources[i];
> > +
> > +		if (!res->phys_addr || !res->size) {
> > +			dev_err(dev,
> > +				"Invalid remote resource[%d] (type=%d phys=%pa size=%llu)\n",
> > +				i, res->type, &res->phys_addr, res->size);
> > +			goto err_free;
> > +		}
> > +
> > +		/* Guard against address overflow */
> > +		if (res->phys_addr + res->size < res->phys_addr) {
> > +			dev_err(dev,
> > +				"Remote resource[%d] overflow (phys=%pa size=%llu)\n",
> > +				i, &res->phys_addr, res->size);
> > +			goto err_free;
> > +		}
> > +
> > +		switch (res->type) {
> > +		case PCI_EPC_RR_DMA_CTRL_MMIO:
> > +			/* Generic checks above are sufficient. */
> > +			break;
> > +		case PCI_EPC_RR_DMA_CHAN_DESC:
> > +			/*
> > +			 * hw_chan_id and ep2rc are informational. No extra validation
> > +			 * beyond the generic checks above is needed.
> > +			 */
> > +			break;
> > +		default:
> > +			dev_err(dev, "Unknown remote resource type %d\n", res->type);
> > +			goto err_free;
> 
> can you call subrange to map to one of bar?

Just for the record, BAR_SUBRANGE_TEST has already landed into the tree and
excercises BAR subrange mapping end-to-end.

In my opinion, simply mapping the returned resources into BAR subranges
here would mostly duplicate the existing subrange test unless we also add
host side validation, and some resource types may be MMIO, so I'd prefer to
keep this as a smoke test. If you had a specific failure mode in mind that
is not covered by BAR_SUBRANGE_TEST, please let me know, I can try to add a
targeted check.

Thanks for the review,
Koichiro

> 
> Frank
> > +		}
> > +	}
> > +
> > +out_success:
> > +	kfree(resources);
> > +	status |= STATUS_EPC_API_SUCCESS;
> > +	reg->status = cpu_to_le32(status);
> > +	return;
> > +
> > +err_free:
> > +	kfree(resources);
> > +err:
> > +	status |= STATUS_EPC_API_FAIL;
> > +	reg->status = cpu_to_le32(status);
> > +}
> > +
> >  static void pci_epf_test_cmd_handler(struct work_struct *work)
> >  {
> >  	u32 command;
> > @@ -1030,6 +1114,10 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
> >  		pci_epf_test_bar_subrange_clear(epf_test, reg);
> >  		pci_epf_test_raise_irq(epf_test, reg);
> >  		break;
> > +	case COMMAND_EPC_API:
> > +		pci_epf_test_epc_api(epf_test, reg);
> > +		pci_epf_test_raise_irq(epf_test, reg);
> > +		break;
> >  	default:
> >  		dev_err(dev, "Invalid command 0x%x\n", command);
> >  		break;
> > --
> > 2.51.0
> >

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ