All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
@ 2023-04-14 12:39 ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Shunsuke Mie, Frank Li, Jon Mason, Randy Dunlap,
	Ren Zhijie, linux-kernel, linux-pci, virtualization

PCIe endpoint framework provides APIs to implement PCIe endpoint function.
This framework allows defining various PCIe endpoint function behaviors in
software. This patch extend the framework for virtio pci device. The
virtio is defined to communicate guest on virtual machine and host side.
Advantage of the virtio is the efficiency of data transfer and the conciseness
of implementation device using software. It also be applied to PCIe
endpoint function.

We designed and implemented a PCIe EP virtio console function driver using
the extended PCIe endpoint framework for virtio. It can be communicate
host and endpoint over virtio as console.

An architecture of the function driver is following:

 ┌────────────┐         ┌──────────────────────┬────────────┐
 │virtio      │         │                      │virtio      │
 │console drv │         ├───────────────┐      │console drv │
 ├────────────┤         │(virtio console│      ├────────────┤
 │ virtio bus │         │ device)       │◄────►│ virtio bus │
 ├────────────┤         ├---------------┤      └────────────┤
 │            │         │ pci ep virtio │                   │
 │  pci bus   │         │  console drv  │                   │
 │            │  pcie   ├───────────────┤                   │
 │            │ ◄─────► │  pci ep Bus   │                   │
 └────────────┘         └───────────────┴───────────────────┘
   PCIe Root              PCIe Endpoint

Introduced driver is `pci ep virtio console drv` in the figure. It works
as ep function for PCIe root and virtual virtio console device for PCIe
endpoint. Each side of virtio console driver has virtqueue, and
introduced driver transfers data on the virtqueue to each other. A data
on root tx queue is transfered to endpoint rx queue and vice versa.

This patchset is depend follwing patches which are under discussion.

