From: wanghaibin wanghaibin.wang@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8UROS CVE: NA
--------------------------------
This driver porbed the virt platform device by name, and it just take up a few MSIs through the vp_irqdomain.
Signed-off-by: wanghaibin wanghaibin.wang@huawei.com Signed-off-by: Zenghui Yu yuzenghui@huawei.com Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com Signed-off-by: Dongxu Sun sundongxu3@huawei.com --- drivers/misc/Kconfig | 9 +++ drivers/misc/Makefile | 1 + drivers/misc/virt_plat_dev.c | 119 +++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 drivers/misc/virt_plat_dev.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index cadd4a820c03..30897ad1bbf7 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -493,6 +493,15 @@ config HISI_HIKEY_USB switching between the dual-role USB-C port and the USB-A host ports using only one USB controller.
+config VIRT_PLAT_DEV + depends on KVM && ARM64 && ARCH_HISI + default y + tristate "virt platform device driver" + help + Enable this configuration option to probe the virtual platform device, + which created for the Qemu emulated device to implement virtual MSI + direct injection. + config OPEN_DICE tristate "Open Profile for DICE driver" depends on OF_RESERVED_MEM diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f2a4d1ff65d4..4592c454be3b 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_PVPANIC) += pvpanic/ obj-$(CONFIG_UACCE) += uacce/ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o +obj-$(CONFIG_VIRT_PLAT_DEV) += virt_plat_dev.o obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o obj-$(CONFIG_OPEN_DICE) += open-dice.o obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/ diff --git a/drivers/misc/virt_plat_dev.c b/drivers/misc/virt_plat_dev.c new file mode 100644 index 000000000000..902d2a7ad0f0 --- /dev/null +++ b/drivers/misc/virt_plat_dev.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019-2020 HUAWEI TECHNOLOGIES CO., LTD., All Rights Reserved. + * Author: Wanghaibin wanghaibin.wang@huawei.com + */ +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/msi.h> +#include <linux/platform_device.h> +#include <linux/uaccess.h> +#include <linux/device.h> + +#define VIRT_DEV_DEBUG 1 + +#ifdef VIRT_DEV_DEBUG +#define virtdev_info(fmt, ...) pr_info("virdev: " fmt, ## __VA_ARGS__) +#else +#define virtdev_info(fmt, ...) +#endif + +static irqreturn_t virt_irq_handle(int irq, void *data) +{ + return IRQ_HANDLED; +} + +static void virt_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg) +{ +} + +static int virt_device_probe(struct platform_device *pdev) +{ + struct msi_desc *desc; + unsigned int *drvdata = dev_get_drvdata(&pdev->dev); + unsigned int nvec = *drvdata; + struct irq_domain *vp_irqdomain = vp_get_irq_domain(); + int ret; + + if (!vp_irqdomain) + return -ENXIO; + + virtdev_info("Allocate platform msi irqs nvecs: %d\n", nvec); + dev_set_msi_domain(&pdev->dev, vp_irqdomain); + + ret = platform_msi_domain_alloc_irqs(&pdev->dev, nvec, + virt_write_msi_msg); + if (ret) { + pr_err("Allocate platform msi irqs failed %d\n", ret); + goto error; + } + + virtdev_info("Allocate platform msi irqs succeed\n"); + msi_for_each_desc(desc, &pdev->dev, MSI_DESC_ALL) { + virtdev_info("Request irq %d\n", desc->irq); + ret = request_irq(desc->irq, virt_irq_handle, 0, + "virt_dev_host", pdev); + if (ret) { + pr_err("Request irq %d failed %d\n", desc->irq, ret); + goto error_free_irqs; + } + } + + virtdev_info("Init virtual platform device driver successfully.\n"); + return 0; + +error_free_irqs: + msi_for_each_desc(desc, &pdev->dev, MSI_DESC_ALL) + free_irq(desc->irq, pdev); + + platform_msi_domain_free_irqs(&pdev->dev); +error: + return ret; +} + +static int virt_device_remove(struct platform_device *pdev) +{ + struct msi_desc *desc; + + virtdev_info("%s\n", __func__); + msi_for_each_desc(desc, &pdev->dev, MSI_DESC_ALL) + free_irq(desc->irq, pdev); + + platform_msi_domain_free_irqs(&pdev->dev); + + return 0; +} + +static struct platform_driver virtdev_driver = { + .driver = { + /* Using the device & driver name to match each other */ + .name = "virt_plat_dev", + }, + .probe = virt_device_probe, + .remove = virt_device_remove, +}; + +static int __init virtdev_init(void) +{ + int ret; + + ret = platform_driver_register(&virtdev_driver); + if (ret) { + pr_err("Register virtdev platform driver failed (%d)\n", ret); + return ret; + } + + virtdev_info("Register virtdev platform driver succeed.\n"); + return 0; +} +module_init(virtdev_init); + +static void __exit virtdev_exit(void) +{ + platform_driver_unregister(&virtdev_driver); +} +module_exit(virtdev_exit); + +MODULE_LICENSE("GPL v2");