- [RFC PATCH 0/3] Deal with alignment restriction on EP side
link: https://lore.kernel.org/linux-pci/20230113090350.1103494-1-mie@igel.co.jp/
- [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
link: https://lore.kernel.org/virtualization/20230202090934.549556-1-mie@igel.co.jp/

First of this patchset is introduce a helper function to realize pci
virtio function using PCIe endpoint framework. The second one is adding
a missing definition for virtio pci header. The last one is for PCIe
endpoint virtio console driver.

This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.

Shunsuke Mie (3):
  PCI: endpoint: introduce a helper to implement pci ep virtio function
  virtio_pci: add a definition of queue flag in ISR
  PCI: endpoint: Add EP function driver to provide virtio-console
    functionality

 drivers/pci/endpoint/functions/Kconfig        |  19 +
 drivers/pci/endpoint/functions/Makefile       |   2 +
 drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
 include/uapi/linux/virtio_pci.h               |   3 +
 6 files changed, 1170 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
@ 2023-04-14 12:39 ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam, Frank Li,
	linux-kernel, virtualization, Ren Zhijie, Shunsuke Mie,
	Jon Mason, Bjorn Helgaas

PCIe endpoint framework provides APIs to implement PCIe endpoint function.
This framework allows defining various PCIe endpoint function behaviors in
software. This patch extend the framework for virtio pci device. The
virtio is defined to communicate guest on virtual machine and host side.
Advantage of the virtio is the efficiency of data transfer and the conciseness
of implementation device using software. It also be applied to PCIe
endpoint function.

We designed and implemented a PCIe EP virtio console function driver using
the extended PCIe endpoint framework for virtio. It can be communicate
host and endpoint over virtio as console.

An architecture of the function driver is following:

 ┌────────────┐         ┌──────────────────────┬────────────┐
 │virtio      │         │                      │virtio      │
 │console drv │         ├───────────────┐      │console drv │
 ├────────────┤         │(virtio console│      ├────────────┤
 │ virtio bus │         │ device)       │◄────►│ virtio bus │
 ├────────────┤         ├---------------┤      └────────────┤
 │            │         │ pci ep virtio │                   │
 │  pci bus   │         │  console drv  │                   │
 │            │  pcie   ├───────────────┤                   │
 │            │ ◄─────► │  pci ep Bus   │                   │
 └────────────┘         └───────────────┴───────────────────┘
   PCIe Root              PCIe Endpoint

Introduced driver is `pci ep virtio console drv` in the figure. It works
as ep function for PCIe root and virtual virtio console device for PCIe
endpoint. Each side of virtio console driver has virtqueue, and
introduced driver transfers data on the virtqueue to each other. A data
on root tx queue is transfered to endpoint rx queue and vice versa.

This patchset is depend follwing patches which are under discussion.

- [RFC PATCH 0/3] Deal with alignment restriction on EP side
link: https://lore.kernel.org/linux-pci/20230113090350.1103494-1-mie@igel.co.jp/
- [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
link: https://lore.kernel.org/virtualization/20230202090934.549556-1-mie@igel.co.jp/

First of this patchset is introduce a helper function to realize pci
virtio function using PCIe endpoint framework. The second one is adding
a missing definition for virtio pci header. The last one is for PCIe
endpoint virtio console driver.

This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.

Shunsuke Mie (3):
  PCI: endpoint: introduce a helper to implement pci ep virtio function
  virtio_pci: add a definition of queue flag in ISR
  PCI: endpoint: Add EP function driver to provide virtio-console
    functionality

 drivers/pci/endpoint/functions/Kconfig        |  19 +
 drivers/pci/endpoint/functions/Makefile       |   2 +
 drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
 include/uapi/linux/virtio_pci.h               |   3 +
 6 files changed, 1170 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h

-- 
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC PATCH 1/3] PCI: endpoint: introduce a helper to implement pci ep virtio function
  2023-04-14 12:39 ` Shunsuke Mie
@ 2023-04-14 12:39   ` Shunsuke Mie
  -1 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Shunsuke Mie, Frank Li, Jon Mason, Randy Dunlap,
	Ren Zhijie, linux-kernel, linux-pci, virtualization

The Linux PCIe Endpoint framework supports to implement PCIe endpoint
functions using a PCIe controller operating in endpoint mode.
It is possble to realize the behavior of PCIe device, such as virtio PCI
device. This patch introduces a setof helper functions and data structures
to implement a PCIe endpoint function that behaves as a virtio device.

Those functions enable the implementation PCIe endpoint function that
comply with the virtio lecacy specification. Because modern virtio
specifications require devices to implement custom PCIe capabilities, which
are not currently supported by either PCIe controllers/drivers or the PCIe
endpoint framework.

The helper functions work with the new struct epf_virtio, which is
initialized and finalized using the following functions:

- int epf_virtio_init();
- void epf_virtio_final()

Once initialized, the PCIe configuration space can be read and written
using the following functions:

- epf_virtio_cfg_{read,write}#size()
- epf_virtio_cfg_{set,clear}#size()
- epf_virtio_cfg_memcpy_toio()

The size is supported 8, 16 and 32bits. The content of configuration space
varies depending on the type of virtio device.

After the setup, launch the kernel thread for negotiation with host virtio
drivers and detection virtqueue notifications with the function:

- epf_virtio_launch_bgtask()

Also there are functions to shutdown and reset the kthread.

- epf_virtio_terminate_bgtask()
- epf_virtio_terminate_reset()

Data transfer function is also provide.

- epf_virtio_vrh_memcpy()

This function copy data indicated descriptor of PCIe host and endpoint
virtqueue to each other. The virtqueue manage as vringh and copy direction
is specified by enum epf_virtio_copy_dir, which is defined as
follows:
This function copies data between the PCIe host and endpoint virtqueues.
The each virtqueues are managed using vringh, and the copy direction is
specified by an enum called epf_virtio_copy_dir, which is defined as
follows:

enum epf_virtio_copy_dir {
	   EPF_VIRTIO_COPY_DIR_FROM_DEV,
	   EPF_VIRTIO_COPY_DIR_TO_DEV,
};

While this patch provides functions for negotiating with host drivers and
copying data, each PCIe function driver must impl ement operations that
depend on each specific device, such as network, block, etc.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 drivers/pci/endpoint/functions/Kconfig        |   7 +
 drivers/pci/endpoint/functions/Makefile       |   1 +
 .../pci/endpoint/functions/pci-epf-virtio.c   | 469 ++++++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.h   | 123 +++++
 4 files changed, 600 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h

diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index 9fd560886871..cf16d33c9585 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -37,3 +37,10 @@ config PCI_EPF_VNTB
 	  between PCI Root Port and PCIe Endpoint.
 
 	  If in doubt, say "N" to disable Endpoint NTB driver.
+
+config PCI_EPF_VIRTIO
+	tristate
+	depends on PCI_ENDPOINT
+	select VHOST_IOMEM
+	help
+	  Helpers to implement PCI virtio Endpoint function
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index 5c13001deaba..a96f127ce900 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -6,3 +6,4 @@
 obj-$(CONFIG_PCI_EPF_TEST)		+= pci-epf-test.o
 obj-$(CONFIG_PCI_EPF_NTB)		+= pci-epf-ntb.o
 obj-$(CONFIG_PCI_EPF_VNTB) 		+= pci-epf-vntb.o
+obj-$(CONFIG_PCI_EPF_VIRTIO)		+= pci-epf-virtio.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-virtio.c b/drivers/pci/endpoint/functions/pci-epf-virtio.c
new file mode 100644
index 000000000000..bb3de01563de
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-virtio.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helpers to implement PCIe virtio EP function.
+ */
+#include <linux/virtio_pci.h>
+#include <linux/virtio_config.h>
+#include <linux/kthread.h>
+
+#include "pci-epf-virtio.h"
+
+static void epf_virtio_unmap_vq(struct pci_epf *epf, void __iomem *vq_virt,
+				phys_addr_t vq_phys, unsigned int num)
+{
+	size_t vq_size = vring_size(num, VIRTIO_PCI_VRING_ALIGN);
+
+	pci_epc_unmap_addr(epf->epc, epf->func_no, epf->vfunc_no, vq_phys,
+			   vq_virt, vq_size);
+	pci_epc_mem_free_addr(epf->epc, vq_phys, vq_virt, vq_size);
+}
+
+static void __iomem *epf_virtio_map_vq(struct pci_epf *epf,
+				       phys_addr_t vq_pci_addr,
+				       unsigned int num, phys_addr_t *vq_phys)
+{
+	int err;
+	size_t vq_size;
+	void __iomem *vq_virt;
+
+	vq_size = vring_size(num, VIRTIO_PCI_VRING_ALIGN);
+
+	vq_virt = pci_epc_map_addr(epf->epc, epf->func_no, epf->vfunc_no,
+				   vq_pci_addr, vq_phys, vq_size);
+	if (IS_ERR(vq_virt)) {
+		pr_err("Failed to map virtuqueue to local");
+		goto err_free;
+	}
+
+	return vq_virt;
+
+err_free:
+	pci_epc_mem_free_addr(epf->epc, *vq_phys, vq_virt, vq_size);
+
+	return ERR_PTR(err);
+}
+
+static void epf_virtio_free_vringh(struct pci_epf *epf, struct epf_vringh *evrh)
+{
+	epf_virtio_unmap_vq(epf, evrh->virt, evrh->phys, evrh->num);
+	kfree(evrh);
+}
+
+static struct epf_vringh *epf_virtio_alloc_vringh(struct pci_epf *epf,
+						  u64 features,
+						  phys_addr_t pci_addr,
+						  unsigned int num)
+{
+	int err;
+	struct vring vring;
+	struct epf_vringh *evrh;
+
+	evrh = kmalloc(sizeof(*evrh), GFP_KERNEL);
+	if (!evrh) {
+		err = -ENOMEM;
+		goto err_unmap_vq;
+	}
+
+	evrh->num = num;
+
+	evrh->virt = epf_virtio_map_vq(epf, pci_addr, num, &evrh->phys);
+	if (IS_ERR(evrh->virt))
+		return evrh->virt;
+
+	vring_init(&vring, num, evrh->virt, VIRTIO_PCI_VRING_ALIGN);
+
+	err = vringh_init_iomem(&evrh->vrh, features, num, false, GFP_KERNEL,
+				vring.desc, vring.avail, vring.used);
+	if (err)
+		goto err_free_epf_vq;
+
+	return evrh;
+
+err_free_epf_vq:
+	kfree(evrh);
+
+err_unmap_vq:
+	epf_virtio_unmap_vq(epf, evrh->virt, evrh->phys, evrh->num);
+
+	return ERR_PTR(err);
+}
+
+#define VIRTIO_PCI_LEGACY_CFG_BAR 0
+
+static void __iomem *epf_virtio_alloc_bar(struct pci_epf *epf, size_t size)
+{
+	struct pci_epf_bar *config_bar = &epf->bar[VIRTIO_PCI_LEGACY_CFG_BAR];
+	const struct pci_epc_features *features;
+	void __iomem *bar;
+	int err;
+
+	features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!features) {
+		pr_debug("Failed to get PCI EPC features\n");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	if (features->reserved_bar & BIT(VIRTIO_PCI_LEGACY_CFG_BAR)) {
+		pr_debug("Cannot use the PCI BAR for legacy virtio pci\n");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	if (features->bar_fixed_size[VIRTIO_PCI_LEGACY_CFG_BAR]) {
+		if (size >
+		    features->bar_fixed_size[VIRTIO_PCI_LEGACY_CFG_BAR]) {
+			pr_debug("PCI BAR size is not enough\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	bar = pci_epf_alloc_space(epf, size, VIRTIO_PCI_LEGACY_CFG_BAR,
+				  features->align, PRIMARY_INTERFACE);
+	if (!bar) {
+		pr_debug("Failed to allocate virtio-net config memory\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	config_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+	err = pci_epc_set_bar(epf->epc, epf->func_no, epf->vfunc_no,
+			      config_bar);
+	if (err) {
+		pr_debug("Failed to set PCI BAR");
+		goto err_free_space;
+	}
+
+	return bar;
+
+err_free_space:
+
+	pci_epf_free_space(epf, bar, VIRTIO_PCI_LEGACY_CFG_BAR,
+			   PRIMARY_INTERFACE);
+
+	return ERR_PTR(err);
+}
+
+static void epf_virtio_free_bar(struct pci_epf *epf, void __iomem *bar)
+{
+	struct pci_epf_bar *config_bar = &epf->bar[VIRTIO_PCI_LEGACY_CFG_BAR];
+
+	pci_epc_clear_bar(epf->epc, epf->func_no, epf->vfunc_no, config_bar);
+	pci_epf_free_space(epf, bar, VIRTIO_PCI_LEGACY_CFG_BAR,
+			   PRIMARY_INTERFACE);
+}
+
+static void epf_virtio_init_bar(struct epf_virtio *evio, void __iomem *bar)
+{
+	evio->bar = bar;
+
+	epf_virtio_cfg_write32(evio, VIRTIO_PCI_HOST_FEATURES, evio->features);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_ISR, VIRTIO_PCI_ISR_QUEUE);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NUM, evio->vqlen);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NOTIFY, evio->nvq);
+	epf_virtio_cfg_write8(evio, VIRTIO_PCI_STATUS, 0);
+}
+
+/**
+ * epf_virtio_init - initialize struct epf_virtio and setup BAR for virtio
+ * @evio: struct epf_virtio to initialize.
+ * @hdr: pci configuration space to show remote host.
+ * @bar_size: pci BAR size it depends on the virtio device type.
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_init(struct epf_virtio *evio, struct pci_epf_header *hdr,
+		    size_t bar_size)
+{
+	struct pci_epf *epf = evio->epf;
+	void __iomem *bar;
+	int err;
+
+	err = pci_epc_write_header(epf->epc, epf->func_no, epf->vfunc_no, hdr);
+	if (err)
+		return err;
+
+	bar = epf_virtio_alloc_bar(epf, bar_size);
+	if (IS_ERR(bar))
+		return PTR_ERR(bar);
+
+	epf_virtio_init_bar(evio, bar);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_init);
+
+/**
+ * epf_virtio_final - finalize struct epf_virtio. it frees bar and memories
+ * @evio: struct epf_virtio to finalize.
+ */
+void epf_virtio_final(struct epf_virtio *evio)
+{
+	epf_virtio_free_bar(evio->epf, evio->bar);
+
+	for (int i = 0; i < evio->nvq; i++)
+		epf_virtio_free_vringh(evio->epf, evio->vrhs[i]);
+
+	kfree(evio->vrhs);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_final);
+
+static int epf_virtio_negotiate_vq(struct epf_virtio *evio)
+{
+	u32 pfn;
+	u16 sel;
+	int i = 0;
+	struct _pair {
+		u32 pfn;
+		u16 sel;
+	} *tmp;
+	int err = 0;
+	size_t nvq = evio->nvq;
+
+	tmp = kmalloc_array(nvq, sizeof(tmp[0]), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	/*
+	 * PCIe EP framework has no capability to hook access PCI BAR space from
+	 * remote host driver, so poll the specific register, queue pfn to detect
+	 * the writing from the driver.
+	 *
+	 * This implementation assumes that the address of each virtqueue is
+	 * written only once.
+	 */
+	for (i = 0; i < nvq; i++) {
+		while (!(pfn = epf_virtio_cfg_read32(evio,
+						     VIRTIO_PCI_QUEUE_PFN)) &&
+		       evio->running)
+			;
+
+		sel = epf_virtio_cfg_read16(evio, VIRTIO_PCI_QUEUE_SEL);
+
+		epf_virtio_cfg_write32(evio, VIRTIO_PCI_QUEUE_PFN, 0);
+
+		tmp[i].pfn = pfn;
+		tmp[i].sel = sel;
+	}
+
+	if (!evio->running)
+		goto err_out;
+
+	evio->vrhs = kmalloc_array(nvq, sizeof(evio->vrhs[0]), GFP_KERNEL);
+	if (!evio->vrhs) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	for (i = 0; i < nvq; i++) {
+		phys_addr_t pci = tmp[i].pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
+
+		evio->vrhs[i] = epf_virtio_alloc_vringh(
+			evio->epf, evio->features, pci, evio->vqlen);
+		if (IS_ERR(evio->vrhs[i])) {
+			err = PTR_ERR(evio->vrhs[i]);
+			goto err_free_evrhs;
+		}
+	}
+
+	kfree(tmp);
+
+	return 0;
+
+err_free_evrhs:
+	for (i -= 1; i > 0; i--)
+		epf_virtio_free_vringh(evio->epf, evio->vrhs[i]);
+
+	kfree(evio->vrhs);
+
+err_out:
+	kfree(tmp);
+
+	return err;
+}
+
+static void epf_virtio_monitor_qnotify(struct epf_virtio *evio)
+{
+	const u16 qn_default = evio->nvq;
+	u16 tmp;
+
+	/* Since there is no way to synchronize between the host and EP functions,
+	 * it is possible to miss multiple notifications.
+	 */
+	while (evio->running) {
+		tmp = epf_virtio_cfg_read16(evio, VIRTIO_PCI_QUEUE_NOTIFY);
+		if (tmp == qn_default)
+			continue;
+
+		epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NOTIFY,
+				       qn_default);
+
+		evio->qn_callback(evio->qn_param);
+	}
+}
+
+static int epf_virtio_bgtask(void *param)
+{
+	struct epf_virtio *evio = param;
+	int err;
+
+	err = epf_virtio_negotiate_vq(evio);
+	if (err < 0) {
+		pr_err("failed to negoticate configs with driver\n");
+		return err;
+	}
+
+	while (!(epf_virtio_cfg_read8(evio, VIRTIO_PCI_STATUS) &
+		 VIRTIO_CONFIG_S_DRIVER_OK) &&
+	       evio->running)
+		;
+
+	if (evio->ic_callback && evio->running)
+		evio->ic_callback(evio->ic_param);
+
+	epf_virtio_monitor_qnotify(evio);
+
+	return 0;
+}
+
+/**
+ * epf_virtio_launch_bgtask - spawn a kthread that emulates virtio device
+ * operations.
+ * @evio: It should be initialized prior with epf_virtio_init().
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_launch_bgtask(struct epf_virtio *evio)
+{
+	evio->bgtask = kthread_create(epf_virtio_bgtask, evio,
+				      "pci-epf-virtio/bgtask");
+	if (IS_ERR(evio->bgtask))
+		return PTR_ERR(evio->bgtask);
+
+	evio->running = true;
+
+	sched_set_fifo(evio->bgtask);
+	wake_up_process(evio->bgtask);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_launch_bgtask);
+
+/**
+ * epf_virtio_terminate_bgtask - shutdown a device emulation kthread.
+ * @evio: struct epf_virtio it already launched bgtask.
+ */
+void epf_virtio_terminate_bgtask(struct epf_virtio *evio)
+{
+	evio->running = false;
+
+	kthread_stop(evio->bgtask);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_terminate_bgtask);
+
+/**
+ * epf_virtio_reset - reset virtio status
+ * @evio: struct epf_virtio to reset
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_reset(struct epf_virtio *evio)
+{
+	epf_virtio_terminate_bgtask(evio);
+	epf_virtio_init_bar(evio, evio->bar);
+
+	return epf_virtio_launch_bgtask(evio);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_reset);
+
+/**
+ * epf_virtio_vrh_memcpy - copy a data with CPU between remote and local vring.
+ * @evio: struct epf_virtio
+ * @svrh: vringh for source virtqueue.
+ * @siov: iovec to store buffer info for source virtqueue
+ * @dvrh: vringh for destination virtqueue.
+ * @diov: iovec to store buffer info for destination virtqueue
+ * @dir: direction of the copy.
+ *
+ * Returns zero, one or a negative.
+ * 0: there is no data in src virtio ring.
+ * 1: success to transfer data.
+ * negative: errors.
+ */
+int epf_virtio_vrh_memcpy(struct epf_virtio *evio, struct vringh *svrh,
+			  struct vringh_kiov *siov, struct vringh *dvrh,
+			  struct vringh_kiov *diov,
+			  enum epf_virtio_copy_dir dir)
+{
+	int err;
+	u16 shead, dhead;
+	size_t slen, dlen, total_len;
+	void *svirt, *dvirt;
+	phys_addr_t sbase, dbase, phys;
+	struct pci_epf *epf = evio->epf;
+
+	err = vringh_getdesc(svrh, siov, NULL, &shead);
+	if (err <= 0) {
+		if (err < 0)
+			pr_err("s err %d\n", err);
+		return err;
+	}
+
+	err = vringh_getdesc(dvrh, NULL, diov, &dhead);
+	if (err <= 0) {
+		if (err < 0)
+			pr_err("d err %d\n", err);
+		return err;
+	}
+
+	total_len = vringh_kiov_length(siov);
+
+	for (; siov->i < siov->used; siov->i++, diov->i++) {
+		slen = siov->iov[siov->i].iov_len;
+		sbase = (u64)siov->iov[siov->i].iov_base;
+		dlen = diov->iov[diov->i].iov_len;
+		dbase = (u64)diov->iov[diov->i].iov_base;
+
+		if (dlen < slen) {
+			pr_err("no space %ld < %ld\n", dlen, slen);
+			return -ENOSPC;
+		}
+
+		if (dir == EPF_VIRTIO_COPY_DIR_FROM_DEV) {
+			svirt = pci_epc_map_addr(epf->epc, epf->func_no,
+						 epf->vfunc_no, sbase, &phys,
+						 slen);
+			if (IS_ERR(svirt)) {
+				pr_err("pci_epc_map_addr s %ld\n",
+				       PTR_ERR(svirt));
+				return PTR_ERR(svirt);
+			}
+
+			dvirt = phys_to_virt(dbase);
+			memcpy_fromio(dvirt, svirt, slen);
+
+			pci_epc_unmap_addr(epf->epc, epf->func_no,
+					   epf->vfunc_no, phys, svirt, slen);
+		} else {
+			svirt = phys_to_virt(sbase);
+			dvirt = pci_epc_map_addr(epf->epc, epf->func_no,
+						 epf->vfunc_no, dbase, &phys,
+						 dlen);
+			if (IS_ERR(dvirt)) {
+				pr_err("pci_epc_map_addr d %ld\n",
+				       PTR_ERR(dvirt));
+				return PTR_ERR(dvirt);
+			}
+
+			memcpy_toio(dvirt, svirt, slen);
+
+			pci_epc_unmap_addr(epf->epc, epf->func_no,
+					   epf->vfunc_no, phys, dvirt, dlen);
+		}
+	}
+
+	vringh_complete(svrh, shead, total_len);
+	vringh_complete(dvrh, dhead, total_len);
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_vrh_memcpy);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pci/endpoint/functions/pci-epf-virtio.h b/drivers/pci/endpoint/functions/pci-epf-virtio.h
new file mode 100644
index 000000000000..162029f6da70
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-virtio.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PCI_EPF_VIRTIO_H__
+#define __PCI_EPF_VIRTIO_H__
+
+#include <linux/pci-epf.h>
+#include <linux/pci-epc.h>
+#include <linux/vringh.h>
+
+struct epf_vringh {
+	struct vringh vrh;
+	void __iomem *virt;
+	phys_addr_t phys;
+	unsigned int num;
+};
+
+struct epf_virtio {
+	/* Base PCI endpoint function */
+	struct pci_epf *epf;
+
+	/* Virtio parameters */
+	u64 features;
+	size_t bar_size;
+	size_t nvq;
+	size_t vqlen;
+
+	/* struct to access virtqueue on remote host */
+	struct epf_vringh **vrhs;
+
+	/* struct for thread to emulate virtio device */
+	struct task_struct *bgtask;
+
+	/* Virtual address of pci configuration space */
+	void __iomem *bar;
+
+	/* Callback function and parameter for queue notifcation
+	 * Note: PCI EP function cannot detect qnotify accurately, therefore this
+	 * callback function should check all of virtqueue's changes.
+	 */
+	void (*qn_callback)(void *param);
+	void *qn_param;
+
+	/* Callback function and parameter for initialize complete */
+	void (*ic_callback)(void *param);
+	void *ic_param;
+
+	bool running;
+};
+
+#define DEFINE_EPF_VIRTIO_CFG_READ(size)                 \
+	static inline u##size epf_virtio_cfg_read##size( \
+		struct epf_virtio *evio, size_t offset)  \
+	{                                                \
+		void __iomem *base = evio->bar + offset; \
+		return ioread##size(base);               \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_READ(8)
+DEFINE_EPF_VIRTIO_CFG_READ(16)
+DEFINE_EPF_VIRTIO_CFG_READ(32)
+
+#define DEFINE_EPF_VIRTIO_CFG_WRITE(size)                              \
+	static inline void epf_virtio_cfg_write##size(                 \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(value, base);                            \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_WRITE(8);
+DEFINE_EPF_VIRTIO_CFG_WRITE(16);
+DEFINE_EPF_VIRTIO_CFG_WRITE(32);
+
+#define DEFINE_EPF_VIRTIO_CFG_SET(size)                                \
+	static inline void epf_virtio_cfg_set##size(                   \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(ioread##size(base) | value, base);       \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_SET(8)
+DEFINE_EPF_VIRTIO_CFG_SET(16)
+DEFINE_EPF_VIRTIO_CFG_SET(32)
+
+#define DEFINE_EPF_VIRTIO_CFG_CLEAR(size)                              \
+	static inline void epf_virtio_cfg_clear##size(                 \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(ioread##size(base) & ~value, base);      \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_CLEAR(8)
+DEFINE_EPF_VIRTIO_CFG_CLEAR(16)
+DEFINE_EPF_VIRTIO_CFG_CLEAR(32)
+
+static inline void epf_virtio_cfg_memcpy_toio(struct epf_virtio *evio,
+					      size_t offset, void *buf,
+					      size_t len)
+{
+	void __iomem *base = evio->bar + offset;
+
+	memcpy_toio(base, buf, len);
+}
+
+int epf_virtio_init(struct epf_virtio *evio, struct pci_epf_header *hdr,
+		    size_t bar_size);
+void epf_virtio_final(struct epf_virtio *evio);
+int epf_virtio_launch_bgtask(struct epf_virtio *evio);
+void epf_virtio_terminate_bgtask(struct epf_virtio *evio);
+int epf_virtio_reset(struct epf_virtio *evio);
+
+enum epf_virtio_copy_dir {
+	EPF_VIRTIO_COPY_DIR_FROM_DEV,
+	EPF_VIRTIO_COPY_DIR_TO_DEV,
+};
+
+int epf_virtio_vrh_memcpy(struct epf_virtio *evio, struct vringh *svrh,
+			  struct vringh_kiov *siov, struct vringh *dvrh,
+			  struct vringh_kiov *diov,
+			  enum epf_virtio_copy_dir dir);
+
+#endif /* __PCI_EPF_VIRTIO_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 1/3] PCI: endpoint: introduce a helper to implement pci ep virtio function
@ 2023-04-14 12:39   ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam, Frank Li,
	linux-kernel, virtualization, Ren Zhijie, Shunsuke Mie,
	Jon Mason, Bjorn Helgaas

The Linux PCIe Endpoint framework supports to implement PCIe endpoint
functions using a PCIe controller operating in endpoint mode.
It is possble to realize the behavior of PCIe device, such as virtio PCI
device. This patch introduces a setof helper functions and data structures
to implement a PCIe endpoint function that behaves as a virtio device.

Those functions enable the implementation PCIe endpoint function that
comply with the virtio lecacy specification. Because modern virtio
specifications require devices to implement custom PCIe capabilities, which
are not currently supported by either PCIe controllers/drivers or the PCIe
endpoint framework.

The helper functions work with the new struct epf_virtio, which is
initialized and finalized using the following functions:

- int epf_virtio_init();
- void epf_virtio_final()

Once initialized, the PCIe configuration space can be read and written
using the following functions:

- epf_virtio_cfg_{read,write}#size()
- epf_virtio_cfg_{set,clear}#size()
- epf_virtio_cfg_memcpy_toio()

The size is supported 8, 16 and 32bits. The content of configuration space
varies depending on the type of virtio device.

After the setup, launch the kernel thread for negotiation with host virtio
drivers and detection virtqueue notifications with the function:

- epf_virtio_launch_bgtask()

Also there are functions to shutdown and reset the kthread.

- epf_virtio_terminate_bgtask()
- epf_virtio_terminate_reset()

Data transfer function is also provide.

- epf_virtio_vrh_memcpy()

This function copy data indicated descriptor of PCIe host and endpoint
virtqueue to each other. The virtqueue manage as vringh and copy direction
is specified by enum epf_virtio_copy_dir, which is defined as
follows:
This function copies data between the PCIe host and endpoint virtqueues.
The each virtqueues are managed using vringh, and the copy direction is
specified by an enum called epf_virtio_copy_dir, which is defined as
follows:

enum epf_virtio_copy_dir {
	   EPF_VIRTIO_COPY_DIR_FROM_DEV,
	   EPF_VIRTIO_COPY_DIR_TO_DEV,
};

While this patch provides functions for negotiating with host drivers and
copying data, each PCIe function driver must impl ement operations that
depend on each specific device, such as network, block, etc.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 drivers/pci/endpoint/functions/Kconfig        |   7 +
 drivers/pci/endpoint/functions/Makefile       |   1 +
 .../pci/endpoint/functions/pci-epf-virtio.c   | 469 ++++++++++++++++++
 .../pci/endpoint/functions/pci-epf-virtio.h   | 123 +++++
 4 files changed, 600 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h

diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index 9fd560886871..cf16d33c9585 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -37,3 +37,10 @@ config PCI_EPF_VNTB
 	  between PCI Root Port and PCIe Endpoint.
 
 	  If in doubt, say "N" to disable Endpoint NTB driver.
+
+config PCI_EPF_VIRTIO
+	tristate
+	depends on PCI_ENDPOINT
+	select VHOST_IOMEM
+	help
+	  Helpers to implement PCI virtio Endpoint function
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index 5c13001deaba..a96f127ce900 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -6,3 +6,4 @@
 obj-$(CONFIG_PCI_EPF_TEST)		+= pci-epf-test.o
 obj-$(CONFIG_PCI_EPF_NTB)		+= pci-epf-ntb.o
 obj-$(CONFIG_PCI_EPF_VNTB) 		+= pci-epf-vntb.o
+obj-$(CONFIG_PCI_EPF_VIRTIO)		+= pci-epf-virtio.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-virtio.c b/drivers/pci/endpoint/functions/pci-epf-virtio.c
new file mode 100644
index 000000000000..bb3de01563de
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-virtio.c
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helpers to implement PCIe virtio EP function.
+ */
+#include <linux/virtio_pci.h>
+#include <linux/virtio_config.h>
+#include <linux/kthread.h>
+
+#include "pci-epf-virtio.h"
+
+static void epf_virtio_unmap_vq(struct pci_epf *epf, void __iomem *vq_virt,
+				phys_addr_t vq_phys, unsigned int num)
+{
+	size_t vq_size = vring_size(num, VIRTIO_PCI_VRING_ALIGN);
+
+	pci_epc_unmap_addr(epf->epc, epf->func_no, epf->vfunc_no, vq_phys,
+			   vq_virt, vq_size);
+	pci_epc_mem_free_addr(epf->epc, vq_phys, vq_virt, vq_size);
+}
+
+static void __iomem *epf_virtio_map_vq(struct pci_epf *epf,
+				       phys_addr_t vq_pci_addr,
+				       unsigned int num, phys_addr_t *vq_phys)
+{
+	int err;
+	size_t vq_size;
+	void __iomem *vq_virt;
+
+	vq_size = vring_size(num, VIRTIO_PCI_VRING_ALIGN);
+
+	vq_virt = pci_epc_map_addr(epf->epc, epf->func_no, epf->vfunc_no,
+				   vq_pci_addr, vq_phys, vq_size);
+	if (IS_ERR(vq_virt)) {
+		pr_err("Failed to map virtuqueue to local");
+		goto err_free;
+	}
+
+	return vq_virt;
+
+err_free:
+	pci_epc_mem_free_addr(epf->epc, *vq_phys, vq_virt, vq_size);
+
+	return ERR_PTR(err);
+}
+
+static void epf_virtio_free_vringh(struct pci_epf *epf, struct epf_vringh *evrh)
+{
+	epf_virtio_unmap_vq(epf, evrh->virt, evrh->phys, evrh->num);
+	kfree(evrh);
+}
+
+static struct epf_vringh *epf_virtio_alloc_vringh(struct pci_epf *epf,
+						  u64 features,
+						  phys_addr_t pci_addr,
+						  unsigned int num)
+{
+	int err;
+	struct vring vring;
+	struct epf_vringh *evrh;
+
+	evrh = kmalloc(sizeof(*evrh), GFP_KERNEL);
+	if (!evrh) {
+		err = -ENOMEM;
+		goto err_unmap_vq;
+	}
+
+	evrh->num = num;
+
+	evrh->virt = epf_virtio_map_vq(epf, pci_addr, num, &evrh->phys);
+	if (IS_ERR(evrh->virt))
+		return evrh->virt;
+
+	vring_init(&vring, num, evrh->virt, VIRTIO_PCI_VRING_ALIGN);
+
+	err = vringh_init_iomem(&evrh->vrh, features, num, false, GFP_KERNEL,
+				vring.desc, vring.avail, vring.used);
+	if (err)
+		goto err_free_epf_vq;
+
+	return evrh;
+
+err_free_epf_vq:
+	kfree(evrh);
+
+err_unmap_vq:
+	epf_virtio_unmap_vq(epf, evrh->virt, evrh->phys, evrh->num);
+
+	return ERR_PTR(err);
+}
+
+#define VIRTIO_PCI_LEGACY_CFG_BAR 0
+
+static void __iomem *epf_virtio_alloc_bar(struct pci_epf *epf, size_t size)
+{
+	struct pci_epf_bar *config_bar = &epf->bar[VIRTIO_PCI_LEGACY_CFG_BAR];
+	const struct pci_epc_features *features;
+	void __iomem *bar;
+	int err;
+
+	features = pci_epc_get_features(epf->epc, epf->func_no, epf->vfunc_no);
+	if (!features) {
+		pr_debug("Failed to get PCI EPC features\n");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	if (features->reserved_bar & BIT(VIRTIO_PCI_LEGACY_CFG_BAR)) {
+		pr_debug("Cannot use the PCI BAR for legacy virtio pci\n");
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	if (features->bar_fixed_size[VIRTIO_PCI_LEGACY_CFG_BAR]) {
+		if (size >
+		    features->bar_fixed_size[VIRTIO_PCI_LEGACY_CFG_BAR]) {
+			pr_debug("PCI BAR size is not enough\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	bar = pci_epf_alloc_space(epf, size, VIRTIO_PCI_LEGACY_CFG_BAR,
+				  features->align, PRIMARY_INTERFACE);
+	if (!bar) {
+		pr_debug("Failed to allocate virtio-net config memory\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	config_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+	err = pci_epc_set_bar(epf->epc, epf->func_no, epf->vfunc_no,
+			      config_bar);
+	if (err) {
+		pr_debug("Failed to set PCI BAR");
+		goto err_free_space;
+	}
+
+	return bar;
+
+err_free_space:
+
+	pci_epf_free_space(epf, bar, VIRTIO_PCI_LEGACY_CFG_BAR,
+			   PRIMARY_INTERFACE);
+
+	return ERR_PTR(err);
+}
+
+static void epf_virtio_free_bar(struct pci_epf *epf, void __iomem *bar)
+{
+	struct pci_epf_bar *config_bar = &epf->bar[VIRTIO_PCI_LEGACY_CFG_BAR];
+
+	pci_epc_clear_bar(epf->epc, epf->func_no, epf->vfunc_no, config_bar);
+	pci_epf_free_space(epf, bar, VIRTIO_PCI_LEGACY_CFG_BAR,
+			   PRIMARY_INTERFACE);
+}
+
+static void epf_virtio_init_bar(struct epf_virtio *evio, void __iomem *bar)
+{
+	evio->bar = bar;
+
+	epf_virtio_cfg_write32(evio, VIRTIO_PCI_HOST_FEATURES, evio->features);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_ISR, VIRTIO_PCI_ISR_QUEUE);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NUM, evio->vqlen);
+	epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NOTIFY, evio->nvq);
+	epf_virtio_cfg_write8(evio, VIRTIO_PCI_STATUS, 0);
+}
+
+/**
+ * epf_virtio_init - initialize struct epf_virtio and setup BAR for virtio
+ * @evio: struct epf_virtio to initialize.
+ * @hdr: pci configuration space to show remote host.
+ * @bar_size: pci BAR size it depends on the virtio device type.
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_init(struct epf_virtio *evio, struct pci_epf_header *hdr,
+		    size_t bar_size)
+{
+	struct pci_epf *epf = evio->epf;
+	void __iomem *bar;
+	int err;
+
+	err = pci_epc_write_header(epf->epc, epf->func_no, epf->vfunc_no, hdr);
+	if (err)
+		return err;
+
+	bar = epf_virtio_alloc_bar(epf, bar_size);
+	if (IS_ERR(bar))
+		return PTR_ERR(bar);
+
+	epf_virtio_init_bar(evio, bar);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_init);
+
+/**
+ * epf_virtio_final - finalize struct epf_virtio. it frees bar and memories
+ * @evio: struct epf_virtio to finalize.
+ */
+void epf_virtio_final(struct epf_virtio *evio)
+{
+	epf_virtio_free_bar(evio->epf, evio->bar);
+
+	for (int i = 0; i < evio->nvq; i++)
+		epf_virtio_free_vringh(evio->epf, evio->vrhs[i]);
+
+	kfree(evio->vrhs);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_final);
+
+static int epf_virtio_negotiate_vq(struct epf_virtio *evio)
+{
+	u32 pfn;
+	u16 sel;
+	int i = 0;
+	struct _pair {
+		u32 pfn;
+		u16 sel;
+	} *tmp;
+	int err = 0;
+	size_t nvq = evio->nvq;
+
+	tmp = kmalloc_array(nvq, sizeof(tmp[0]), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	/*
+	 * PCIe EP framework has no capability to hook access PCI BAR space from
+	 * remote host driver, so poll the specific register, queue pfn to detect
+	 * the writing from the driver.
+	 *
+	 * This implementation assumes that the address of each virtqueue is
+	 * written only once.
+	 */
+	for (i = 0; i < nvq; i++) {
+		while (!(pfn = epf_virtio_cfg_read32(evio,
+						     VIRTIO_PCI_QUEUE_PFN)) &&
+		       evio->running)
+			;
+
+		sel = epf_virtio_cfg_read16(evio, VIRTIO_PCI_QUEUE_SEL);
+
+		epf_virtio_cfg_write32(evio, VIRTIO_PCI_QUEUE_PFN, 0);
+
+		tmp[i].pfn = pfn;
+		tmp[i].sel = sel;
+	}
+
+	if (!evio->running)
+		goto err_out;
+
+	evio->vrhs = kmalloc_array(nvq, sizeof(evio->vrhs[0]), GFP_KERNEL);
+	if (!evio->vrhs) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	for (i = 0; i < nvq; i++) {
+		phys_addr_t pci = tmp[i].pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
+
+		evio->vrhs[i] = epf_virtio_alloc_vringh(
+			evio->epf, evio->features, pci, evio->vqlen);
+		if (IS_ERR(evio->vrhs[i])) {
+			err = PTR_ERR(evio->vrhs[i]);
+			goto err_free_evrhs;
+		}
+	}
+
+	kfree(tmp);
+
+	return 0;
+
+err_free_evrhs:
+	for (i -= 1; i > 0; i--)
+		epf_virtio_free_vringh(evio->epf, evio->vrhs[i]);
+
+	kfree(evio->vrhs);
+
+err_out:
+	kfree(tmp);
+
+	return err;
+}
+
+static void epf_virtio_monitor_qnotify(struct epf_virtio *evio)
+{
+	const u16 qn_default = evio->nvq;
+	u16 tmp;
+
+	/* Since there is no way to synchronize between the host and EP functions,
+	 * it is possible to miss multiple notifications.
+	 */
+	while (evio->running) {
+		tmp = epf_virtio_cfg_read16(evio, VIRTIO_PCI_QUEUE_NOTIFY);
+		if (tmp == qn_default)
+			continue;
+
+		epf_virtio_cfg_write16(evio, VIRTIO_PCI_QUEUE_NOTIFY,
+				       qn_default);
+
+		evio->qn_callback(evio->qn_param);
+	}
+}
+
+static int epf_virtio_bgtask(void *param)
+{
+	struct epf_virtio *evio = param;
+	int err;
+
+	err = epf_virtio_negotiate_vq(evio);
+	if (err < 0) {
+		pr_err("failed to negoticate configs with driver\n");
+		return err;
+	}
+
+	while (!(epf_virtio_cfg_read8(evio, VIRTIO_PCI_STATUS) &
+		 VIRTIO_CONFIG_S_DRIVER_OK) &&
+	       evio->running)
+		;
+
+	if (evio->ic_callback && evio->running)
+		evio->ic_callback(evio->ic_param);
+
+	epf_virtio_monitor_qnotify(evio);
+
+	return 0;
+}
+
+/**
+ * epf_virtio_launch_bgtask - spawn a kthread that emulates virtio device
+ * operations.
+ * @evio: It should be initialized prior with epf_virtio_init().
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_launch_bgtask(struct epf_virtio *evio)
+{
+	evio->bgtask = kthread_create(epf_virtio_bgtask, evio,
+				      "pci-epf-virtio/bgtask");
+	if (IS_ERR(evio->bgtask))
+		return PTR_ERR(evio->bgtask);
+
+	evio->running = true;
+
+	sched_set_fifo(evio->bgtask);
+	wake_up_process(evio->bgtask);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_launch_bgtask);
+
+/**
+ * epf_virtio_terminate_bgtask - shutdown a device emulation kthread.
+ * @evio: struct epf_virtio it already launched bgtask.
+ */
+void epf_virtio_terminate_bgtask(struct epf_virtio *evio)
+{
+	evio->running = false;
+
+	kthread_stop(evio->bgtask);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_terminate_bgtask);
+
+/**
+ * epf_virtio_reset - reset virtio status
+ * @evio: struct epf_virtio to reset
+ *
+ * Returns zero or a negative error.
+ */
+int epf_virtio_reset(struct epf_virtio *evio)
+{
+	epf_virtio_terminate_bgtask(evio);
+	epf_virtio_init_bar(evio, evio->bar);
+
+	return epf_virtio_launch_bgtask(evio);
+}
+EXPORT_SYMBOL_GPL(epf_virtio_reset);
+
+/**
+ * epf_virtio_vrh_memcpy - copy a data with CPU between remote and local vring.
+ * @evio: struct epf_virtio
+ * @svrh: vringh for source virtqueue.
+ * @siov: iovec to store buffer info for source virtqueue
+ * @dvrh: vringh for destination virtqueue.
+ * @diov: iovec to store buffer info for destination virtqueue
+ * @dir: direction of the copy.
+ *
+ * Returns zero, one or a negative.
+ * 0: there is no data in src virtio ring.
+ * 1: success to transfer data.
+ * negative: errors.
+ */
+int epf_virtio_vrh_memcpy(struct epf_virtio *evio, struct vringh *svrh,
+			  struct vringh_kiov *siov, struct vringh *dvrh,
+			  struct vringh_kiov *diov,
+			  enum epf_virtio_copy_dir dir)
+{
+	int err;
+	u16 shead, dhead;
+	size_t slen, dlen, total_len;
+	void *svirt, *dvirt;
+	phys_addr_t sbase, dbase, phys;
+	struct pci_epf *epf = evio->epf;
+
+	err = vringh_getdesc(svrh, siov, NULL, &shead);
+	if (err <= 0) {
+		if (err < 0)
+			pr_err("s err %d\n", err);
+		return err;
+	}
+
+	err = vringh_getdesc(dvrh, NULL, diov, &dhead);
+	if (err <= 0) {
+		if (err < 0)
+			pr_err("d err %d\n", err);
+		return err;
+	}
+
+	total_len = vringh_kiov_length(siov);
+
+	for (; siov->i < siov->used; siov->i++, diov->i++) {
+		slen = siov->iov[siov->i].iov_len;
+		sbase = (u64)siov->iov[siov->i].iov_base;
+		dlen = diov->iov[diov->i].iov_len;
+		dbase = (u64)diov->iov[diov->i].iov_base;
+
+		if (dlen < slen) {
+			pr_err("no space %ld < %ld\n", dlen, slen);
+			return -ENOSPC;
+		}
+
+		if (dir == EPF_VIRTIO_COPY_DIR_FROM_DEV) {
+			svirt = pci_epc_map_addr(epf->epc, epf->func_no,
+						 epf->vfunc_no, sbase, &phys,
+						 slen);
+			if (IS_ERR(svirt)) {
+				pr_err("pci_epc_map_addr s %ld\n",
+				       PTR_ERR(svirt));
+				return PTR_ERR(svirt);
+			}
+
+			dvirt = phys_to_virt(dbase);
+			memcpy_fromio(dvirt, svirt, slen);
+
+			pci_epc_unmap_addr(epf->epc, epf->func_no,
+					   epf->vfunc_no, phys, svirt, slen);
+		} else {
+			svirt = phys_to_virt(sbase);
+			dvirt = pci_epc_map_addr(epf->epc, epf->func_no,
+						 epf->vfunc_no, dbase, &phys,
+						 dlen);
+			if (IS_ERR(dvirt)) {
+				pr_err("pci_epc_map_addr d %ld\n",
+				       PTR_ERR(dvirt));
+				return PTR_ERR(dvirt);
+			}
+
+			memcpy_toio(dvirt, svirt, slen);
+
+			pci_epc_unmap_addr(epf->epc, epf->func_no,
+					   epf->vfunc_no, phys, dvirt, dlen);
+		}
+	}
+
+	vringh_complete(svrh, shead, total_len);
+	vringh_complete(dvrh, dhead, total_len);
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(epf_virtio_vrh_memcpy);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pci/endpoint/functions/pci-epf-virtio.h b/drivers/pci/endpoint/functions/pci-epf-virtio.h
new file mode 100644
index 000000000000..162029f6da70
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-virtio.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PCI_EPF_VIRTIO_H__
+#define __PCI_EPF_VIRTIO_H__
+
+#include <linux/pci-epf.h>
+#include <linux/pci-epc.h>
+#include <linux/vringh.h>
+
+struct epf_vringh {
+	struct vringh vrh;
+	void __iomem *virt;
+	phys_addr_t phys;
+	unsigned int num;
+};
+
+struct epf_virtio {
+	/* Base PCI endpoint function */
+	struct pci_epf *epf;
+
+	/* Virtio parameters */
+	u64 features;
+	size_t bar_size;
+	size_t nvq;
+	size_t vqlen;
+
+	/* struct to access virtqueue on remote host */
+	struct epf_vringh **vrhs;
+
+	/* struct for thread to emulate virtio device */
+	struct task_struct *bgtask;
+
+	/* Virtual address of pci configuration space */
+	void __iomem *bar;
+
+	/* Callback function and parameter for queue notifcation
+	 * Note: PCI EP function cannot detect qnotify accurately, therefore this
+	 * callback function should check all of virtqueue's changes.
+	 */
+	void (*qn_callback)(void *param);
+	void *qn_param;
+
+	/* Callback function and parameter for initialize complete */
+	void (*ic_callback)(void *param);
+	void *ic_param;
+
+	bool running;
+};
+
+#define DEFINE_EPF_VIRTIO_CFG_READ(size)                 \
+	static inline u##size epf_virtio_cfg_read##size( \
+		struct epf_virtio *evio, size_t offset)  \
+	{                                                \
+		void __iomem *base = evio->bar + offset; \
+		return ioread##size(base);               \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_READ(8)
+DEFINE_EPF_VIRTIO_CFG_READ(16)
+DEFINE_EPF_VIRTIO_CFG_READ(32)
+
+#define DEFINE_EPF_VIRTIO_CFG_WRITE(size)                              \
+	static inline void epf_virtio_cfg_write##size(                 \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(value, base);                            \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_WRITE(8);
+DEFINE_EPF_VIRTIO_CFG_WRITE(16);
+DEFINE_EPF_VIRTIO_CFG_WRITE(32);
+
+#define DEFINE_EPF_VIRTIO_CFG_SET(size)                                \
+	static inline void epf_virtio_cfg_set##size(                   \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(ioread##size(base) | value, base);       \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_SET(8)
+DEFINE_EPF_VIRTIO_CFG_SET(16)
+DEFINE_EPF_VIRTIO_CFG_SET(32)
+
+#define DEFINE_EPF_VIRTIO_CFG_CLEAR(size)                              \
+	static inline void epf_virtio_cfg_clear##size(                 \
+		struct epf_virtio *evio, size_t offset, u##size value) \
+	{                                                              \
+		void __iomem *base = evio->bar + offset;               \
+		iowrite##size(ioread##size(base) & ~value, base);      \
+	}
+
+DEFINE_EPF_VIRTIO_CFG_CLEAR(8)
+DEFINE_EPF_VIRTIO_CFG_CLEAR(16)
+DEFINE_EPF_VIRTIO_CFG_CLEAR(32)
+
+static inline void epf_virtio_cfg_memcpy_toio(struct epf_virtio *evio,
+					      size_t offset, void *buf,
+					      size_t len)
+{
+	void __iomem *base = evio->bar + offset;
+
+	memcpy_toio(base, buf, len);
+}
+
+int epf_virtio_init(struct epf_virtio *evio, struct pci_epf_header *hdr,
+		    size_t bar_size);
+void epf_virtio_final(struct epf_virtio *evio);
+int epf_virtio_launch_bgtask(struct epf_virtio *evio);
+void epf_virtio_terminate_bgtask(struct epf_virtio *evio);
+int epf_virtio_reset(struct epf_virtio *evio);
+
+enum epf_virtio_copy_dir {
+	EPF_VIRTIO_COPY_DIR_FROM_DEV,
+	EPF_VIRTIO_COPY_DIR_TO_DEV,
+};
+
+int epf_virtio_vrh_memcpy(struct epf_virtio *evio, struct vringh *svrh,
+			  struct vringh_kiov *siov, struct vringh *dvrh,
+			  struct vringh_kiov *diov,
+			  enum epf_virtio_copy_dir dir);
+
+#endif /* __PCI_EPF_VIRTIO_H__ */
-- 
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 2/3] virtio_pci: add a definition of queue flag in ISR
  2023-04-14 12:39 ` Shunsuke Mie
@ 2023-04-14 12:39   ` Shunsuke Mie
  -1 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Shunsuke Mie, Frank Li, Jon Mason, Randy Dunlap,
	Ren Zhijie, linux-kernel, linux-pci, virtualization

Already it has beed defined a config changed flag of ISR, but not the queue
flag. Add a macro for it.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 include/uapi/linux/virtio_pci.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index f703afc7ad31..d405bea27240 100644
--- a/include/uapi/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
@@ -94,6 +94,9 @@
 
 #endif /* VIRTIO_PCI_NO_LEGACY */
 
+/* Bits for ISR status field:only when if MSI-X is disabled */
+/* The bit of the ISR which indicates a queue entry update. */
+#define VIRTIO_PCI_ISR_QUEUE		0x1
 /* The bit of the ISR which indicates a device configuration change. */
 #define VIRTIO_PCI_ISR_CONFIG		0x2
 /* Vector value used to disable MSI for queue */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 2/3] virtio_pci: add a definition of queue flag in ISR
@ 2023-04-14 12:39   ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam, Frank Li,
	linux-kernel, virtualization, Ren Zhijie, Shunsuke Mie,
	Jon Mason, Bjorn Helgaas

Already it has beed defined a config changed flag of ISR, but not the queue
flag. Add a macro for it.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 include/uapi/linux/virtio_pci.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index f703afc7ad31..d405bea27240 100644
--- a/include/uapi/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
@@ -94,6 +94,9 @@
 
 #endif /* VIRTIO_PCI_NO_LEGACY */
 
+/* Bits for ISR status field:only when if MSI-X is disabled */
+/* The bit of the ISR which indicates a queue entry update. */
+#define VIRTIO_PCI_ISR_QUEUE		0x1
 /* The bit of the ISR which indicates a device configuration change. */
 #define VIRTIO_PCI_ISR_CONFIG		0x2
 /* Vector value used to disable MSI for queue */
-- 
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
  2023-04-14 12:39 ` Shunsuke Mie
@ 2023-04-14 12:39   ` Shunsuke Mie
  -1 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Shunsuke Mie, Frank Li, Jon Mason, Randy Dunlap,
	Ren Zhijie, linux-kernel, linux-pci, virtualization

Add a new PCIe endpoint function driver that works as a pci virtio-console
device. The console connect to endpoint side console. It enables to
communicate PCIe host and endpoint.

Architecture is following:

 ┌────────────┐         ┌──────────────────────┬────────────┐
 │virtioe     │         │                      │virtio      │
 │console drv │         ├───────────────┐      │console drv │
 ├────────────┤         │(virtio console│      ├────────────┤
 │ virtio bus │         │ device)       │◄────►│ virtio bus │
 ├────────────┤         ├---------------┤      └────────────┤
 │            │         │ pci ep virtio │                   │
 │  pci bus   │         │  console drv  │                   │
 │            │  pcie   ├───────────────┤                   │
 │            │ ◄─────► │  pci ep Bus   │                   │
 └────────────┘         └───────────────┴───────────────────┘
   PCIe Root              PCIe Endpoint

This driver has two roles. The first is as a PCIe endpoint virtio console
function, which is implemented using the PCIe endpoint framework and PCIe
EP virtio helpers. The second is as a virtual virtio console device
connected to the virtio bus on PCIe endpoint Linux.

Communication between the two is achieved by copying the virtqueue data
between PCIe root and endpoint, respectively.

This is a simple implementation and does not include features of
virtio-console such as MULTIPORT, EMERG_WRITE, etc. As a result, each
virtio console driver only displays /dev/hvc0.

As an example of usage, by setting getty to /dev/hvc0, it is possible to
login to another host.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 drivers/pci/endpoint/functions/Kconfig        |  12 +
 drivers/pci/endpoint/functions/Makefile       |   1 +
 drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
 3 files changed, 567 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c

diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index cf16d33c9585..890e07b51cbe 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -44,3 +44,15 @@ config PCI_EPF_VIRTIO
 	select VHOST_IOMEM
 	help
 	  Helpers to implement PCI virtio Endpoint function
+
+config PCI_EPF_VCON
+	tristate "PCI Endpoint virito-console driver"
+	depends on PCI_ENDPOINT
+	select VHOST_RING
+	select PCI_EPF_VIRTIO
+	help
+	  PCIe Endpoint virtio-console function implementatino. This module
+	  enables to show the virtio-console as pci device to PCIe host side, and
+	  another virtual virtio-console device registers to endpoint system.
+	  Those devices are connected virtually and can communicate each other.
+
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index a96f127ce900..b4056689ce33 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_PCI_EPF_TEST)		+= pci-epf-test.o
 obj-$(CONFIG_PCI_EPF_NTB)		+= pci-epf-ntb.o
 obj-$(CONFIG_PCI_EPF_VNTB) 		+= pci-epf-vntb.o
 obj-$(CONFIG_PCI_EPF_VIRTIO)		+= pci-epf-virtio.o
+obj-$(CONFIG_PCI_EPF_VCON)		+= pci-epf-vcon.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-vcon.c b/drivers/pci/endpoint/functions/pci-epf-vcon.c
new file mode 100644
index 000000000000..39538133e39d
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-vcon.c
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint function driver to impliment virtio-console device
+ * functionality.
+ */
+#include <linux/pci-epf.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_pci.h>
+#include <linux/virtio_console.h>
+#include <linux/virtio_ring.h>
+
+#include "pci-epf-virtio.h"
+
+static int virtio_queue_size = 0x100;
+module_param(virtio_queue_size, int, 0444);
+MODULE_PARM_DESC(virtio_queue_size, "A length of virtqueue");
+
+struct epf_vcon {
+	/* To access virtqueues on remote host */
+	struct epf_virtio evio;
+	struct vringh_kiov *rdev_iovs;
+
+	/* To register a local virtio bus */
+	struct virtio_device vdev;
+
+	/* To access virtqueus of local host driver */
+	struct vringh *vdev_vrhs;
+	struct vringh_kiov *vdev_iovs;
+	struct virtqueue **vdev_vqs;
+
+	/* For transportation and notification */
+	struct workqueue_struct *task_wq;
+	struct work_struct raise_irq_work, rx_work, tx_work;
+
+	/* To retain virtio features. It is commonly used local and remote. */
+	u64 features;
+
+	/* To show a status whether this driver is ready and the remote is connected */
+	bool connected;
+};
+
+enum {
+	VCON_VIRTQUEUE_RX,
+	VCON_VIRTQUEUE_TX,
+};
+
+static struct epf_vcon *vdev_to_vcon(struct virtio_device *vdev)
+{
+	return container_of(vdev, struct epf_vcon, vdev);
+}
+
+static unsigned int epf_vcon_get_nvq(struct epf_vcon *vcon)
+{
+	/* This is a minimum implementation. Doesn't support any features of
+	 * virtio console. It means driver and device use just 2 virtuque for tx
+	 * and rx.
+	 */
+	return 2;
+}
+
+static void epf_vcon_rx_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon = container_of(work, struct epf_vcon, rx_work);
+	struct epf_virtio *evio = &vcon->evio;
+	struct vringh *svrh, *dvrh;
+	struct vringh_kiov *siov, *diov;
+	int ret;
+
+	if (unlikely(!vcon->connected))
+		return;
+
+	svrh = &evio->vrhs[VCON_VIRTQUEUE_TX]->vrh;
+	dvrh = &vcon->vdev_vrhs[VCON_VIRTQUEUE_RX];
+	siov = &vcon->rdev_iovs[VCON_VIRTQUEUE_TX];
+	diov = &vcon->vdev_iovs[VCON_VIRTQUEUE_RX];
+
+	do {
+		ret = epf_virtio_vrh_memcpy(evio, svrh, siov, dvrh, diov,
+					    EPF_VIRTIO_COPY_DIR_FROM_DEV);
+		if (unlikely(ret < 0))
+			pr_err("failed to copy desc on virtqueue for rx\n");
+	} while (ret > 0);
+
+	vring_interrupt(0, vcon->vdev_vqs[VCON_VIRTQUEUE_RX]);
+}
+
+static void epf_vcon_tx_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon = container_of(work, struct epf_vcon, tx_work);
+	struct epf_virtio *evio = &vcon->evio;
+	struct vringh *svrh, *dvrh;
+	struct vringh_kiov *siov, *diov;
+	int ret;
+
+	if (unlikely(!vcon->connected))
+		return;
+
+	svrh = &vcon->vdev_vrhs[VCON_VIRTQUEUE_TX];
+	dvrh = &evio->vrhs[VCON_VIRTQUEUE_RX]->vrh;
+	siov = &vcon->vdev_iovs[VCON_VIRTQUEUE_TX];
+	diov = &vcon->rdev_iovs[VCON_VIRTQUEUE_RX];
+
+	do {
+		ret = epf_virtio_vrh_memcpy(evio, svrh, siov, dvrh, diov,
+					    EPF_VIRTIO_COPY_DIR_TO_DEV);
+		if (unlikely(ret < 0))
+			pr_err("failed to copy desc on virtqueue for tx\n");
+	} while (ret > 0);
+
+	queue_work(vcon->task_wq, &vcon->raise_irq_work);
+}
+
+static void epf_vcon_raise_irq_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon =
+		container_of(work, struct epf_vcon, raise_irq_work);
+	struct pci_epf *epf = vcon->evio.epf;
+
+	pci_epc_raise_irq(epf->epc, epf->func_no, epf->vfunc_no,
+			  PCI_EPC_IRQ_LEGACY, 0);
+}
+
+static int epf_vcon_setup_common(struct epf_vcon *vcon)
+{
+	vcon->features = 0;
+	vcon->connected = false;
+
+	vcon->task_wq =
+		alloc_workqueue("pci-epf-vcon/task-wq",
+				WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_UNBOUND, 0);
+	if (!vcon->task_wq)
+		return -ENOMEM;
+
+	INIT_WORK(&vcon->rx_work, epf_vcon_rx_handler);
+	INIT_WORK(&vcon->tx_work, epf_vcon_tx_handler);
+	INIT_WORK(&vcon->raise_irq_work, epf_vcon_raise_irq_handler);
+
+	return 0;
+}
+
+static void epf_vcon_cleanup_common(struct epf_vcon *vcon)
+{
+	/* Should do first to stop polling in other kernel thread */
+	vcon->connected = false;
+
+	flush_work(&vcon->raise_irq_work);
+	flush_work(&vcon->tx_work);
+	flush_work(&vcon->rx_work);
+
+	destroy_workqueue(vcon->task_wq);
+}
+
+static void epf_vcon_qnotify_callback(void *param)
+{
+	struct epf_vcon *vcon = param;
+
+	queue_work(vcon->task_wq, &vcon->rx_work);
+}
+
+static void epf_vcon_initialize_complete(void *param)
+{
+	struct epf_vcon *vcon = param;
+
+	pr_debug("Remote host has connected\n");
+
+	vcon->connected = true;
+
+	/* send filled buffer */
+	queue_work(vcon->task_wq, &vcon->tx_work);
+}
+
+static struct pci_epf_header epf_vcon_pci_header = {
+	.vendorid = PCI_VENDOR_ID_REDHAT_QUMRANET,
+	.deviceid = VIRTIO_TRANS_ID_CONSOLE,
+	.subsys_vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+	.subsys_id = VIRTIO_ID_CONSOLE,
+	.revid = 0,
+	.baseclass_code = PCI_BASE_CLASS_COMMUNICATION,
+	.interrupt_pin = PCI_INTERRUPT_PIN,
+};
+
+static int epf_vcon_setup_ep_func(struct epf_vcon *vcon, struct pci_epf *epf)
+{
+	int err;
+	struct epf_virtio *evio = &vcon->evio;
+	unsigned int nvq = epf_vcon_get_nvq(vcon);
+
+	vcon->rdev_iovs =
+		kmalloc_array(nvq, sizeof(vcon->rdev_iovs[0]), GFP_KERNEL);
+	if (!vcon->rdev_iovs)
+		return -ENOMEM;
+
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_init(&vcon->rdev_iovs[i], NULL, 0);
+
+	evio->epf = epf;
+	evio->features = vcon->features;
+	evio->nvq = nvq;
+	evio->vqlen = virtio_queue_size;
+
+	evio->qn_callback = epf_vcon_qnotify_callback;
+	evio->qn_param = vcon;
+
+	evio->ic_callback = epf_vcon_initialize_complete;
+	evio->ic_param = vcon;
+
+	err = epf_virtio_init(evio, &epf_vcon_pci_header, 0);
+	if (err)
+		goto err_cleanup_kiov;
+
+	err = epf_virtio_launch_bgtask(evio);
+	if (err)
+		goto err_virtio_final;
+
+	return 0;
+
+err_virtio_final:
+	epf_virtio_final(evio);
+
+err_cleanup_kiov:
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_cleanup(&vcon->rdev_iovs[i]);
+
+	kfree(vcon->rdev_iovs);
+
+	return err;
+}
+
+static void epf_vcon_cleanup_ep_func(struct epf_vcon *vcon)
+{
+	epf_virtio_terminate_bgtask(&vcon->evio);
+
+	epf_virtio_final(&vcon->evio);
+
+	kfree(vcon->rdev_iovs);
+}
+
+/*
+ * Functions for local virtio device operation
+ */
+static u64 epf_vcon_vdev_get_features(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	return vcon->features;
+}
+
+static int epf_vcon_vdev_finalize_features(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	return vdev->features != vcon->features;
+}
+
+static void epf_vcon_vdev_get_config(struct virtio_device *vdev,
+				     unsigned int offset, void *buf,
+				     unsigned int len)
+{
+	/* There is no config for virtio console because this console device
+	 * doesn't any support features
+	 */
+	memset(buf, 0x00, len);
+}
+
+static void epf_vcon_vdev_set_config(struct virtio_device *vdev,
+				     unsigned int offset, const void *buf,
+				     unsigned int len)
+{
+	/* Do nothing because this console device doesn't any support features */
+}
+
+static u8 epf_vcon_vdev_get_status(struct virtio_device *vdev)
+{
+	return 0;
+}
+
+static void epf_vcon_vdev_set_status(struct virtio_device *vdev, u8 status)
+{
+	if (status & VIRTIO_CONFIG_S_FAILED)
+		pr_debug("driver failed to setup this device\n");
+}
+
+static void epf_vcon_vdev_reset(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	epf_virtio_reset(&vcon->evio);
+}
+
+static bool epf_vcon_vdev_vq_notify(struct virtqueue *vq)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vq->vdev);
+
+	switch (vq->index) {
+	case VCON_VIRTQUEUE_RX:
+	case VCON_VIRTQUEUE_TX:
+		queue_work(vcon->task_wq, &vcon->tx_work);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static int epf_vcon_vdev_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
+				  struct virtqueue *vqs[],
+				  vq_callback_t *callback[],
+				  const char *const names[], const bool *ctx,
+				  struct irq_affinity *desc)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+	int err;
+	int qidx, i;
+
+	if (nvqs > epf_vcon_get_nvq(vcon))
+		return -EINVAL;
+
+	for (qidx = 0, i = 0; i < nvqs; i++) {
+		struct virtqueue *vq;
+		const struct vring *vring;
+
+		if (!names[i]) {
+			vqs[i] = NULL;
+			continue;
+		}
+
+		vq = vring_create_virtqueue(qidx++, virtio_queue_size,
+					    VIRTIO_PCI_VRING_ALIGN, vdev, true,
+					    false, ctx ? ctx[i] : false,
+					    epf_vcon_vdev_vq_notify,
+					    callback[i], names[i]);
+		if (!vq) {
+			err = -ENOMEM;
+			goto err_del_vqs;
+		}
+
+		vqs[i] = vq;
+		vcon->vdev_vqs[i] = vq;
+
+		vring = virtqueue_get_vring(vq);
+		err = vringh_init_kern(&vcon->vdev_vrhs[i], vcon->features,
+				       virtio_queue_size, false, GFP_KERNEL,
+				       vring->desc, vring->avail, vring->used);
+		if (err) {
+			pr_err("failed to init vringh for vring %d\n", i);
+			goto err_del_vqs;
+		}
+	}
+
+	return 0;
+
+err_del_vqs:
+	for (; i >= 0; i--) {
+		if (!names[i])
+			continue;
+
+		if (!vqs[i])
+			continue;
+
+		vring_del_virtqueue(vqs[i]);
+	}
+	return err;
+}
+
+static void epf_vcon_vdev_del_vqs(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	for (int i = 0; i < epf_vcon_get_nvq(vcon); i++) {
+		if (!vcon->vdev_vqs[i])
+			continue;
+
+		vring_del_virtqueue(vcon->vdev_vqs[i]);
+	}
+}
+
+static const struct virtio_config_ops epf_vcon_vdev_config_ops = {
+	.get_features = epf_vcon_vdev_get_features,
+	.finalize_features = epf_vcon_vdev_finalize_features,
+	.get = epf_vcon_vdev_get_config,
+	.set = epf_vcon_vdev_set_config,
+	.get_status = epf_vcon_vdev_get_status,
+	.set_status = epf_vcon_vdev_set_status,
+	.reset = epf_vcon_vdev_reset,
+	.find_vqs = epf_vcon_vdev_find_vqs,
+	.del_vqs = epf_vcon_vdev_del_vqs,
+};
+
+static void epf_vcon_vdev_release(struct device *dev)
+{
+	/* Do nothing, because the struct virtio_device will be reused. */
+}
+
+static int epf_vcon_setup_vdev(struct epf_vcon *vcon, struct device *parent)
+{
+	int err;
+	struct virtio_device *vdev = &vcon->vdev;
+	const unsigned int nvq = epf_vcon_get_nvq(vcon);
+
+	vcon->vdev_vrhs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_vrhs[0]), GFP_KERNEL);
+	if (!vcon->vdev_vrhs)
+		return -ENOMEM;
+
+	vcon->vdev_iovs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_iovs[0]), GFP_KERNEL);
+	if (!vcon->vdev_iovs) {
+		err = -ENOMEM;
+		goto err_free_vrhs;
+	}
+
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_init(&vcon->vdev_iovs[i], NULL, 0);
+
+	vcon->vdev_vqs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_vrhs[0]), GFP_KERNEL);
+	if (!vcon->vdev_vqs) {
+		err = -ENOMEM;
+		goto err_cleanup_kiov;
+	}
+
+	vdev->dev.parent = parent;
+	vdev->dev.release = epf_vcon_vdev_release;
+	vdev->config = &epf_vcon_vdev_config_ops;
+	vdev->id.vendor = PCI_VENDOR_ID_REDHAT_QUMRANET;
+	vdev->id.device = VIRTIO_ID_CONSOLE;
+
+	err = register_virtio_device(vdev);
+	if (err)
+		goto err_free_vdev_vqs;
+
+	return 0;
+
+err_free_vdev_vqs:
+	kfree(vcon->vdev_vqs);
+
+err_cleanup_kiov:
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_cleanup(&vcon->vdev_iovs[i]);
+
+	kfree(vcon->vdev_iovs);
+
+err_free_vrhs:
+	kfree(vcon->vdev_vrhs);
+
+	return err;
+}
+
+static void epf_vcon_cleanup_vdev(struct epf_vcon *vcon)
+{
+	unregister_virtio_device(&vcon->vdev);
+	/* Cleanup struct virtio_device that has kobject, otherwise error occures when
+	 * reregister the virtio device.
+	 */
+	memset(&vcon->vdev, 0x00, sizeof(vcon->vdev));
+
+	kfree(vcon->vdev_vqs);
+
+	for (int i = 0; i < epf_vcon_get_nvq(vcon); i++)
+		vringh_kiov_cleanup(&vcon->vdev_iovs[i]);
+
+	kfree(vcon->vdev_iovs);
+	kfree(vcon->vdev_vrhs);
+}
+
+static int epf_vcon_bind(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon = epf_get_drvdata(epf);
+	int err;
+
+	err = epf_vcon_setup_common(vcon);
+	if (err)
+		return err;
+
+	err = epf_vcon_setup_ep_func(vcon, epf);
+	if (err)
+		goto err_cleanup_common;
+
+	err = epf_vcon_setup_vdev(vcon, epf->epc->dev.parent);
+	if (err)
+		goto err_cleanup_ep_func;
+
+	return 0;
+
+err_cleanup_common:
+	epf_vcon_cleanup_common(vcon);
+
+err_cleanup_ep_func:
+	epf_vcon_cleanup_ep_func(vcon);
+
+	return err;
+}
+
+static void epf_vcon_unbind(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon = epf_get_drvdata(epf);
+
+	epf_vcon_cleanup_common(vcon);
+	epf_vcon_cleanup_ep_func(vcon);
+	epf_vcon_cleanup_vdev(vcon);
+}
+
+static struct pci_epf_ops epf_vcon_ops = {
+	.bind = epf_vcon_bind,
+	.unbind = epf_vcon_unbind,
+};
+
+static const struct pci_epf_device_id epf_vcon_ids[] = {
+	{ .name = "pci_epf_vcon" },
+	{}
+};
+
+static int epf_vcon_probe(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon;
+
+	vcon = devm_kzalloc(&epf->dev, sizeof(*vcon), GFP_KERNEL);
+	if (!vcon)
+		return -ENOMEM;
+
+	epf_set_drvdata(epf, vcon);
+
+	return 0;
+}
+
+static struct pci_epf_driver epf_vcon_drv = {
+	.driver.name = "pci_epf_vcon",
+	.ops = &epf_vcon_ops,
+	.id_table = epf_vcon_ids,
+	.probe = epf_vcon_probe,
+	.owner = THIS_MODULE,
+};
+
+static int __init epf_vcon_init(void)
+{
+	int err;
+
+	err = pci_epf_register_driver(&epf_vcon_drv);
+	if (err)
+		pr_err("Failed to register PCI EP virtio-console function\n");
+
+	return 0;
+}
+module_init(epf_vcon_init);
+
+static void epf_vcon_exit(void)
+{
+	pci_epf_unregister_driver(&epf_vcon_drv);
+}
+module_exit(epf_vcon_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Shunsuke Mie <mie@igel.co.jp>");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
@ 2023-04-14 12:39   ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-14 12:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam, Frank Li,
	linux-kernel, virtualization, Ren Zhijie, Shunsuke Mie,
	Jon Mason, Bjorn Helgaas

Add a new PCIe endpoint function driver that works as a pci virtio-console
device. The console connect to endpoint side console. It enables to
communicate PCIe host and endpoint.

Architecture is following:

 ┌────────────┐         ┌──────────────────────┬────────────┐
 │virtioe     │         │                      │virtio      │
 │console drv │         ├───────────────┐      │console drv │
 ├────────────┤         │(virtio console│      ├────────────┤
 │ virtio bus │         │ device)       │◄────►│ virtio bus │
 ├────────────┤         ├---------------┤      └────────────┤
 │            │         │ pci ep virtio │                   │
 │  pci bus   │         │  console drv  │                   │
 │            │  pcie   ├───────────────┤                   │
 │            │ ◄─────► │  pci ep Bus   │                   │
 └────────────┘         └───────────────┴───────────────────┘
   PCIe Root              PCIe Endpoint

This driver has two roles. The first is as a PCIe endpoint virtio console
function, which is implemented using the PCIe endpoint framework and PCIe
EP virtio helpers. The second is as a virtual virtio console device
connected to the virtio bus on PCIe endpoint Linux.

Communication between the two is achieved by copying the virtqueue data
between PCIe root and endpoint, respectively.

This is a simple implementation and does not include features of
virtio-console such as MULTIPORT, EMERG_WRITE, etc. As a result, each
virtio console driver only displays /dev/hvc0.

As an example of usage, by setting getty to /dev/hvc0, it is possible to
login to another host.

Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
---
 drivers/pci/endpoint/functions/Kconfig        |  12 +
 drivers/pci/endpoint/functions/Makefile       |   1 +
 drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
 3 files changed, 567 insertions(+)
 create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c

diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index cf16d33c9585..890e07b51cbe 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -44,3 +44,15 @@ config PCI_EPF_VIRTIO
 	select VHOST_IOMEM
 	help
 	  Helpers to implement PCI virtio Endpoint function
+
+config PCI_EPF_VCON
+	tristate "PCI Endpoint virito-console driver"
+	depends on PCI_ENDPOINT
+	select VHOST_RING
+	select PCI_EPF_VIRTIO
+	help
+	  PCIe Endpoint virtio-console function implementatino. This module
+	  enables to show the virtio-console as pci device to PCIe host side, and
+	  another virtual virtio-console device registers to endpoint system.
+	  Those devices are connected virtually and can communicate each other.
+
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index a96f127ce900..b4056689ce33 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_PCI_EPF_TEST)		+= pci-epf-test.o
 obj-$(CONFIG_PCI_EPF_NTB)		+= pci-epf-ntb.o
 obj-$(CONFIG_PCI_EPF_VNTB) 		+= pci-epf-vntb.o
 obj-$(CONFIG_PCI_EPF_VIRTIO)		+= pci-epf-virtio.o
+obj-$(CONFIG_PCI_EPF_VCON)		+= pci-epf-vcon.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-vcon.c b/drivers/pci/endpoint/functions/pci-epf-vcon.c
new file mode 100644
index 000000000000..39538133e39d
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-vcon.c
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint function driver to impliment virtio-console device
+ * functionality.
+ */
+#include <linux/pci-epf.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_pci.h>
+#include <linux/virtio_console.h>
+#include <linux/virtio_ring.h>
+
+#include "pci-epf-virtio.h"
+
+static int virtio_queue_size = 0x100;
+module_param(virtio_queue_size, int, 0444);
+MODULE_PARM_DESC(virtio_queue_size, "A length of virtqueue");
+
+struct epf_vcon {
+	/* To access virtqueues on remote host */
+	struct epf_virtio evio;
+	struct vringh_kiov *rdev_iovs;
+
+	/* To register a local virtio bus */
+	struct virtio_device vdev;
+
+	/* To access virtqueus of local host driver */
+	struct vringh *vdev_vrhs;
+	struct vringh_kiov *vdev_iovs;
+	struct virtqueue **vdev_vqs;
+
+	/* For transportation and notification */
+	struct workqueue_struct *task_wq;
+	struct work_struct raise_irq_work, rx_work, tx_work;
+
+	/* To retain virtio features. It is commonly used local and remote. */
+	u64 features;
+
+	/* To show a status whether this driver is ready and the remote is connected */
+	bool connected;
+};
+
+enum {
+	VCON_VIRTQUEUE_RX,
+	VCON_VIRTQUEUE_TX,
+};
+
+static struct epf_vcon *vdev_to_vcon(struct virtio_device *vdev)
+{
+	return container_of(vdev, struct epf_vcon, vdev);
+}
+
+static unsigned int epf_vcon_get_nvq(struct epf_vcon *vcon)
+{
+	/* This is a minimum implementation. Doesn't support any features of
+	 * virtio console. It means driver and device use just 2 virtuque for tx
+	 * and rx.
+	 */
+	return 2;
+}
+
+static void epf_vcon_rx_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon = container_of(work, struct epf_vcon, rx_work);
+	struct epf_virtio *evio = &vcon->evio;
+	struct vringh *svrh, *dvrh;
+	struct vringh_kiov *siov, *diov;
+	int ret;
+
+	if (unlikely(!vcon->connected))
+		return;
+
+	svrh = &evio->vrhs[VCON_VIRTQUEUE_TX]->vrh;
+	dvrh = &vcon->vdev_vrhs[VCON_VIRTQUEUE_RX];
+	siov = &vcon->rdev_iovs[VCON_VIRTQUEUE_TX];
+	diov = &vcon->vdev_iovs[VCON_VIRTQUEUE_RX];
+
+	do {
+		ret = epf_virtio_vrh_memcpy(evio, svrh, siov, dvrh, diov,
+					    EPF_VIRTIO_COPY_DIR_FROM_DEV);
+		if (unlikely(ret < 0))
+			pr_err("failed to copy desc on virtqueue for rx\n");
+	} while (ret > 0);
+
+	vring_interrupt(0, vcon->vdev_vqs[VCON_VIRTQUEUE_RX]);
+}
+
+static void epf_vcon_tx_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon = container_of(work, struct epf_vcon, tx_work);
+	struct epf_virtio *evio = &vcon->evio;
+	struct vringh *svrh, *dvrh;
+	struct vringh_kiov *siov, *diov;
+	int ret;
+
+	if (unlikely(!vcon->connected))
+		return;
+
+	svrh = &vcon->vdev_vrhs[VCON_VIRTQUEUE_TX];
+	dvrh = &evio->vrhs[VCON_VIRTQUEUE_RX]->vrh;
+	siov = &vcon->vdev_iovs[VCON_VIRTQUEUE_TX];
+	diov = &vcon->rdev_iovs[VCON_VIRTQUEUE_RX];
+
+	do {
+		ret = epf_virtio_vrh_memcpy(evio, svrh, siov, dvrh, diov,
+					    EPF_VIRTIO_COPY_DIR_TO_DEV);
+		if (unlikely(ret < 0))
+			pr_err("failed to copy desc on virtqueue for tx\n");
+	} while (ret > 0);
+
+	queue_work(vcon->task_wq, &vcon->raise_irq_work);
+}
+
+static void epf_vcon_raise_irq_handler(struct work_struct *work)
+{
+	struct epf_vcon *vcon =
+		container_of(work, struct epf_vcon, raise_irq_work);
+	struct pci_epf *epf = vcon->evio.epf;
+
+	pci_epc_raise_irq(epf->epc, epf->func_no, epf->vfunc_no,
+			  PCI_EPC_IRQ_LEGACY, 0);
+}
+
+static int epf_vcon_setup_common(struct epf_vcon *vcon)
+{
+	vcon->features = 0;
+	vcon->connected = false;
+
+	vcon->task_wq =
+		alloc_workqueue("pci-epf-vcon/task-wq",
+				WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_UNBOUND, 0);
+	if (!vcon->task_wq)
+		return -ENOMEM;
+
+	INIT_WORK(&vcon->rx_work, epf_vcon_rx_handler);
+	INIT_WORK(&vcon->tx_work, epf_vcon_tx_handler);
+	INIT_WORK(&vcon->raise_irq_work, epf_vcon_raise_irq_handler);
+
+	return 0;
+}
+
+static void epf_vcon_cleanup_common(struct epf_vcon *vcon)
+{
+	/* Should do first to stop polling in other kernel thread */
+	vcon->connected = false;
+
+	flush_work(&vcon->raise_irq_work);
+	flush_work(&vcon->tx_work);
+	flush_work(&vcon->rx_work);
+
+	destroy_workqueue(vcon->task_wq);
+}
+
+static void epf_vcon_qnotify_callback(void *param)
+{
+	struct epf_vcon *vcon = param;
+
+	queue_work(vcon->task_wq, &vcon->rx_work);
+}
+
+static void epf_vcon_initialize_complete(void *param)
+{
+	struct epf_vcon *vcon = param;
+
+	pr_debug("Remote host has connected\n");
+
+	vcon->connected = true;
+
+	/* send filled buffer */
+	queue_work(vcon->task_wq, &vcon->tx_work);
+}
+
+static struct pci_epf_header epf_vcon_pci_header = {
+	.vendorid = PCI_VENDOR_ID_REDHAT_QUMRANET,
+	.deviceid = VIRTIO_TRANS_ID_CONSOLE,
+	.subsys_vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+	.subsys_id = VIRTIO_ID_CONSOLE,
+	.revid = 0,
+	.baseclass_code = PCI_BASE_CLASS_COMMUNICATION,
+	.interrupt_pin = PCI_INTERRUPT_PIN,
+};
+
+static int epf_vcon_setup_ep_func(struct epf_vcon *vcon, struct pci_epf *epf)
+{
+	int err;
+	struct epf_virtio *evio = &vcon->evio;
+	unsigned int nvq = epf_vcon_get_nvq(vcon);
+
+	vcon->rdev_iovs =
+		kmalloc_array(nvq, sizeof(vcon->rdev_iovs[0]), GFP_KERNEL);
+	if (!vcon->rdev_iovs)
+		return -ENOMEM;
+
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_init(&vcon->rdev_iovs[i], NULL, 0);
+
+	evio->epf = epf;
+	evio->features = vcon->features;
+	evio->nvq = nvq;
+	evio->vqlen = virtio_queue_size;
+
+	evio->qn_callback = epf_vcon_qnotify_callback;
+	evio->qn_param = vcon;
+
+	evio->ic_callback = epf_vcon_initialize_complete;
+	evio->ic_param = vcon;
+
+	err = epf_virtio_init(evio, &epf_vcon_pci_header, 0);
+	if (err)
+		goto err_cleanup_kiov;
+
+	err = epf_virtio_launch_bgtask(evio);
+	if (err)
+		goto err_virtio_final;
+
+	return 0;
+
+err_virtio_final:
+	epf_virtio_final(evio);
+
+err_cleanup_kiov:
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_cleanup(&vcon->rdev_iovs[i]);
+
+	kfree(vcon->rdev_iovs);
+
+	return err;
+}
+
+static void epf_vcon_cleanup_ep_func(struct epf_vcon *vcon)
+{
+	epf_virtio_terminate_bgtask(&vcon->evio);
+
+	epf_virtio_final(&vcon->evio);
+
+	kfree(vcon->rdev_iovs);
+}
+
+/*
+ * Functions for local virtio device operation
+ */
+static u64 epf_vcon_vdev_get_features(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	return vcon->features;
+}
+
+static int epf_vcon_vdev_finalize_features(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	return vdev->features != vcon->features;
+}
+
+static void epf_vcon_vdev_get_config(struct virtio_device *vdev,
+				     unsigned int offset, void *buf,
+				     unsigned int len)
+{
+	/* There is no config for virtio console because this console device
+	 * doesn't any support features
+	 */
+	memset(buf, 0x00, len);
+}
+
+static void epf_vcon_vdev_set_config(struct virtio_device *vdev,
+				     unsigned int offset, const void *buf,
+				     unsigned int len)
+{
+	/* Do nothing because this console device doesn't any support features */
+}
+
+static u8 epf_vcon_vdev_get_status(struct virtio_device *vdev)
+{
+	return 0;
+}
+
+static void epf_vcon_vdev_set_status(struct virtio_device *vdev, u8 status)
+{
+	if (status & VIRTIO_CONFIG_S_FAILED)
+		pr_debug("driver failed to setup this device\n");
+}
+
+static void epf_vcon_vdev_reset(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	epf_virtio_reset(&vcon->evio);
+}
+
+static bool epf_vcon_vdev_vq_notify(struct virtqueue *vq)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vq->vdev);
+
+	switch (vq->index) {
+	case VCON_VIRTQUEUE_RX:
+	case VCON_VIRTQUEUE_TX:
+		queue_work(vcon->task_wq, &vcon->tx_work);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static int epf_vcon_vdev_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
+				  struct virtqueue *vqs[],
+				  vq_callback_t *callback[],
+				  const char *const names[], const bool *ctx,
+				  struct irq_affinity *desc)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+	int err;
+	int qidx, i;
+
+	if (nvqs > epf_vcon_get_nvq(vcon))
+		return -EINVAL;
+
+	for (qidx = 0, i = 0; i < nvqs; i++) {
+		struct virtqueue *vq;
+		const struct vring *vring;
+
+		if (!names[i]) {
+			vqs[i] = NULL;
+			continue;
+		}
+
+		vq = vring_create_virtqueue(qidx++, virtio_queue_size,
+					    VIRTIO_PCI_VRING_ALIGN, vdev, true,
+					    false, ctx ? ctx[i] : false,
+					    epf_vcon_vdev_vq_notify,
+					    callback[i], names[i]);
+		if (!vq) {
+			err = -ENOMEM;
+			goto err_del_vqs;
+		}
+
+		vqs[i] = vq;
+		vcon->vdev_vqs[i] = vq;
+
+		vring = virtqueue_get_vring(vq);
+		err = vringh_init_kern(&vcon->vdev_vrhs[i], vcon->features,
+				       virtio_queue_size, false, GFP_KERNEL,
+				       vring->desc, vring->avail, vring->used);
+		if (err) {
+			pr_err("failed to init vringh for vring %d\n", i);
+			goto err_del_vqs;
+		}
+	}
+
+	return 0;
+
+err_del_vqs:
+	for (; i >= 0; i--) {
+		if (!names[i])
+			continue;
+
+		if (!vqs[i])
+			continue;
+
+		vring_del_virtqueue(vqs[i]);
+	}
+	return err;
+}
+
+static void epf_vcon_vdev_del_vqs(struct virtio_device *vdev)
+{
+	struct epf_vcon *vcon = vdev_to_vcon(vdev);
+
+	for (int i = 0; i < epf_vcon_get_nvq(vcon); i++) {
+		if (!vcon->vdev_vqs[i])
+			continue;
+
+		vring_del_virtqueue(vcon->vdev_vqs[i]);
+	}
+}
+
+static const struct virtio_config_ops epf_vcon_vdev_config_ops = {
+	.get_features = epf_vcon_vdev_get_features,
+	.finalize_features = epf_vcon_vdev_finalize_features,
+	.get = epf_vcon_vdev_get_config,
+	.set = epf_vcon_vdev_set_config,
+	.get_status = epf_vcon_vdev_get_status,
+	.set_status = epf_vcon_vdev_set_status,
+	.reset = epf_vcon_vdev_reset,
+	.find_vqs = epf_vcon_vdev_find_vqs,
+	.del_vqs = epf_vcon_vdev_del_vqs,
+};
+
+static void epf_vcon_vdev_release(struct device *dev)
+{
+	/* Do nothing, because the struct virtio_device will be reused. */
+}
+
+static int epf_vcon_setup_vdev(struct epf_vcon *vcon, struct device *parent)
+{
+	int err;
+	struct virtio_device *vdev = &vcon->vdev;
+	const unsigned int nvq = epf_vcon_get_nvq(vcon);
+
+	vcon->vdev_vrhs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_vrhs[0]), GFP_KERNEL);
+	if (!vcon->vdev_vrhs)
+		return -ENOMEM;
+
+	vcon->vdev_iovs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_iovs[0]), GFP_KERNEL);
+	if (!vcon->vdev_iovs) {
+		err = -ENOMEM;
+		goto err_free_vrhs;
+	}
+
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_init(&vcon->vdev_iovs[i], NULL, 0);
+
+	vcon->vdev_vqs =
+		kmalloc_array(nvq, sizeof(vcon->vdev_vrhs[0]), GFP_KERNEL);
+	if (!vcon->vdev_vqs) {
+		err = -ENOMEM;
+		goto err_cleanup_kiov;
+	}
+
+	vdev->dev.parent = parent;
+	vdev->dev.release = epf_vcon_vdev_release;
+	vdev->config = &epf_vcon_vdev_config_ops;
+	vdev->id.vendor = PCI_VENDOR_ID_REDHAT_QUMRANET;
+	vdev->id.device = VIRTIO_ID_CONSOLE;
+
+	err = register_virtio_device(vdev);
+	if (err)
+		goto err_free_vdev_vqs;
+
+	return 0;
+
+err_free_vdev_vqs:
+	kfree(vcon->vdev_vqs);
+
+err_cleanup_kiov:
+	for (int i = 0; i < nvq; i++)
+		vringh_kiov_cleanup(&vcon->vdev_iovs[i]);
+
+	kfree(vcon->vdev_iovs);
+
+err_free_vrhs:
+	kfree(vcon->vdev_vrhs);
+
+	return err;
+}
+
+static void epf_vcon_cleanup_vdev(struct epf_vcon *vcon)
+{
+	unregister_virtio_device(&vcon->vdev);
+	/* Cleanup struct virtio_device that has kobject, otherwise error occures when
+	 * reregister the virtio device.
+	 */
+	memset(&vcon->vdev, 0x00, sizeof(vcon->vdev));
+
+	kfree(vcon->vdev_vqs);
+
+	for (int i = 0; i < epf_vcon_get_nvq(vcon); i++)
+		vringh_kiov_cleanup(&vcon->vdev_iovs[i]);
+
+	kfree(vcon->vdev_iovs);
+	kfree(vcon->vdev_vrhs);
+}
+
+static int epf_vcon_bind(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon = epf_get_drvdata(epf);
+	int err;
+
+	err = epf_vcon_setup_common(vcon);
+	if (err)
+		return err;
+
+	err = epf_vcon_setup_ep_func(vcon, epf);
+	if (err)
+		goto err_cleanup_common;
+
+	err = epf_vcon_setup_vdev(vcon, epf->epc->dev.parent);
+	if (err)
+		goto err_cleanup_ep_func;
+
+	return 0;
+
+err_cleanup_common:
+	epf_vcon_cleanup_common(vcon);
+
+err_cleanup_ep_func:
+	epf_vcon_cleanup_ep_func(vcon);
+
+	return err;
+}
+
+static void epf_vcon_unbind(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon = epf_get_drvdata(epf);
+
+	epf_vcon_cleanup_common(vcon);
+	epf_vcon_cleanup_ep_func(vcon);
+	epf_vcon_cleanup_vdev(vcon);
+}
+
+static struct pci_epf_ops epf_vcon_ops = {
+	.bind = epf_vcon_bind,
+	.unbind = epf_vcon_unbind,
+};
+
+static const struct pci_epf_device_id epf_vcon_ids[] = {
+	{ .name = "pci_epf_vcon" },
+	{}
+};
+
+static int epf_vcon_probe(struct pci_epf *epf)
+{
+	struct epf_vcon *vcon;
+
+	vcon = devm_kzalloc(&epf->dev, sizeof(*vcon), GFP_KERNEL);
+	if (!vcon)
+		return -ENOMEM;
+
+	epf_set_drvdata(epf, vcon);
+
+	return 0;
+}
+
+static struct pci_epf_driver epf_vcon_drv = {
+	.driver.name = "pci_epf_vcon",
+	.ops = &epf_vcon_ops,
+	.id_table = epf_vcon_ids,
+	.probe = epf_vcon_probe,
+	.owner = THIS_MODULE,
+};
+
+static int __init epf_vcon_init(void)
+{
+	int err;
+
+	err = pci_epf_register_driver(&epf_vcon_drv);
+	if (err)
+		pr_err("Failed to register PCI EP virtio-console function\n");
+
+	return 0;
+}
+module_init(epf_vcon_init);
+
+static void epf_vcon_exit(void)
+{
+	pci_epf_unregister_driver(&epf_vcon_drv);
+}
+module_exit(epf_vcon_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Shunsuke Mie <mie@igel.co.jp>");
-- 
2.25.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* RE: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-14 12:39 ` Shunsuke Mie
                   ` (3 preceding siblings ...)
  (?)
@ 2023-04-14 14:39 ` Frank Li
  2023-04-17  2:11     ` Shunsuke Mie
  -1 siblings, 1 reply; 19+ messages in thread
From: Frank Li @ 2023-04-14 14:39 UTC (permalink / raw)
  To: Shunsuke Mie, Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Jon Mason, Randy Dunlap, Ren Zhijie, linux-kernel,
	linux-pci, virtualization



> -----Original Message-----
> From: Shunsuke Mie <mie@igel.co.jp>
> Sent: Friday, April 14, 2023 7:39 AM
> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> virtualization@lists.linux-foundation.org
> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>
> Caution: EXT Email
>
> PCIe endpoint framework provides APIs to implement PCIe endpoint
> function.
> This framework allows defining various PCIe endpoint function behaviors in
> software. This patch extend the framework for virtio pci device. The
> virtio is defined to communicate guest on virtual machine and host side.
> Advantage of the virtio is the efficiency of data transfer and the conciseness
> of implementation device using software. It also be applied to PCIe
> endpoint function.
>
> We designed and implemented a PCIe EP virtio console function driver using
> the extended PCIe endpoint framework for virtio. It can be communicate
> host and endpoint over virtio as console.
>
> An architecture of the function driver is following:
>
>  ┌────────────┐         ┌──────────────
> ────────┬────────────┐
>  │virtio      │         │                      │virtio      │
>  │console drv │         ├───────────────┐      │console
> drv │
>  ├────────────┤         │(virtio console│      ├─────
> ───────┤
>  │ virtio bus │         │ device)       │◄────►│ virtio bus │
>  ├────────────┤         ├---------------┤      └──────
> ──────┤
>  │            │         │ pci ep virtio │                   │
>  │  pci bus   │         │  console drv  │                   │
>  │            │  pcie   ├───────────────┤                   │
>  │            │ ◄─────► │  pci ep Bus   │                   │
>  └────────────┘         └──────────────
> ─┴───────────────────┘
>    PCIe Root              PCIe Endpoint
>

[Frank Li] Some basic question,
I see you call register_virtio_device at epf_vcon_setup_vdev,
Why call it as virtio console?  I suppose it should be virtiobus directly?

Previous you use virtio-net, why change to virtio-console here?  Does it matter?
All virtio-XXX should work?

You removed EDMA support this version?


> Introduced driver is `pci ep virtio console drv` in the figure. It works
> as ep function for PCIe root and virtual virtio console device for PCIe
> endpoint. Each side of virtio console driver has virtqueue, and
> introduced driver transfers data on the virtqueue to each other. A data
> on root tx queue is transfered to endpoint rx queue and vice versa.
>
> This patchset is depend follwing patches which are under discussion.
>
> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
> link:
> https://lore.k/
> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mmsvo
> %3D&reserved=0
> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
> link:
> https://lore.k/
> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0%3
> D&reserved=0
>
> First of this patchset is introduce a helper function to realize pci
> virtio function using PCIe endpoint framework. The second one is adding
> a missing definition for virtio pci header. The last one is for PCIe
> endpoint virtio console driver.
>
> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
>
> Shunsuke Mie (3):
>   PCI: endpoint: introduce a helper to implement pci ep virtio function
>   virtio_pci: add a definition of queue flag in ISR
>   PCI: endpoint: Add EP function driver to provide virtio-console
>     functionality
>
>  drivers/pci/endpoint/functions/Kconfig        |  19 +
>  drivers/pci/endpoint/functions/Makefile       |   2 +
>  drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
>  .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
>  .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
>  include/uapi/linux/virtio_pci.h               |   3 +
>  6 files changed, 1170 insertions(+)
>  create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
>  create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
>  create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
>
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
  2023-04-14 12:39   ` Shunsuke Mie
  (?)
@ 2023-04-14 14:45   ` kernel test robot
  -1 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2023-04-14 14:45 UTC (permalink / raw)
  To: Shunsuke Mie; +Cc: oe-kbuild-all

Hi Shunsuke,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on pci/next]
[also build test ERROR on pci/for-linus linus/master v6.3-rc6 next-20230413]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shunsuke-Mie/PCI-endpoint-introduce-a-helper-to-implement-pci-ep-virtio-function/20230414-204118
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20230414123903.896914-4-mie%40igel.co.jp
patch subject: [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
config: riscv-allmodconfig (https://download.01.org/0day-ci/archive/20230414/202304142229.xxs56Ps0-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/1351b90fcb70907e50f3a8c6a4e4e978bd00cda0
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Shunsuke-Mie/PCI-endpoint-introduce-a-helper-to-implement-pci-ep-virtio-function/20230414-204118
        git checkout 1351b90fcb70907e50f3a8c6a4e4e978bd00cda0
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/pci/endpoint/functions/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304142229.xxs56Ps0-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_unmap_vq':
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:16:9: error: too many arguments to function 'pci_epc_unmap_addr'
      16 |         pci_epc_unmap_addr(epf->epc, epf->func_no, epf->vfunc_no, vq_phys,
         |         ^~~~~~~~~~~~~~~~~~
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_map_vq':
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:32:49: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
      32 |                                    vq_pci_addr, vq_phys, vq_size);
         |                                                 ^~~~~~~
         |                                                 |
         |                                                 phys_addr_t * {aka long long unsigned int *}
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'long long unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:31:17: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      31 |         vq_virt = pci_epc_map_addr(epf->epc, epf->func_no, epf->vfunc_no,
         |                 ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_alloc_vringh':
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:75:15: error: implicit declaration of function 'vringh_init_iomem'; did you mean 'vringh_init_iotlb'? [-Werror=implicit-function-declaration]
      75 |         err = vringh_init_iomem(&evrh->vrh, features, num, false, GFP_KERNEL,
         |               ^~~~~~~~~~~~~~~~~
         |               vringh_init_iotlb
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_vrh_memcpy':
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:402:15: error: implicit declaration of function 'vringh_getdesc'; did you mean 'vringh_getdesc_kern'? [-Werror=implicit-function-declaration]
     402 |         err = vringh_getdesc(svrh, siov, NULL, &shead);
         |               ^~~~~~~~~~~~~~
         |               vringh_getdesc_kern
   drivers/pci/endpoint/functions/pci-epf-virtio.c:431:72: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
     431 |                                                  epf->vfunc_no, sbase, &phys,
         |                                                                        ^~~~~
         |                                                                        |
         |                                                                        phys_addr_t * {aka long long unsigned int *}
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'long long unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:430:31: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     430 |                         svirt = pci_epc_map_addr(epf->epc, epf->func_no,
         |                               ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c:442:25: error: too many arguments to function 'pci_epc_unmap_addr'
     442 |                         pci_epc_unmap_addr(epf->epc, epf->func_no,
         |                         ^~~~~~~~~~~~~~~~~~
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:447:72: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
     447 |                                                  epf->vfunc_no, dbase, &phys,
         |                                                                        ^~~~~
         |                                                                        |
         |                                                                        phys_addr_t * {aka long long unsigned int *}
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'long long unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:446:31: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     446 |                         dvirt = pci_epc_map_addr(epf->epc, epf->func_no,
         |                               ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c:457:25: error: too many arguments to function 'pci_epc_unmap_addr'
     457 |                         pci_epc_unmap_addr(epf->epc, epf->func_no,
         |                         ^~~~~~~~~~~~~~~~~~
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:462:9: error: implicit declaration of function 'vringh_complete'; did you mean 'vringh_complete_kern'? [-Werror=implicit-function-declaration]
     462 |         vringh_complete(svrh, shead, total_len);
         |         ^~~~~~~~~~~~~~~
         |         vringh_complete_kern
   cc1: some warnings being treated as errors
--
   In file included from include/linux/cpumask.h:15,
                    from include/linux/smp.h:13,
                    from include/linux/lockdep.h:14,
                    from include/linux/spinlock.h:63,
                    from include/linux/kref.h:16,
                    from include/linux/configfs.h:25,
                    from include/linux/pci-epf.h:12,
                    from drivers/pci/endpoint/functions/pci-epf-vcon.c:6:
   drivers/pci/endpoint/functions/pci-epf-vcon.c: In function 'epf_vcon_vdev_find_vqs':
>> include/linux/gfp_types.h:329:25: warning: passing argument 5 of 'vringh_init_kern' makes pointer from integer without a cast [-Wint-conversion]
     329 | #define GFP_KERNEL      (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                         |
         |                         unsigned int
   drivers/pci/endpoint/functions/pci-epf-vcon.c:343:66: note: in expansion of macro 'GFP_KERNEL'
     343 |                                        virtio_queue_size, false, GFP_KERNEL,
         |                                                                  ^~~~~~~~~~
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:7,
                    from drivers/pci/endpoint/functions/pci-epf-vcon.c:12:
   include/linux/vringh.h:174:41: note: expected 'struct vring_desc *' but argument is of type 'unsigned int'
     174 |                      struct vring_desc *desc,
         |                      ~~~~~~~~~~~~~~~~~~~^~~~
>> drivers/pci/endpoint/functions/pci-epf-vcon.c:344:45: error: passing argument 6 of 'vringh_init_kern' from incompatible pointer type [-Werror=incompatible-pointer-types]
     344 |                                        vring->desc, vring->avail, vring->used);
         |                                        ~~~~~^~~~~~
         |                                             |
         |                                             vring_desc_t * {aka struct vring_desc *}
   include/linux/vringh.h:175:42: note: expected 'struct vring_avail *' but argument is of type 'vring_desc_t *' {aka 'struct vring_desc *'}
     175 |                      struct vring_avail *avail,
         |                      ~~~~~~~~~~~~~~~~~~~~^~~~~
   drivers/pci/endpoint/functions/pci-epf-vcon.c:344:58: error: passing argument 7 of 'vringh_init_kern' from incompatible pointer type [-Werror=incompatible-pointer-types]
     344 |                                        vring->desc, vring->avail, vring->used);
         |                                                     ~~~~~^~~~~~~
         |                                                          |
         |                                                          vring_avail_t * {aka struct vring_avail *}
   include/linux/vringh.h:176:41: note: expected 'struct vring_used *' but argument is of type 'vring_avail_t *' {aka 'struct vring_avail *'}
     176 |                      struct vring_used *used);
         |                      ~~~~~~~~~~~~~~~~~~~^~~~
>> drivers/pci/endpoint/functions/pci-epf-vcon.c:342:23: error: too many arguments to function 'vringh_init_kern'
     342 |                 err = vringh_init_kern(&vcon->vdev_vrhs[i], vcon->features,
         |                       ^~~~~~~~~~~~~~~~
   include/linux/vringh.h:172:5: note: declared here
     172 | int vringh_init_kern(struct vringh *vrh, u64 features,
         |     ^~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/vringh_init_kern +344 drivers/pci/endpoint/functions/pci-epf-vcon.c

   305	
   306	static int epf_vcon_vdev_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
   307					  struct virtqueue *vqs[],
   308					  vq_callback_t *callback[],
   309					  const char *const names[], const bool *ctx,
   310					  struct irq_affinity *desc)
   311	{
   312		struct epf_vcon *vcon = vdev_to_vcon(vdev);
   313		int err;
   314		int qidx, i;
   315	
   316		if (nvqs > epf_vcon_get_nvq(vcon))
   317			return -EINVAL;
   318	
   319		for (qidx = 0, i = 0; i < nvqs; i++) {
   320			struct virtqueue *vq;
   321			const struct vring *vring;
   322	
   323			if (!names[i]) {
   324				vqs[i] = NULL;
   325				continue;
   326			}
   327	
   328			vq = vring_create_virtqueue(qidx++, virtio_queue_size,
   329						    VIRTIO_PCI_VRING_ALIGN, vdev, true,
   330						    false, ctx ? ctx[i] : false,
   331						    epf_vcon_vdev_vq_notify,
   332						    callback[i], names[i]);
   333			if (!vq) {
   334				err = -ENOMEM;
   335				goto err_del_vqs;
   336			}
   337	
   338			vqs[i] = vq;
   339			vcon->vdev_vqs[i] = vq;
   340	
   341			vring = virtqueue_get_vring(vq);
 > 342			err = vringh_init_kern(&vcon->vdev_vrhs[i], vcon->features,
   343					       virtio_queue_size, false, GFP_KERNEL,
 > 344					       vring->desc, vring->avail, vring->used);
   345			if (err) {
   346				pr_err("failed to init vringh for vring %d\n", i);
   347				goto err_del_vqs;
   348			}
   349		}
   350	
   351		return 0;
   352	
   353	err_del_vqs:
   354		for (; i >= 0; i--) {
   355			if (!names[i])
   356				continue;
   357	
   358			if (!vqs[i])
   359				continue;
   360	
   361			vring_del_virtqueue(vqs[i]);
   362		}
   363		return err;
   364	}
   365	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
  2023-04-14 12:39   ` Shunsuke Mie
  (?)
  (?)
@ 2023-04-14 16:29   ` kernel test robot
  -1 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2023-04-14 16:29 UTC (permalink / raw)
  To: Shunsuke Mie; +Cc: oe-kbuild-all

Hi Shunsuke,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on pci/next]
[also build test WARNING on pci/for-linus linus/master v6.3-rc6 next-20230413]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shunsuke-Mie/PCI-endpoint-introduce-a-helper-to-implement-pci-ep-virtio-function/20230414-204118
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20230414123903.896914-4-mie%40igel.co.jp
patch subject: [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20230415/202304150030.X5T0IfTH-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/1351b90fcb70907e50f3a8c6a4e4e978bd00cda0
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Shunsuke-Mie/PCI-endpoint-introduce-a-helper-to-implement-pci-ep-virtio-function/20230414-204118
        git checkout 1351b90fcb70907e50f3a8c6a4e4e978bd00cda0
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 olddefconfig
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/pci/endpoint/functions/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304150030.X5T0IfTH-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_unmap_vq':
   drivers/pci/endpoint/functions/pci-epf-virtio.c:16:9: error: too many arguments to function 'pci_epc_unmap_addr'
      16 |         pci_epc_unmap_addr(epf->epc, epf->func_no, epf->vfunc_no, vq_phys,
         |         ^~~~~~~~~~~~~~~~~~
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_map_vq':
   drivers/pci/endpoint/functions/pci-epf-virtio.c:32:49: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
      32 |                                    vq_pci_addr, vq_phys, vq_size);
         |                                                 ^~~~~~~
         |                                                 |
         |                                                 phys_addr_t * {aka unsigned int *}
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:31:17: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      31 |         vq_virt = pci_epc_map_addr(epf->epc, epf->func_no, epf->vfunc_no,
         |                 ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_alloc_vringh':
   drivers/pci/endpoint/functions/pci-epf-virtio.c:75:15: error: implicit declaration of function 'vringh_init_iomem'; did you mean 'vringh_init_iotlb'? [-Werror=implicit-function-declaration]
      75 |         err = vringh_init_iomem(&evrh->vrh, features, num, false, GFP_KERNEL,
         |               ^~~~~~~~~~~~~~~~~
         |               vringh_init_iotlb
   drivers/pci/endpoint/functions/pci-epf-virtio.c: In function 'epf_virtio_vrh_memcpy':
   drivers/pci/endpoint/functions/pci-epf-virtio.c:402:15: error: implicit declaration of function 'vringh_getdesc'; did you mean 'vringh_getdesc_kern'? [-Werror=implicit-function-declaration]
     402 |         err = vringh_getdesc(svrh, siov, NULL, &shead);
         |               ^~~~~~~~~~~~~~
         |               vringh_getdesc_kern
>> drivers/pci/endpoint/functions/pci-epf-virtio.c:420:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     420 |                 sbase = (u64)siov->iov[siov->i].iov_base;
         |                         ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c:422:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     422 |                 dbase = (u64)diov->iov[diov->i].iov_base;
         |                         ^
   In file included from include/asm-generic/bug.h:22,
                    from arch/x86/include/asm/bug.h:87,
                    from include/linux/bug.h:5,
                    from include/linux/virtio_config.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:6:
   include/linux/kern_levels.h:5:25: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
       5 | #define KERN_SOH        "\001"          /* ASCII Start Of Header */
         |                         ^~~~~~
   include/linux/printk.h:427:25: note: in definition of macro 'printk_index_wrap'
     427 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                         ^~~~
   include/linux/printk.h:498:9: note: in expansion of macro 'printk'
     498 |         printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~
   include/linux/kern_levels.h:11:25: note: in expansion of macro 'KERN_SOH'
      11 | #define KERN_ERR        KERN_SOH "3"    /* error conditions */
         |                         ^~~~~~~~
   include/linux/printk.h:498:16: note: in expansion of macro 'KERN_ERR'
     498 |         printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
         |                ^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:425:25: note: in expansion of macro 'pr_err'
     425 |                         pr_err("no space %ld < %ld\n", dlen, slen);
         |                         ^~~~~~
   include/linux/kern_levels.h:5:25: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
       5 | #define KERN_SOH        "\001"          /* ASCII Start Of Header */
         |                         ^~~~~~
   include/linux/printk.h:427:25: note: in definition of macro 'printk_index_wrap'
     427 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                         ^~~~
   include/linux/printk.h:498:9: note: in expansion of macro 'printk'
     498 |         printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~
   include/linux/kern_levels.h:11:25: note: in expansion of macro 'KERN_SOH'
      11 | #define KERN_ERR        KERN_SOH "3"    /* error conditions */
         |                         ^~~~~~~~
   include/linux/printk.h:498:16: note: in expansion of macro 'KERN_ERR'
     498 |         printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
         |                ^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:425:25: note: in expansion of macro 'pr_err'
     425 |                         pr_err("no space %ld < %ld\n", dlen, slen);
         |                         ^~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:431:72: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
     431 |                                                  epf->vfunc_no, sbase, &phys,
         |                                                                        ^~~~~
         |                                                                        |
         |                                                                        phys_addr_t * {aka unsigned int *}
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:430:31: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     430 |                         svirt = pci_epc_map_addr(epf->epc, epf->func_no,
         |                               ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c:442:25: error: too many arguments to function 'pci_epc_unmap_addr'
     442 |                         pci_epc_unmap_addr(epf->epc, epf->func_no,
         |                         ^~~~~~~~~~~~~~~~~~
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:447:72: warning: passing argument 5 of 'pci_epc_map_addr' makes integer from pointer without a cast [-Wint-conversion]
     447 |                                                  epf->vfunc_no, dbase, &phys,
         |                                                                        ^~~~~
         |                                                                        |
         |                                                                        phys_addr_t * {aka unsigned int *}
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:217:26: note: expected 'u64' {aka 'long long unsigned int'} but argument is of type 'phys_addr_t *' {aka 'unsigned int *'}
     217 |                      u64 pci_addr, size_t size);
         |                      ~~~~^~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:446:31: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     446 |                         dvirt = pci_epc_map_addr(epf->epc, epf->func_no,
         |                               ^
   drivers/pci/endpoint/functions/pci-epf-virtio.c:457:25: error: too many arguments to function 'pci_epc_unmap_addr'
     457 |                         pci_epc_unmap_addr(epf->epc, epf->func_no,
         |                         ^~~~~~~~~~~~~~~~~~
   In file included from drivers/pci/endpoint/functions/pci-epf-virtio.h:6,
                    from drivers/pci/endpoint/functions/pci-epf-virtio.c:9:
   include/linux/pci-epc.h:218:6: note: declared here
     218 | void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
         |      ^~~~~~~~~~~~~~~~~~
   drivers/pci/endpoint/functions/pci-epf-virtio.c:462:9: error: implicit declaration of function 'vringh_complete'; did you mean 'vringh_complete_kern'? [-Werror=implicit-function-declaration]
     462 |         vringh_complete(svrh, shead, total_len);
         |         ^~~~~~~~~~~~~~~
         |         vringh_complete_kern
   cc1: some warnings being treated as errors


vim +420 drivers/pci/endpoint/functions/pci-epf-virtio.c

7a5dfc758cfa25 Shunsuke Mie 2023-04-14  375  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  376  /**
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  377   * epf_virtio_vrh_memcpy - copy a data with CPU between remote and local vring.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  378   * @evio: struct epf_virtio
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  379   * @svrh: vringh for source virtqueue.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  380   * @siov: iovec to store buffer info for source virtqueue
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  381   * @dvrh: vringh for destination virtqueue.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  382   * @diov: iovec to store buffer info for destination virtqueue
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  383   * @dir: direction of the copy.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  384   *
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  385   * Returns zero, one or a negative.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  386   * 0: there is no data in src virtio ring.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  387   * 1: success to transfer data.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  388   * negative: errors.
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  389   */
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  390  int epf_virtio_vrh_memcpy(struct epf_virtio *evio, struct vringh *svrh,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  391  			  struct vringh_kiov *siov, struct vringh *dvrh,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  392  			  struct vringh_kiov *diov,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  393  			  enum epf_virtio_copy_dir dir)
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  394  {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  395  	int err;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  396  	u16 shead, dhead;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  397  	size_t slen, dlen, total_len;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  398  	void *svirt, *dvirt;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  399  	phys_addr_t sbase, dbase, phys;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  400  	struct pci_epf *epf = evio->epf;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  401  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  402  	err = vringh_getdesc(svrh, siov, NULL, &shead);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  403  	if (err <= 0) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  404  		if (err < 0)
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  405  			pr_err("s err %d\n", err);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  406  		return err;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  407  	}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  408  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  409  	err = vringh_getdesc(dvrh, NULL, diov, &dhead);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  410  	if (err <= 0) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  411  		if (err < 0)
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  412  			pr_err("d err %d\n", err);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  413  		return err;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  414  	}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  415  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  416  	total_len = vringh_kiov_length(siov);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  417  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  418  	for (; siov->i < siov->used; siov->i++, diov->i++) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  419  		slen = siov->iov[siov->i].iov_len;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14 @420  		sbase = (u64)siov->iov[siov->i].iov_base;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  421  		dlen = diov->iov[diov->i].iov_len;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  422  		dbase = (u64)diov->iov[diov->i].iov_base;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  423  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  424  		if (dlen < slen) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  425  			pr_err("no space %ld < %ld\n", dlen, slen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  426  			return -ENOSPC;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  427  		}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  428  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  429  		if (dir == EPF_VIRTIO_COPY_DIR_FROM_DEV) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  430  			svirt = pci_epc_map_addr(epf->epc, epf->func_no,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  431  						 epf->vfunc_no, sbase, &phys,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  432  						 slen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  433  			if (IS_ERR(svirt)) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  434  				pr_err("pci_epc_map_addr s %ld\n",
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  435  				       PTR_ERR(svirt));
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  436  				return PTR_ERR(svirt);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  437  			}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  438  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  439  			dvirt = phys_to_virt(dbase);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  440  			memcpy_fromio(dvirt, svirt, slen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  441  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  442  			pci_epc_unmap_addr(epf->epc, epf->func_no,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  443  					   epf->vfunc_no, phys, svirt, slen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  444  		} else {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  445  			svirt = phys_to_virt(sbase);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  446  			dvirt = pci_epc_map_addr(epf->epc, epf->func_no,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  447  						 epf->vfunc_no, dbase, &phys,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  448  						 dlen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  449  			if (IS_ERR(dvirt)) {
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  450  				pr_err("pci_epc_map_addr d %ld\n",
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  451  				       PTR_ERR(dvirt));
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  452  				return PTR_ERR(dvirt);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  453  			}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  454  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  455  			memcpy_toio(dvirt, svirt, slen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  456  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  457  			pci_epc_unmap_addr(epf->epc, epf->func_no,
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  458  					   epf->vfunc_no, phys, dvirt, dlen);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  459  		}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  460  	}
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  461  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  462  	vringh_complete(svrh, shead, total_len);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  463  	vringh_complete(dvrh, dhead, total_len);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  464  
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  465  	return 1;
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  466  }
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  467  EXPORT_SYMBOL_GPL(epf_virtio_vrh_memcpy);
7a5dfc758cfa25 Shunsuke Mie 2023-04-14  468  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-14 14:39 ` [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console Frank Li
@ 2023-04-17  2:11     ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-17  2:11 UTC (permalink / raw)
  To: Frank Li, Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Jon Mason, Randy Dunlap, Ren Zhijie, linux-kernel,
	linux-pci, virtualization


On 2023/04/14 23:39, Frank Li wrote:
>
>> -----Original Message-----
>> From: Shunsuke Mie <mie@igel.co.jp>
>> Sent: Friday, April 14, 2023 7:39 AM
>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
>> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
>> virtualization@lists.linux-foundation.org
>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>
>> Caution: EXT Email
>>
>> PCIe endpoint framework provides APIs to implement PCIe endpoint
>> function.
>> This framework allows defining various PCIe endpoint function behaviors in
>> software. This patch extend the framework for virtio pci device. The
>> virtio is defined to communicate guest on virtual machine and host side.
>> Advantage of the virtio is the efficiency of data transfer and the conciseness
>> of implementation device using software. It also be applied to PCIe
>> endpoint function.
>>
>> We designed and implemented a PCIe EP virtio console function driver using
>> the extended PCIe endpoint framework for virtio. It can be communicate
>> host and endpoint over virtio as console.
>>
>> An architecture of the function driver is following:
>>
>>   ┌────────────┐         ┌──────────────
>> ────────┬────────────┐
>>   │virtio      │         │                      │virtio      │
>>   │console drv │         ├───────────────┐      │console
>> drv │
>>   ├────────────┤         │(virtio console│      ├─────
>> ───────┤
>>   │ virtio bus │         │ device)       │◄────►│ virtio bus │
>>   ├────────────┤         ├---------------┤      └──────
>> ──────┤
>>   │            │         │ pci ep virtio │                   │
>>   │  pci bus   │         │  console drv  │                   │
>>   │            │  pcie   ├───────────────┤                   │
>>   │            │ ◄─────► │  pci ep Bus   │                   │
>>   └────────────┘         └──────────────
>> ─┴───────────────────┘
>>     PCIe Root              PCIe Endpoint
>>
> [Frank Li] Some basic question,
> I see you call register_virtio_device at epf_vcon_setup_vdev,
> Why call it as virtio console?  I suppose it should be virtiobus directly?

I'm sorry I didn't understand your question. What do you mean the 
virtiobus directly?

>
> Previous you use virtio-net, why change to virtio-console here?  Does it matter?

No, it doesn't. Just I'd like to break down the changes into smaller 
steps to make it easier to review and merge the changes.

As a first step, I propose adding a simplest virtio function driver with 
the extension defined in pci-epf-virtio.{h,c}.

> All virtio-XXX should work?
Yes, the extension is designed to use any type of virtio device.
>
> You removed EDMA support this version?
I planed the support will be added with epf virtio-net patches.
>
>> Introduced driver is `pci ep virtio console drv` in the figure. It works
>> as ep function for PCIe root and virtual virtio console device for PCIe
>> endpoint. Each side of virtio console driver has virtqueue, and
>> introduced driver transfers data on the virtqueue to each other. A data
>> on root tx queue is transfered to endpoint rx queue and vice versa.
>>
>> This patchset is depend follwing patches which are under discussion.
>>
>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
>> link:
>> https://lore.k/
>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mmsvo
>> %3D&reserved=0
>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
>> link:
>> https://lore.k/
>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0%3
>> D&reserved=0
>>
>> First of this patchset is introduce a helper function to realize pci
>> virtio function using PCIe endpoint framework. The second one is adding
>> a missing definition for virtio pci header. The last one is for PCIe
>> endpoint virtio console driver.
>>
>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
>>
>> Shunsuke Mie (3):
>>    PCI: endpoint: introduce a helper to implement pci ep virtio function
>>    virtio_pci: add a definition of queue flag in ISR
>>    PCI: endpoint: Add EP function driver to provide virtio-console
>>      functionality
>>
>>   drivers/pci/endpoint/functions/Kconfig        |  19 +
>>   drivers/pci/endpoint/functions/Makefile       |   2 +
>>   drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
>>   .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
>>   .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
>>   include/uapi/linux/virtio_pci.h               |   3 +
>>   6 files changed, 1170 insertions(+)
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
>>
>> --
>> 2.25.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
@ 2023-04-17  2:11     ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-17  2:11 UTC (permalink / raw)
  To: Frank Li, Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam,
	linux-kernel, virtualization, Ren Zhijie, Jon Mason,
	Bjorn Helgaas


On 2023/04/14 23:39, Frank Li wrote:
>
>> -----Original Message-----
>> From: Shunsuke Mie <mie@igel.co.jp>
>> Sent: Friday, April 14, 2023 7:39 AM
>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
>> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
>> virtualization@lists.linux-foundation.org
>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>
>> Caution: EXT Email
>>
>> PCIe endpoint framework provides APIs to implement PCIe endpoint
>> function.
>> This framework allows defining various PCIe endpoint function behaviors in
>> software. This patch extend the framework for virtio pci device. The
>> virtio is defined to communicate guest on virtual machine and host side.
>> Advantage of the virtio is the efficiency of data transfer and the conciseness
>> of implementation device using software. It also be applied to PCIe
>> endpoint function.
>>
>> We designed and implemented a PCIe EP virtio console function driver using
>> the extended PCIe endpoint framework for virtio. It can be communicate
>> host and endpoint over virtio as console.
>>
>> An architecture of the function driver is following:
>>
>>   ┌────────────┐         ┌──────────────
>> ────────┬────────────┐
>>   │virtio      │         │                      │virtio      │
>>   │console drv │         ├───────────────┐      │console
>> drv │
>>   ├────────────┤         │(virtio console│      ├─────
>> ───────┤
>>   │ virtio bus │         │ device)       │◄────►│ virtio bus │
>>   ├────────────┤         ├---------------┤      └──────
>> ──────┤
>>   │            │         │ pci ep virtio │                   │
>>   │  pci bus   │         │  console drv  │                   │
>>   │            │  pcie   ├───────────────┤                   │
>>   │            │ ◄─────► │  pci ep Bus   │                   │
>>   └────────────┘         └──────────────
>> ─┴───────────────────┘
>>     PCIe Root              PCIe Endpoint
>>
> [Frank Li] Some basic question,
> I see you call register_virtio_device at epf_vcon_setup_vdev,
> Why call it as virtio console?  I suppose it should be virtiobus directly?

I'm sorry I didn't understand your question. What do you mean the 
virtiobus directly?

>
> Previous you use virtio-net, why change to virtio-console here?  Does it matter?

No, it doesn't. Just I'd like to break down the changes into smaller 
steps to make it easier to review and merge the changes.

As a first step, I propose adding a simplest virtio function driver with 
the extension defined in pci-epf-virtio.{h,c}.

> All virtio-XXX should work?
Yes, the extension is designed to use any type of virtio device.
>
> You removed EDMA support this version?
I planed the support will be added with epf virtio-net patches.
>
>> Introduced driver is `pci ep virtio console drv` in the figure. It works
>> as ep function for PCIe root and virtual virtio console device for PCIe
>> endpoint. Each side of virtio console driver has virtqueue, and
>> introduced driver transfers data on the virtqueue to each other. A data
>> on root tx queue is transfered to endpoint rx queue and vice versa.
>>
>> This patchset is depend follwing patches which are under discussion.
>>
>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
>> link:
>> https://lore.k/
>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mmsvo
>> %3D&reserved=0
>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
>> link:
>> https://lore.k/
>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0%3
>> D&reserved=0
>>
>> First of this patchset is introduce a helper function to realize pci
>> virtio function using PCIe endpoint framework. The second one is adding
>> a missing definition for virtio pci header. The last one is for PCIe
>> endpoint virtio console driver.
>>
>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
>>
>> Shunsuke Mie (3):
>>    PCI: endpoint: introduce a helper to implement pci ep virtio function
>>    virtio_pci: add a definition of queue flag in ISR
>>    PCI: endpoint: Add EP function driver to provide virtio-console
>>      functionality
>>
>>   drivers/pci/endpoint/functions/Kconfig        |  19 +
>>   drivers/pci/endpoint/functions/Makefile       |   2 +
>>   drivers/pci/endpoint/functions/pci-epf-vcon.c | 554 ++++++++++++++++++
>>   .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
>>   .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
>>   include/uapi/linux/virtio_pci.h               |   3 +
>>   6 files changed, 1170 insertions(+)
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
>>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
>>
>> --
>> 2.25.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-17  2:11     ` Shunsuke Mie
  (?)
@ 2023-04-17 15:19     ` Frank Li
  2023-04-18 10:31         ` Shunsuke Mie
  -1 siblings, 1 reply; 19+ messages in thread
From: Frank Li @ 2023-04-17 15:19 UTC (permalink / raw)
  To: Shunsuke Mie, Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Jon Mason, Randy Dunlap, Ren Zhijie, linux-kernel,
	linux-pci, virtualization



> -----Original Message-----
> From: Shunsuke Mie <mie@igel.co.jp>
> Sent: Sunday, April 16, 2023 9:12 PM
> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>
> Caution: EXT Email
>
> On 2023/04/14 23:39, Frank Li wrote:
> >
> >> -----Original Message-----
> >> From: Shunsuke Mie <mie@igel.co.jp>
> >> Sent: Friday, April 14, 2023 7:39 AM
> >> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
> >> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> >> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> >> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> >> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
> >> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
> >> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
> >> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> >> virtualization@lists.linux-foundation.org
> >> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> >>
> >> Caution: EXT Email
> >>
> >> PCIe endpoint framework provides APIs to implement PCIe endpoint
> >> function.
> >> This framework allows defining various PCIe endpoint function behaviors
> in
> >> software. This patch extend the framework for virtio pci device. The
> >> virtio is defined to communicate guest on virtual machine and host side.
> >> Advantage of the virtio is the efficiency of data transfer and the
> conciseness
> >> of implementation device using software. It also be applied to PCIe
> >> endpoint function.
> >>
> >> We designed and implemented a PCIe EP virtio console function driver
> using
> >> the extended PCIe endpoint framework for virtio. It can be communicate
> >> host and endpoint over virtio as console.
> >>
> >> An architecture of the function driver is following:
> >>
> >>   ┌────────────┐         ┌────────────
> ──
> >> ────────┬────────────┐
> >>   │virtio      │         │                      │virtio      │
> >>   │console drv │         ├───────────────┐      │
> console
> >> drv │
> >>   ├────────────┤         │(virtio console│      ├───
> ──
> >> ───────┤
> >>   │ virtio bus │         │ device)       │◄────►│ virtio bus │
> >>   ├────────────┤         ├---------------┤      └────
> ──
> >> ──────┤
> >>   │            │         │ pci ep virtio │                   │
> >>   │  pci bus   │         │  console drv  │                   │
> >>   │            │  pcie   ├───────────────┤                   │
> >>   │            │ ◄─────► │  pci ep Bus   │                   │
> >>   └────────────┘         └────────────
> ──
> >> ─┴───────────────────┘
> >>     PCIe Root              PCIe Endpoint
> >>
> > [Frank Li] Some basic question,
> > I see you call register_virtio_device at epf_vcon_setup_vdev,
> > Why call it as virtio console?  I suppose it should be virtiobus directly?
>
> I'm sorry I didn't understand your question. What do you mean the
> virtiobus directly?

I go through your code again.  I think I understand why you need pci-epf-vcon.c.
Actually,  my means is like virtio_mmio_probe.

vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);

I am not sure that if VIRTIO_MMIO_VENDOR_ID and VIRTIO_MMIO_DEVICE_ID
reuse PCI's vendor ID and Device ID.  If yes, you can directly get such information
from epf.  If no,  a customer field can been added at epf driver.

So you needn't write pci-epf-vcon  and pci-epf-vnet .....

Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic create platform
Devices.  It may have some difficult because pci memory map requirement.

>
> >
> > Previous you use virtio-net, why change to virtio-console here?  Does it
> matter?
>
> No, it doesn't. Just I'd like to break down the changes into smaller
> steps to make it easier to review and merge the changes.
>
> As a first step, I propose adding a simplest virtio function driver with
> the extension defined in pci-epf-virtio.{h,c}.
>
> > All virtio-XXX should work?
> Yes, the extension is designed to use any type of virtio device.
> >
> > You removed EDMA support this version?
> I planed the support will be added with epf virtio-net patches.
> >
> >> Introduced driver is `pci ep virtio console drv` in the figure. It works
> >> as ep function for PCIe root and virtual virtio console device for PCIe
> >> endpoint. Each side of virtio console driver has virtqueue, and
> >> introduced driver transfers data on the virtqueue to each other. A data
> >> on root tx queue is transfered to endpoint rx queue and vice versa.
> >>
> >> This patchset is depend follwing patches which are under discussion.
> >>
> >> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
> >> link:
> >>
> https://lore.k/
> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> >> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
> >>
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> >>
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> >>
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> >>
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> >> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mm
> svo
> >> %3D&reserved=0
> >> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
> >> link:
> >>
> https://lore.k/
> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> >> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
> >>
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> >>
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> >>
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> >>
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> >> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0
> %3
> >> D&reserved=0
> >>
> >> First of this patchset is introduce a helper function to realize pci
> >> virtio function using PCIe endpoint framework. The second one is adding
> >> a missing definition for virtio pci header. The last one is for PCIe
> >> endpoint virtio console driver.
> >>
> >> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
> >>
> >> Shunsuke Mie (3):
> >>    PCI: endpoint: introduce a helper to implement pci ep virtio function
> >>    virtio_pci: add a definition of queue flag in ISR
> >>    PCI: endpoint: Add EP function driver to provide virtio-console
> >>      functionality
> >>
> >>   drivers/pci/endpoint/functions/Kconfig        |  19 +
> >>   drivers/pci/endpoint/functions/Makefile       |   2 +
> >>   drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
> ++++++++++++++++++
> >>   .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
> >>   .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
> >>   include/uapi/linux/virtio_pci.h               |   3 +
> >>   6 files changed, 1170 insertions(+)
> >>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
> >>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
> >>   create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
> >>
> >> --
> >> 2.25.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-17 15:19     ` Frank Li
@ 2023-04-18 10:31         ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-18 10:31 UTC (permalink / raw)
  To: Frank Li, Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Jon Mason, Randy Dunlap, Ren Zhijie, linux-kernel,
	linux-pci, virtualization


On 2023/04/18 0:19, Frank Li wrote:
>
>> -----Original Message-----
>> From: Shunsuke Mie <mie@igel.co.jp>
>> Sent: Sunday, April 16, 2023 9:12 PM
>> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
>> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
>> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
>> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
>> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>
>> Caution: EXT Email
>>
>> On 2023/04/14 23:39, Frank Li wrote:
>>>> -----Original Message-----
>>>> From: Shunsuke Mie <mie@igel.co.jp>
>>>> Sent: Friday, April 14, 2023 7:39 AM
>>>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
>>>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>>>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>>>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>>>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
>>>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
>>>> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
>>>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
>>>> virtualization@lists.linux-foundation.org
>>>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>>>
>>>> Caution: EXT Email
>>>>
>>>> PCIe endpoint framework provides APIs to implement PCIe endpoint
>>>> function.
>>>> This framework allows defining various PCIe endpoint function behaviors
>> in
>>>> software. This patch extend the framework for virtio pci device. The
>>>> virtio is defined to communicate guest on virtual machine and host side.
>>>> Advantage of the virtio is the efficiency of data transfer and the
>> conciseness
>>>> of implementation device using software. It also be applied to PCIe
>>>> endpoint function.
>>>>
>>>> We designed and implemented a PCIe EP virtio console function driver
>> using
>>>> the extended PCIe endpoint framework for virtio. It can be communicate
>>>> host and endpoint over virtio as console.
>>>>
>>>> An architecture of the function driver is following:
>>>>
>>>>    ┌────────────┐         ┌────────────
>> ──
>>>> ────────┬────────────┐
>>>>    │virtio      │         │                      │virtio      │
>>>>    │console drv │         ├───────────────┐      │
>> console
>>>> drv │
>>>>    ├────────────┤         │(virtio console│      ├───
>> ──
>>>> ───────┤
>>>>    │ virtio bus │         │ device)       │◄────►│ virtio bus │
>>>>    ├────────────┤         ├---------------┤      └────
>> ──
>>>> ──────┤
>>>>    │            │         │ pci ep virtio │                   │
>>>>    │  pci bus   │         │  console drv  │                   │
>>>>    │            │  pcie   ├───────────────┤                   │
>>>>    │            │ ◄─────► │  pci ep Bus   │                   │
>>>>    └────────────┘         └────────────
>> ──
>>>> ─┴───────────────────┘
>>>>      PCIe Root              PCIe Endpoint
>>>>
>>> [Frank Li] Some basic question,
>>> I see you call register_virtio_device at epf_vcon_setup_vdev,
>>> Why call it as virtio console?  I suppose it should be virtiobus directly?
>> I'm sorry I didn't understand your question. What do you mean the
>> virtiobus directly?
> I go through your code again.  I think I understand why you need pci-epf-vcon.c.
> Actually,  my means is like virtio_mmio_probe.
>
> vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
> vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
>
> I am not sure that if VIRTIO_MMIO_VENDOR_ID and VIRTIO_MMIO_DEVICE_ID
> reuse PCI's vendor ID and Device ID.  If yes, you can directly get such information
> from epf.  If no,  a customer field can been added at epf driver.
>
> So you needn't write pci-epf-vcon  and pci-epf-vnet .....
>
> Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic create platform
> Devices.  It may have some difficult because pci memory map requirement.
I think that some fields are shared between the vdev and epf device.
However, we need to implement device emulation because each virtio device
has its specific set of tasks. For example, the virtio-net device has a
control queue, and the driver can request MAC filters, VLANs, and other
settings via this queue. These requests have to be processed by the virtio
device that we are implementing in pci-epf-vnet.

The simplest virtio-console device doesn’t have these tasks, but the other
virtio devices requireprocessing them.

That's why the current pci-epf-virtio design requires a specific
implementation for each virtio device.

Is this what you meant?

>
>>> Previous you use virtio-net, why change to virtio-console here?  Does it
>> matter?
>>
>> No, it doesn't. Just I'd like to break down the changes into smaller
>> steps to make it easier to review and merge the changes.
>>
>> As a first step, I propose adding a simplest virtio function driver with
>> the extension defined in pci-epf-virtio.{h,c}.
>>
>>> All virtio-XXX should work?
>> Yes, the extension is designed to use any type of virtio device.
>>> You removed EDMA support this version?
>> I planed the support will be added with epf virtio-net patches.
>>>> Introduced driver is `pci ep virtio console drv` in the figure. It works
>>>> as ep function for PCIe root and virtual virtio console device for PCIe
>>>> endpoint. Each side of virtio console driver has virtqueue, and
>>>> introduced driver transfers data on the virtqueue to each other. A data
>>>> on root tx queue is transfered to endpoint rx queue and vice versa.
>>>>
>>>> This patchset is depend follwing patches which are under discussion.
>>>>
>>>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
>>>> link:
>>>>
>> https://lore.k/
>> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
>> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
>> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
>> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
>> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
>>>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
>>>>
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>>>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mm
>> svo
>>>> %3D&reserved=0
>>>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
>>>> link:
>>>>
>> https://lore.k/
>> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
>> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
>> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
>> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
>> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
>>>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
>>>>
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>>>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0
>> %3
>>>> D&reserved=0
>>>>
>>>> First of this patchset is introduce a helper function to realize pci
>>>> virtio function using PCIe endpoint framework. The second one is adding
>>>> a missing definition for virtio pci header. The last one is for PCIe
>>>> endpoint virtio console driver.
>>>>
>>>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
>>>>
>>>> Shunsuke Mie (3):
>>>>     PCI: endpoint: introduce a helper to implement pci ep virtio function
>>>>     virtio_pci: add a definition of queue flag in ISR
>>>>     PCI: endpoint: Add EP function driver to provide virtio-console
>>>>       functionality
>>>>
>>>>    drivers/pci/endpoint/functions/Kconfig        |  19 +
>>>>    drivers/pci/endpoint/functions/Makefile       |   2 +
>>>>    drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
>> ++++++++++++++++++
>>>>    .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
>>>>    .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
>>>>    include/uapi/linux/virtio_pci.h               |   3 +
>>>>    6 files changed, 1170 insertions(+)
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
>>>>
>>>> --
>>>> 2.25.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
@ 2023-04-18 10:31         ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-18 10:31 UTC (permalink / raw)
  To: Frank Li, Lorenzo Pieralisi
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Manivannan Sadhasivam,
	linux-kernel, virtualization, Ren Zhijie, Jon Mason,
	Bjorn Helgaas


On 2023/04/18 0:19, Frank Li wrote:
>
>> -----Original Message-----
>> From: Shunsuke Mie <mie@igel.co.jp>
>> Sent: Sunday, April 16, 2023 9:12 PM
>> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
>> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
>> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
>> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
>> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>
>> Caution: EXT Email
>>
>> On 2023/04/14 23:39, Frank Li wrote:
>>>> -----Original Message-----
>>>> From: Shunsuke Mie <mie@igel.co.jp>
>>>> Sent: Friday, April 14, 2023 7:39 AM
>>>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
>>>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
>>>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
>>>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
>>>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie <mie@igel.co.jp>;
>>>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
>>>> Dunlap <rdunlap@infradead.org>; Ren Zhijie <renzhijie2@huawei.com>;
>>>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
>>>> virtualization@lists.linux-foundation.org
>>>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>>>>
>>>> Caution: EXT Email
>>>>
>>>> PCIe endpoint framework provides APIs to implement PCIe endpoint
>>>> function.
>>>> This framework allows defining various PCIe endpoint function behaviors
>> in
>>>> software. This patch extend the framework for virtio pci device. The
>>>> virtio is defined to communicate guest on virtual machine and host side.
>>>> Advantage of the virtio is the efficiency of data transfer and the
>> conciseness
>>>> of implementation device using software. It also be applied to PCIe
>>>> endpoint function.
>>>>
>>>> We designed and implemented a PCIe EP virtio console function driver
>> using
>>>> the extended PCIe endpoint framework for virtio. It can be communicate
>>>> host and endpoint over virtio as console.
>>>>
>>>> An architecture of the function driver is following:
>>>>
>>>>    ┌────────────┐         ┌────────────
>> ──
>>>> ────────┬────────────┐
>>>>    │virtio      │         │                      │virtio      │
>>>>    │console drv │         ├───────────────┐      │
>> console
>>>> drv │
>>>>    ├────────────┤         │(virtio console│      ├───
>> ──
>>>> ───────┤
>>>>    │ virtio bus │         │ device)       │◄────►│ virtio bus │
>>>>    ├────────────┤         ├---------------┤      └────
>> ──
>>>> ──────┤
>>>>    │            │         │ pci ep virtio │                   │
>>>>    │  pci bus   │         │  console drv  │                   │
>>>>    │            │  pcie   ├───────────────┤                   │
>>>>    │            │ ◄─────► │  pci ep Bus   │                   │
>>>>    └────────────┘         └────────────
>> ──
>>>> ─┴───────────────────┘
>>>>      PCIe Root              PCIe Endpoint
>>>>
>>> [Frank Li] Some basic question,
>>> I see you call register_virtio_device at epf_vcon_setup_vdev,
>>> Why call it as virtio console?  I suppose it should be virtiobus directly?
>> I'm sorry I didn't understand your question. What do you mean the
>> virtiobus directly?
> I go through your code again.  I think I understand why you need pci-epf-vcon.c.
> Actually,  my means is like virtio_mmio_probe.
>
> vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
> vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
>
> I am not sure that if VIRTIO_MMIO_VENDOR_ID and VIRTIO_MMIO_DEVICE_ID
> reuse PCI's vendor ID and Device ID.  If yes, you can directly get such information
> from epf.  If no,  a customer field can been added at epf driver.
>
> So you needn't write pci-epf-vcon  and pci-epf-vnet .....
>
> Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic create platform
> Devices.  It may have some difficult because pci memory map requirement.
I think that some fields are shared between the vdev and epf device.
However, we need to implement device emulation because each virtio device
has its specific set of tasks. For example, the virtio-net device has a
control queue, and the driver can request MAC filters, VLANs, and other
settings via this queue. These requests have to be processed by the virtio
device that we are implementing in pci-epf-vnet.

The simplest virtio-console device doesn’t have these tasks, but the other
virtio devices requireprocessing them.

That's why the current pci-epf-virtio design requires a specific
implementation for each virtio device.

Is this what you meant?

>
>>> Previous you use virtio-net, why change to virtio-console here?  Does it
>> matter?
>>
>> No, it doesn't. Just I'd like to break down the changes into smaller
>> steps to make it easier to review and merge the changes.
>>
>> As a first step, I propose adding a simplest virtio function driver with
>> the extension defined in pci-epf-virtio.{h,c}.
>>
>>> All virtio-XXX should work?
>> Yes, the extension is designed to use any type of virtio device.
>>> You removed EDMA support this version?
>> I planed the support will be added with epf virtio-net patches.
>>>> Introduced driver is `pci ep virtio console drv` in the figure. It works
>>>> as ep function for PCIe root and virtual virtio console device for PCIe
>>>> endpoint. Each side of virtio console driver has virtqueue, and
>>>> introduced driver transfers data on the virtqueue to each other. A data
>>>> on root tx queue is transfered to endpoint rx queue and vice versa.
>>>>
>>>> This patchset is depend follwing patches which are under discussion.
>>>>
>>>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
>>>> link:
>>>>
>> https://lore.k/
>> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
>> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
>> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
>> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
>> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
>>>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
>>>>
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>>>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5Mm
>> svo
>>>> %3D&reserved=0
>>>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
>>>> link:
>>>>
>> https://lore.k/
>> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908db3
>> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
>> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
>> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
>> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
>>>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
>>>>
>> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
>> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
>> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
>>>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WIZ0
>> %3
>>>> D&reserved=0
>>>>
>>>> First of this patchset is introduce a helper function to realize pci
>>>> virtio function using PCIe endpoint framework. The second one is adding
>>>> a missing definition for virtio pci header. The last one is for PCIe
>>>> endpoint virtio console driver.
>>>>
>>>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
>>>>
>>>> Shunsuke Mie (3):
>>>>     PCI: endpoint: introduce a helper to implement pci ep virtio function
>>>>     virtio_pci: add a definition of queue flag in ISR
>>>>     PCI: endpoint: Add EP function driver to provide virtio-console
>>>>       functionality
>>>>
>>>>    drivers/pci/endpoint/functions/Kconfig        |  19 +
>>>>    drivers/pci/endpoint/functions/Makefile       |   2 +
>>>>    drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
>> ++++++++++++++++++
>>>>    .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
>>>>    .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
>>>>    include/uapi/linux/virtio_pci.h               |   3 +
>>>>    6 files changed, 1170 insertions(+)
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
>>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
>>>>
>>>> --
>>>> 2.25.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-18 10:31         ` Shunsuke Mie
  (?)
@ 2023-04-18 16:42         ` Frank Li
  2023-04-24 10:06             ` Shunsuke Mie
  -1 siblings, 1 reply; 19+ messages in thread
From: Frank Li @ 2023-04-18 16:42 UTC (permalink / raw)
  To: Shunsuke Mie, Lorenzo Pieralisi
  Cc: Krzysztof Wilczyński, Manivannan Sadhasivam,
	Kishon Vijay Abraham I, Bjorn Helgaas, Michael S. Tsirkin,
	Jason Wang, Jon Mason, Randy Dunlap, Ren Zhijie, linux-kernel,
	linux-pci, virtualization



> -----Original Message-----
> From: Shunsuke Mie <mie@igel.co.jp>
> Sent: Tuesday, April 18, 2023 5:31 AM
> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
>
> Caution: EXT Email
>
> On 2023/04/18 0:19, Frank Li wrote:
> >
> >> -----Original Message-----
> >> From: Shunsuke Mie <mie@igel.co.jp>
> >> Sent: Sunday, April 16, 2023 9:12 PM
> >> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> >> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> >> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> >> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> >> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> >> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> >> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> >> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> >> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio
> console
> >>
> >> Caution: EXT Email
> >>
> >> On 2023/04/14 23:39, Frank Li wrote:
> >>>> -----Original Message-----
> >>>> From: Shunsuke Mie <mie@igel.co.jp>
> >>>> Sent: Friday, April 14, 2023 7:39 AM
> >>>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
> >>>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> >>>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>;
> Bjorn
> >>>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin
> <mst@redhat.com>;
> >>>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie
> <mie@igel.co.jp>;
> >>>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
> >>>> Dunlap <rdunlap@infradead.org>; Ren Zhijie
> <renzhijie2@huawei.com>;
> >>>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> >>>> virtualization@lists.linux-foundation.org
> >>>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> >>>>
> >>>> Caution: EXT Email
> >>>>
> >>>> PCIe endpoint framework provides APIs to implement PCIe endpoint
> >>>> function.
> >>>> This framework allows defining various PCIe endpoint function
> behaviors
> >> in
> >>>> software. This patch extend the framework for virtio pci device. The
> >>>> virtio is defined to communicate guest on virtual machine and host side.
> >>>> Advantage of the virtio is the efficiency of data transfer and the
> >> conciseness
> >>>> of implementation device using software. It also be applied to PCIe
> >>>> endpoint function.
> >>>>
> >>>> We designed and implemented a PCIe EP virtio console function driver
> >> using
> >>>> the extended PCIe endpoint framework for virtio. It can be
> communicate
> >>>> host and endpoint over virtio as console.
> >>>>
> >>>> An architecture of the function driver is following:
> >>>>
> >>>>    ┌────────────┐         ┌───────────
> ─
> >> ──
> >>>> ────────┬────────────┐
> >>>>    │virtio      │         │                      │virtio      │
> >>>>    │console drv │         ├───────────────┐      │
> >> console
> >>>> drv │
> >>>>    ├────────────┤         │(virtio console│      ├──
> ─
> >> ──
> >>>> ───────┤
> >>>>    │ virtio bus │         │ device)       │◄────►│ virtio bus │
> >>>>    ├────────────┤         ├---------------┤      └───
> ─
> >> ──
> >>>> ──────┤
> >>>>    │            │         │ pci ep virtio │                   │
> >>>>    │  pci bus   │         │  console drv  │                   │
> >>>>    │            │  pcie   ├───────────────┤
> │
> >>>>    │            │ ◄─────► │  pci ep Bus   │                   │
> >>>>    └────────────┘         └───────────
> ─
> >> ──
> >>>> ─┴───────────────────┘
> >>>>      PCIe Root              PCIe Endpoint
> >>>>
> >>> [Frank Li] Some basic question,
> >>> I see you call register_virtio_device at epf_vcon_setup_vdev,
> >>> Why call it as virtio console?  I suppose it should be virtiobus directly?
> >> I'm sorry I didn't understand your question. What do you mean the
> >> virtiobus directly?
> > I go through your code again.  I think I understand why you need pci-epf-
> vcon.c.
> > Actually,  my means is like virtio_mmio_probe.
> >
> > vm_dev->vdev.id.device = readl(vm_dev->base +
> VIRTIO_MMIO_DEVICE_ID);
> > vm_dev->vdev.id.vendor = readl(vm_dev->base +
> VIRTIO_MMIO_VENDOR_ID);
> >
> > I am not sure that if VIRTIO_MMIO_VENDOR_ID and
> VIRTIO_MMIO_DEVICE_ID
> > reuse PCI's vendor ID and Device ID.  If yes, you can directly get such
> information
> > from epf.  If no,  a customer field can been added at epf driver.
> >
> > So you needn't write pci-epf-vcon  and pci-epf-vnet .....
> >
> > Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic
> create platform
> > Devices.  It may have some difficult because pci memory map requirement.
> I think that some fields are shared between the vdev and epf device.
> However, we need to implement device emulation because each virtio
> device
> has its specific set of tasks. For example, the virtio-net device has a
> control queue, and the driver can request MAC filters, VLANs, and other
> settings via this queue. These requests have to be processed by the virtio
> device that we are implementing in pci-epf-vnet.
>
> The simplest virtio-console device doesn’t have these tasks, but the other
> virtio devices requireprocessing them.
>
> That's why the current pci-epf-virtio design requires a specific
> implementation for each virtio device.
>
> Is this what you meant

I see. Thank you for explain.
Thing may become complex. How to implement composite at EPF driver?
Such as console + net

>
> >
> >>> Previous you use virtio-net, why change to virtio-console here?  Does it
> >> matter?
> >>
> >> No, it doesn't. Just I'd like to break down the changes into smaller
> >> steps to make it easier to review and merge the changes.
> >>
> >> As a first step, I propose adding a simplest virtio function driver with
> >> the extension defined in pci-epf-virtio.{h,c}.
> >>
> >>> All virtio-XXX should work?
> >> Yes, the extension is designed to use any type of virtio device.
> >>> You removed EDMA support this version?
> >> I planed the support will be added with epf virtio-net patches.
> >>>> Introduced driver is `pci ep virtio console drv` in the figure. It works
> >>>> as ep function for PCIe root and virtual virtio console device for PCIe
> >>>> endpoint. Each side of virtio console driver has virtqueue, and
> >>>> introduced driver transfers data on the virtqueue to each other. A data
> >>>> on root tx queue is transfered to endpoint rx queue and vice versa.
> >>>>
> >>>> This patchset is depend follwing patches which are under discussion.
> >>>>
> >>>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
> >>>> link:
> >>>>
> >>
> https://lore.k/
> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> db3
> >>
> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> >>
> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> >>
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> >>>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
> >>>>
> >>
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> >>
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> >>
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> >>
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> >>>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5
> Mm
> >> svo
> >>>> %3D&reserved=0
> >>>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
> >>>> link:
> >>>>
> >>
> https://lore.k/
> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> db3
> >>
> ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> >>
> 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> >>
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> >>>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
> >>>>
> >>
> mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> >>
> 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> >>
> C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> >>
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> >>>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WI
> Z0
> >> %3
> >>>> D&reserved=0
> >>>>
> >>>> First of this patchset is introduce a helper function to realize pci
> >>>> virtio function using PCIe endpoint framework. The second one is
> adding
> >>>> a missing definition for virtio pci header. The last one is for PCIe
> >>>> endpoint virtio console driver.
> >>>>
> >>>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
> >>>>
> >>>> Shunsuke Mie (3):
> >>>>     PCI: endpoint: introduce a helper to implement pci ep virtio function
> >>>>     virtio_pci: add a definition of queue flag in ISR
> >>>>     PCI: endpoint: Add EP function driver to provide virtio-console
> >>>>       functionality
> >>>>
> >>>>    drivers/pci/endpoint/functions/Kconfig        |  19 +
> >>>>    drivers/pci/endpoint/functions/Makefile       |   2 +
> >>>>    drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
> >> ++++++++++++++++++
> >>>>    .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
> >>>>    .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
> >>>>    include/uapi/linux/virtio_pci.h               |   3 +
> >>>>    6 files changed, 1170 insertions(+)
> >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
> >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
> >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
> >>>>
> >>>> --
> >>>> 2.25.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
  2023-04-18 16:42         ` Frank Li
@ 2023-04-24 10:06             ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-24 10:06 UTC (permalink / raw)
  To: Frank Li
  Cc: Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Kishon Vijay Abraham I, Bjorn Helgaas,
	Michael S. Tsirkin, Jason Wang, Jon Mason, Randy Dunlap,
	Ren Zhijie, linux-kernel, linux-pci, virtualization

2023年4月19日(水) 1:42 Frank Li <frank.li@nxp.com>:
>
>
>
> > -----Original Message-----
> > From: Shunsuke Mie <mie@igel.co.jp>
> > Sent: Tuesday, April 18, 2023 5:31 AM
> > To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> > Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> > Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> > Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> > Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> > pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> > Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> >
> > Caution: EXT Email
> >
> > On 2023/04/18 0:19, Frank Li wrote:
> > >
> > >> -----Original Message-----
> > >> From: Shunsuke Mie <mie@igel.co.jp>
> > >> Sent: Sunday, April 16, 2023 9:12 PM
> > >> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> > >> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > >> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> > >> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> > >> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> > >> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > >> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> > >> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> > >> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio
> > console
> > >>
> > >> Caution: EXT Email
> > >>
> > >> On 2023/04/14 23:39, Frank Li wrote:
> > >>>> -----Original Message-----
> > >>>> From: Shunsuke Mie <mie@igel.co.jp>
> > >>>> Sent: Friday, April 14, 2023 7:39 AM
> > >>>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
> > >>>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > >>>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>;
> > Bjorn
> > >>>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin
> > <mst@redhat.com>;
> > >>>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie
> > <mie@igel.co.jp>;
> > >>>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
> > >>>> Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > <renzhijie2@huawei.com>;
> > >>>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> > >>>> virtualization@lists.linux-foundation.org
> > >>>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> > >>>>
> > >>>> Caution: EXT Email
> > >>>>
> > >>>> PCIe endpoint framework provides APIs to implement PCIe endpoint
> > >>>> function.
> > >>>> This framework allows defining various PCIe endpoint function
> > behaviors
> > >> in
> > >>>> software. This patch extend the framework for virtio pci device. The
> > >>>> virtio is defined to communicate guest on virtual machine and host side.
> > >>>> Advantage of the virtio is the efficiency of data transfer and the
> > >> conciseness
> > >>>> of implementation device using software. It also be applied to PCIe
> > >>>> endpoint function.
> > >>>>
> > >>>> We designed and implemented a PCIe EP virtio console function driver
> > >> using
> > >>>> the extended PCIe endpoint framework for virtio. It can be
> > communicate
> > >>>> host and endpoint over virtio as console.
> > >>>>
> > >>>> An architecture of the function driver is following:
> > >>>>
> > >>>>    ┌────────────┐         ┌───────────
> > ─
> > >> ──
> > >>>> ────────┬────────────┐
> > >>>>    │virtio      │         │                      │virtio      │
> > >>>>    │console drv │         ├───────────────┐      │
> > >> console
> > >>>> drv │
> > >>>>    ├────────────┤         │(virtio console│      ├──
> > ─
> > >> ──
> > >>>> ───────┤
> > >>>>    │ virtio bus │         │ device)       │◄────►│ virtio bus │
> > >>>>    ├────────────┤         ├---------------┤      └───
> > ─
> > >> ──
> > >>>> ──────┤
> > >>>>    │            │         │ pci ep virtio │                   │
> > >>>>    │  pci bus   │         │  console drv  │                   │
> > >>>>    │            │  pcie   ├───────────────┤
> > │
> > >>>>    │            │ ◄─────► │  pci ep Bus   │                   │
> > >>>>    └────────────┘         └───────────
> > ─
> > >> ──
> > >>>> ─┴───────────────────┘
> > >>>>      PCIe Root              PCIe Endpoint
> > >>>>
> > >>> [Frank Li] Some basic question,
> > >>> I see you call register_virtio_device at epf_vcon_setup_vdev,
> > >>> Why call it as virtio console?  I suppose it should be virtiobus directly?
> > >> I'm sorry I didn't understand your question. What do you mean the
> > >> virtiobus directly?
> > > I go through your code again.  I think I understand why you need pci-epf-
> > vcon.c.
> > > Actually,  my means is like virtio_mmio_probe.
> > >
> > > vm_dev->vdev.id.device = readl(vm_dev->base +
> > VIRTIO_MMIO_DEVICE_ID);
> > > vm_dev->vdev.id.vendor = readl(vm_dev->base +
> > VIRTIO_MMIO_VENDOR_ID);
> > >
> > > I am not sure that if VIRTIO_MMIO_VENDOR_ID and
> > VIRTIO_MMIO_DEVICE_ID
> > > reuse PCI's vendor ID and Device ID.  If yes, you can directly get such
> > information
> > > from epf.  If no,  a customer field can been added at epf driver.
> > >
> > > So you needn't write pci-epf-vcon  and pci-epf-vnet .....
> > >
> > > Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic
> > create platform
> > > Devices.  It may have some difficult because pci memory map requirement.
> > I think that some fields are shared between the vdev and epf device.
> > However, we need to implement device emulation because each virtio
> > device
> > has its specific set of tasks. For example, the virtio-net device has a
> > control queue, and the driver can request MAC filters, VLANs, and other
> > settings via this queue. These requests have to be processed by the virtio
> > device that we are implementing in pci-epf-vnet.
> >
> > The simplest virtio-console device doesn’t have these tasks, but the other
> > virtio devices requireprocessing them.
> >
> > That's why the current pci-epf-virtio design requires a specific
> > implementation for each virtio device.
> >
> > Is this what you meant
>
> I see. Thank you for explain.
> Thing may become complex. How to implement composite at EPF driver?
> Such as console + net
I'm not sure your suggestion. Could you tell me the advantages?
> >
> > >
> > >>> Previous you use virtio-net, why change to virtio-console here?  Does it
> > >> matter?
> > >>
> > >> No, it doesn't. Just I'd like to break down the changes into smaller
> > >> steps to make it easier to review and merge the changes.
> > >>
> > >> As a first step, I propose adding a simplest virtio function driver with
> > >> the extension defined in pci-epf-virtio.{h,c}.
> > >>
> > >>> All virtio-XXX should work?
> > >> Yes, the extension is designed to use any type of virtio device.
> > >>> You removed EDMA support this version?
> > >> I planed the support will be added with epf virtio-net patches.
> > >>>> Introduced driver is `pci ep virtio console drv` in the figure. It works
> > >>>> as ep function for PCIe root and virtual virtio console device for PCIe
> > >>>> endpoint. Each side of virtio console driver has virtqueue, and
> > >>>> introduced driver transfers data on the virtqueue to each other. A data
> > >>>> on root tx queue is transfered to endpoint rx queue and vice versa.
> > >>>>
> > >>>> This patchset is depend follwing patches which are under discussion.
> > >>>>
> > >>>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
> > >>>> link:
> > >>>>
> > >>
> > https://lore.k/
> > %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> > 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> > 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> > LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> > >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> > db3
> > >>
> > ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> > >>
> > 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > >>
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> > >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> > >>>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
> > >>>>
> > >>
> > mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> > >>
> > 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> > >>
> > C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> > >>
> > LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> > >>>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5
> > Mm
> > >> svo
> > >>>> %3D&reserved=0
> > >>>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
> > >>>> link:
> > >>>>
> > >>
> > https://lore.k/
> > %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> > 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> > 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> > LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> > >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> > db3
> > >>
> > ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> > >>
> > 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > >>
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> > >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> > >>>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
> > >>>>
> > >>
> > mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> > >>
> > 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> > >>
> > C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> > >>
> > LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> > >>>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WI
> > Z0
> > >> %3
> > >>>> D&reserved=0
> > >>>>
> > >>>> First of this patchset is introduce a helper function to realize pci
> > >>>> virtio function using PCIe endpoint framework. The second one is
> > adding
> > >>>> a missing definition for virtio pci header. The last one is for PCIe
> > >>>> endpoint virtio console driver.
> > >>>>
> > >>>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
> > >>>>
> > >>>> Shunsuke Mie (3):
> > >>>>     PCI: endpoint: introduce a helper to implement pci ep virtio function
> > >>>>     virtio_pci: add a definition of queue flag in ISR
> > >>>>     PCI: endpoint: Add EP function driver to provide virtio-console
> > >>>>       functionality
> > >>>>
> > >>>>    drivers/pci/endpoint/functions/Kconfig        |  19 +
> > >>>>    drivers/pci/endpoint/functions/Makefile       |   2 +
> > >>>>    drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
> > >> ++++++++++++++++++
> > >>>>    .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
> > >>>>    .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
> > >>>>    include/uapi/linux/virtio_pci.h               |   3 +
> > >>>>    6 files changed, 1170 insertions(+)
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
> > >>>>
> > >>>> --
> > >>>> 2.25.1
Best regards,
Shunsuike

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
@ 2023-04-24 10:06             ` Shunsuke Mie
  0 siblings, 0 replies; 19+ messages in thread
From: Shunsuke Mie @ 2023-04-24 10:06 UTC (permalink / raw)
  To: Frank Li
  Cc: Kishon Vijay Abraham I, Krzysztof Wilczyński, Randy Dunlap,
	Michael S. Tsirkin, linux-pci, Lorenzo Pieralisi,
	Manivannan Sadhasivam, linux-kernel, virtualization, Ren Zhijie,
	Jon Mason, Bjorn Helgaas

2023年4月19日(水) 1:42 Frank Li <frank.li@nxp.com>:
>
>
>
> > -----Original Message-----
> > From: Shunsuke Mie <mie@igel.co.jp>
> > Sent: Tuesday, April 18, 2023 5:31 AM
> > To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> > Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> > Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> > Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> > Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> > pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> > Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> >
> > Caution: EXT Email
> >
> > On 2023/04/18 0:19, Frank Li wrote:
> > >
> > >> -----Original Message-----
> > >> From: Shunsuke Mie <mie@igel.co.jp>
> > >> Sent: Sunday, April 16, 2023 9:12 PM
> > >> To: Frank Li <frank.li@nxp.com>; Lorenzo Pieralisi <lpieralisi@kernel.org>
> > >> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > >> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>; Bjorn
> > >> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin <mst@redhat.com>;
> > >> Jason Wang <jasowang@redhat.com>; Jon Mason <jdmason@kudzu.us>;
> > >> Randy Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > >> <renzhijie2@huawei.com>; linux-kernel@vger.kernel.org; linux-
> > >> pci@vger.kernel.org; virtualization@lists.linux-foundation.org
> > >> Subject: Re: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio
> > console
> > >>
> > >> Caution: EXT Email
> > >>
> > >> On 2023/04/14 23:39, Frank Li wrote:
> > >>>> -----Original Message-----
> > >>>> From: Shunsuke Mie <mie@igel.co.jp>
> > >>>> Sent: Friday, April 14, 2023 7:39 AM
> > >>>> To: Lorenzo Pieralisi <lpieralisi@kernel.org>
> > >>>> Cc: Krzysztof Wilczyński <kw@linux.com>; Manivannan Sadhasivam
> > >>>> <mani@kernel.org>; Kishon Vijay Abraham I <kishon@kernel.org>;
> > Bjorn
> > >>>> Helgaas <bhelgaas@google.com>; Michael S. Tsirkin
> > <mst@redhat.com>;
> > >>>> Jason Wang <jasowang@redhat.com>; Shunsuke Mie
> > <mie@igel.co.jp>;
> > >>>> Frank Li <frank.li@nxp.com>; Jon Mason <jdmason@kudzu.us>; Randy
> > >>>> Dunlap <rdunlap@infradead.org>; Ren Zhijie
> > <renzhijie2@huawei.com>;
> > >>>> linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> > >>>> virtualization@lists.linux-foundation.org
> > >>>> Subject: [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console
> > >>>>
> > >>>> Caution: EXT Email
> > >>>>
> > >>>> PCIe endpoint framework provides APIs to implement PCIe endpoint
> > >>>> function.
> > >>>> This framework allows defining various PCIe endpoint function
> > behaviors
> > >> in
> > >>>> software. This patch extend the framework for virtio pci device. The
> > >>>> virtio is defined to communicate guest on virtual machine and host side.
> > >>>> Advantage of the virtio is the efficiency of data transfer and the
> > >> conciseness
> > >>>> of implementation device using software. It also be applied to PCIe
> > >>>> endpoint function.
> > >>>>
> > >>>> We designed and implemented a PCIe EP virtio console function driver
> > >> using
> > >>>> the extended PCIe endpoint framework for virtio. It can be
> > communicate
> > >>>> host and endpoint over virtio as console.
> > >>>>
> > >>>> An architecture of the function driver is following:
> > >>>>
> > >>>>    ┌────────────┐         ┌───────────
> > ─
> > >> ──
> > >>>> ────────┬────────────┐
> > >>>>    │virtio      │         │                      │virtio      │
> > >>>>    │console drv │         ├───────────────┐      │
> > >> console
> > >>>> drv │
> > >>>>    ├────────────┤         │(virtio console│      ├──
> > ─
> > >> ──
> > >>>> ───────┤
> > >>>>    │ virtio bus │         │ device)       │◄────►│ virtio bus │
> > >>>>    ├────────────┤         ├---------------┤      └───
> > ─
> > >> ──
> > >>>> ──────┤
> > >>>>    │            │         │ pci ep virtio │                   │
> > >>>>    │  pci bus   │         │  console drv  │                   │
> > >>>>    │            │  pcie   ├───────────────┤
> > │
> > >>>>    │            │ ◄─────► │  pci ep Bus   │                   │
> > >>>>    └────────────┘         └───────────
> > ─
> > >> ──
> > >>>> ─┴───────────────────┘
> > >>>>      PCIe Root              PCIe Endpoint
> > >>>>
> > >>> [Frank Li] Some basic question,
> > >>> I see you call register_virtio_device at epf_vcon_setup_vdev,
> > >>> Why call it as virtio console?  I suppose it should be virtiobus directly?
> > >> I'm sorry I didn't understand your question. What do you mean the
> > >> virtiobus directly?
> > > I go through your code again.  I think I understand why you need pci-epf-
> > vcon.c.
> > > Actually,  my means is like virtio_mmio_probe.
> > >
> > > vm_dev->vdev.id.device = readl(vm_dev->base +
> > VIRTIO_MMIO_DEVICE_ID);
> > > vm_dev->vdev.id.vendor = readl(vm_dev->base +
> > VIRTIO_MMIO_VENDOR_ID);
> > >
> > > I am not sure that if VIRTIO_MMIO_VENDOR_ID and
> > VIRTIO_MMIO_DEVICE_ID
> > > reuse PCI's vendor ID and Device ID.  If yes, you can directly get such
> > information
> > > from epf.  If no,  a customer field can been added at epf driver.
> > >
> > > So you needn't write pci-epf-vcon  and pci-epf-vnet .....
> > >
> > > Of cause it will be wonderful if directly use virtio_mmio_probe by dynmatic
> > create platform
> > > Devices.  It may have some difficult because pci memory map requirement.
> > I think that some fields are shared between the vdev and epf device.
> > However, we need to implement device emulation because each virtio
> > device
> > has its specific set of tasks. For example, the virtio-net device has a
> > control queue, and the driver can request MAC filters, VLANs, and other
> > settings via this queue. These requests have to be processed by the virtio
> > device that we are implementing in pci-epf-vnet.
> >
> > The simplest virtio-console device doesn’t have these tasks, but the other
> > virtio devices requireprocessing them.
> >
> > That's why the current pci-epf-virtio design requires a specific
> > implementation for each virtio device.
> >
> > Is this what you meant
>
> I see. Thank you for explain.
> Thing may become complex. How to implement composite at EPF driver?
> Such as console + net
I'm not sure your suggestion. Could you tell me the advantages?
> >
> > >
> > >>> Previous you use virtio-net, why change to virtio-console here?  Does it
> > >> matter?
> > >>
> > >> No, it doesn't. Just I'd like to break down the changes into smaller
> > >> steps to make it easier to review and merge the changes.
> > >>
> > >> As a first step, I propose adding a simplest virtio function driver with
> > >> the extension defined in pci-epf-virtio.{h,c}.
> > >>
> > >>> All virtio-XXX should work?
> > >> Yes, the extension is designed to use any type of virtio device.
> > >>> You removed EDMA support this version?
> > >> I planed the support will be added with epf virtio-net patches.
> > >>>> Introduced driver is `pci ep virtio console drv` in the figure. It works
> > >>>> as ep function for PCIe root and virtual virtio console device for PCIe
> > >>>> endpoint. Each side of virtio console driver has virtqueue, and
> > >>>> introduced driver transfers data on the virtqueue to each other. A data
> > >>>> on root tx queue is transfered to endpoint rx queue and vice versa.
> > >>>>
> > >>>> This patchset is depend follwing patches which are under discussion.
> > >>>>
> > >>>> - [RFC PATCH 0/3] Deal with alignment restriction on EP side
> > >>>> link:
> > >>>>
> > >>
> > https://lore.k/
> > %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> > 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> > 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> > LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> > >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> > db3
> > >>
> > ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> > >>
> > 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > >>
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> > >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> > >>>> ernel.org%2Flinux-pci%2F20230113090350.1103494-1-
> > >>>>
> > >>
> > mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> > >>
> > 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> > >>
> > C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> > >>
> > LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> > >>>> %7C%7C&sdata=jYgy%2Bxk84ZXZRVfqm0GCXoRnCTLMrX4zTfV%2Bs5
> > Mm
> > >> svo
> > >>>> %3D&reserved=0
> > >>>> - [RFC PATCH v2 0/7] Introduce a vringh accessor for IO memory
> > >>>> link:
> > >>>>
> > >>
> > https://lore.k/
> > %2F&data=05%7C01%7Cfrank.li%40nxp.com%7C80a237184ff4420a96de08db
> > 3ff80d78%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817410683
> > 2489955%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=LSP
> > LeFzTYpUVTZpymoM00Es9kOpxlN90%2BDM6ceDJMFE%3D&reserved=0
> > >> %2F&data=05%7C01%7Cfrank.li%40nxp.com%7Cff59a16f88c643913e3908
> > db3
> > >>
> > ee91ca8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63817294315
> > >>
> > 3821831%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> > >>
> > 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=hTB
> > >> 5UDaJoJfta9ohMG%2BrxCVJY34ANn10iSLP9iCHX3M%3D&reserved=0
> > >>>> ernel.org%2Fvirtualization%2F20230202090934.549556-1-
> > >>>>
> > >>
> > mie%40igel.co.jp%2F&data=05%7C01%7CFrank.Li%40nxp.com%7Cea6513dbf
> > >>
> > 4084b80ced208db3ce54133%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> > >>
> > C0%7C638170727558800720%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> > >>
> > LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> > >>>> %7C%7C&sdata=K4El76GSAGtsWkNBXJK5%2Fn7flCN20eEMZpZYTX2WI
> > Z0
> > >> %3
> > >>>> D&reserved=0
> > >>>>
> > >>>> First of this patchset is introduce a helper function to realize pci
> > >>>> virtio function using PCIe endpoint framework. The second one is
> > adding
> > >>>> a missing definition for virtio pci header. The last one is for PCIe
> > >>>> endpoint virtio console driver.
> > >>>>
> > >>>> This is tested on linux-20230406 and RCar S4 board as PCIe endpoint.
> > >>>>
> > >>>> Shunsuke Mie (3):
> > >>>>     PCI: endpoint: introduce a helper to implement pci ep virtio function
> > >>>>     virtio_pci: add a definition of queue flag in ISR
> > >>>>     PCI: endpoint: Add EP function driver to provide virtio-console
> > >>>>       functionality
> > >>>>
> > >>>>    drivers/pci/endpoint/functions/Kconfig        |  19 +
> > >>>>    drivers/pci/endpoint/functions/Makefile       |   2 +
> > >>>>    drivers/pci/endpoint/functions/pci-epf-vcon.c | 554
> > >> ++++++++++++++++++
> > >>>>    .../pci/endpoint/functions/pci-epf-virtio.c   | 469 +++++++++++++++
> > >>>>    .../pci/endpoint/functions/pci-epf-virtio.h   | 123 ++++
> > >>>>    include/uapi/linux/virtio_pci.h               |   3 +
> > >>>>    6 files changed, 1170 insertions(+)
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-vcon.c
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.c
> > >>>>    create mode 100644 drivers/pci/endpoint/functions/pci-epf-virtio.h
> > >>>>
> > >>>> --
> > >>>> 2.25.1
Best regards,
Shunsuike
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2023-04-24 10:07 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-14 12:39 [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console Shunsuke Mie
2023-04-14 12:39 ` Shunsuke Mie
2023-04-14 12:39 ` [RFC PATCH 1/3] PCI: endpoint: introduce a helper to implement pci ep virtio function Shunsuke Mie
2023-04-14 12:39   ` Shunsuke Mie
2023-04-14 12:39 ` [RFC PATCH 2/3] virtio_pci: add a definition of queue flag in ISR Shunsuke Mie
2023-04-14 12:39   ` Shunsuke Mie
2023-04-14 12:39 ` [RFC PATCH 3/3] PCI: endpoint: Add EP function driver to provide virtio-console functionality Shunsuke Mie
2023-04-14 12:39   ` Shunsuke Mie
2023-04-14 14:45   ` kernel test robot
2023-04-14 16:29   ` kernel test robot
2023-04-14 14:39 ` [EXT] [RFC PATCH 0/3] Introduce a PCIe endpoint virtio console Frank Li
2023-04-17  2:11   ` Shunsuke Mie
2023-04-17  2:11     ` Shunsuke Mie
2023-04-17 15:19     ` Frank Li
2023-04-18 10:31       ` Shunsuke Mie
2023-04-18 10:31         ` Shunsuke Mie
2023-04-18 16:42         ` Frank Li
2023-04-24 10:06           ` Shunsuke Mie
2023-04-24 10:06             ` Shunsuke Mie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.