[PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings

Sudan Landge posted 4 patches 1 year, 10 months ago
There is a newer version of this series
[PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by Sudan Landge 1 year, 10 months ago
Extend the vmgenid platform driver to support devicetree bindings.
With this support, hypervisors can send vmgenid notifications to
the virtual machine without the need to enable ACPI.

The bindings are located at:
- Documentation/devicetree/bindings/vmgenid/vmgenid.yaml

Signed-off-by: Sudan Landge <sudanl@amazon.com>
---
 drivers/virt/Kconfig   |  2 +-
 drivers/virt/vmgenid.c | 90 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 40129b6f0eca..4f33ee2f0372 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -16,7 +16,7 @@ if VIRT_DRIVERS
 config VMGENID
 	tristate "Virtual Machine Generation ID driver"
 	default y
-	depends on ACPI
+	depends on (ACPI || OF)
 	help
 	  Say Y here to use the hypervisor-provided Virtual Machine Generation ID
 	  to reseed the RNG when the VM is cloned. This is highly recommended if
diff --git a/drivers/virt/vmgenid.c b/drivers/virt/vmgenid.c
index e82b344a9d61..96a3ff8ec05a 100644
--- a/drivers/virt/vmgenid.c
+++ b/drivers/virt/vmgenid.c
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  *
- * The "Virtual Machine Generation ID" is exposed via ACPI and changes when a
+ * The "Virtual Machine Generation ID" is exposed via ACPI or DT and changes when a
  * virtual machine forks or is cloned. This driver exists for shepherding that
  * information to random.c.
  */
@@ -12,6 +12,12 @@
 #include <linux/acpi.h>
 #include <linux/random.h>
 #include <acpi/actypes.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 
 ACPI_MODULE_NAME("vmgenid");
@@ -21,6 +27,7 @@ enum { VMGENID_SIZE = 16 };
 struct vmgenid_state {
 	u8 *next_id;
 	u8 this_id[VMGENID_SIZE];
+	unsigned int irq;
 };
 
 static void vmgenid_notify(struct device *device)
@@ -42,6 +49,13 @@ static void vmgenid_acpi_handler(acpi_handle handle, u32 event, void *dev)
 	vmgenid_notify(dev);
 }
 
+static irqreturn_t vmgenid_of_irq_handler(int irq, void *dev)
+{
+	vmgenid_notify(dev);
+
+	return IRQ_HANDLED;
+}
+
 static int setup_vmgenid_state(struct vmgenid_state *state, u8 *next_id)
 {
 	if (IS_ERR(next_id))
@@ -98,6 +112,43 @@ static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
 	return ret;
 }
 
+static int vmgenid_add_of(struct device *dev, struct vmgenid_state *state)
+{
+	struct resource res;
+	int ret = 0;
+
+	if (of_address_to_resource(dev->of_node, 0, &res)) {
+		dev_err(dev, "Failed to get resources from device tree");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!__request_mem_region(res.start, resource_size(&res),
+				  "vmgenid", IORESOURCE_EXCLUSIVE)) {
+		dev_err(dev, "Failed to request mem region");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = setup_vmgenid_state(state, of_iomap(dev->of_node, 0));
+	if (ret)
+		goto out;
+
+	state->irq = irq_of_parse_and_map(dev->of_node, 0);
+	dev->driver_data = state;
+
+	if (request_irq(state->irq, vmgenid_of_irq_handler,
+			IRQF_SHARED, "vmgenid", dev) < 0) {
+		dev_err(dev, "request_irq failed");
+		dev->driver_data = NULL;
+		ret = -EINVAL;
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
 static int vmgenid_add(struct platform_device *pdev)
 {
 	struct vmgenid_state *state;
@@ -108,7 +159,10 @@ static int vmgenid_add(struct platform_device *pdev)
 	if (!state)
 		return -ENOMEM;
 
-	ret = vmgenid_add_acpi(dev, state);
+	if (dev->of_node)
+		ret = vmgenid_add_of(dev, state);
+	else
+		ret = vmgenid_add_acpi(dev, state);
 
 	if (ret)
 		devm_kfree(dev, state);
@@ -116,7 +170,30 @@ static int vmgenid_add(struct platform_device *pdev)
 	return ret;
 }
 
-static const struct acpi_device_id vmgenid_ids[] = {
+static int vmgenid_remove(struct platform_device *pdev)
+{
+	struct vmgenid_state *state = NULL;
+
+	if (!pdev)
+		return -EINVAL;
+
+	state = pdev->dev.driver_data;
+
+	if (state && pdev->dev.of_node)
+		free_irq(state->irq, &pdev->dev);
+
+	if (state)
+		devm_kfree(&pdev->dev, state);
+
+	return 0;
+}
+
+static const struct of_device_id vmgenid_of_ids[] = {
+	{ .compatible = "linux,vmgenctr", },
+	{},
+};
+
+static const struct acpi_device_id vmgenid_acpi_ids[] = {
 	{ "VMGENCTR", 0 },
 	{ "VM_GEN_COUNTER", 0 },
 	{ }
@@ -124,9 +201,11 @@ static const struct acpi_device_id vmgenid_ids[] = {
 
 static struct platform_driver vmgenid_plaform_driver = {
 	.probe      = vmgenid_add,
+	.remove     = vmgenid_remove,
 	.driver     = {
 		.name   = "vmgenid",
-		.acpi_match_table = ACPI_PTR(vmgenid_ids),
+		.acpi_match_table = ACPI_PTR(vmgenid_acpi_ids),
+		.of_match_table = vmgenid_of_ids,
 		.owner = THIS_MODULE,
 	},
 };
@@ -144,7 +223,8 @@ static void vmgenid_platform_device_exit(void)
 module_init(vmgenid_platform_device_init)
 module_exit(vmgenid_platform_device_exit)
 
-MODULE_DEVICE_TABLE(acpi, vmgenid_ids);
+MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids);
+MODULE_DEVICE_TABLE(of, vmgenid_of_ids);
 MODULE_DESCRIPTION("Virtual Machine Generation ID");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
-- 
2.40.1
Re: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by kernel test robot 1 year, 10 months ago
Hi Sudan,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.8 next-20240320]
[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/Sudan-Landge/virt-vmgenid-rearrange-code-to-make-review-easier/20240319-223642
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240319143253.22317-5-sudanl%40amazon.com
patch subject: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20240321/202403210806.pMEGAp0x-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240321/202403210806.pMEGAp0x-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403210806.pMEGAp0x-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/virt/vmgenid.c: In function 'vmgenid_add_acpi':
>> drivers/virt/vmgenid.c:79:45: error: invalid use of undefined type 'struct acpi_device'
      79 |         status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
         |                                             ^~
   drivers/virt/vmgenid.c:96:56: error: invalid use of undefined type 'struct acpi_device'
      96 |                                   devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB)
         |                                                        ^~
   drivers/virt/vmgenid.c:102:52: error: invalid use of undefined type 'struct acpi_device'
     102 |         status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
         |                                                    ^~
   drivers/virt/vmgenid.c: At top level:
   drivers/virt/vmgenid.c:196:36: warning: 'vmgenid_acpi_ids' defined but not used [-Wunused-const-variable=]
     196 | static const struct acpi_device_id vmgenid_acpi_ids[] = {
         |                                    ^~~~~~~~~~~~~~~~


vim +79 drivers/virt/vmgenid.c

657fab4d1001e1 Sudan Landge       2024-03-19   69  
657fab4d1001e1 Sudan Landge       2024-03-19   70  static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
657fab4d1001e1 Sudan Landge       2024-03-19   71  {
657fab4d1001e1 Sudan Landge       2024-03-19   72  	struct acpi_device *device = ACPI_COMPANION(dev);
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   73  	struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   74  	union acpi_object *obj;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   75  	phys_addr_t phys_addr;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   76  	acpi_status status;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   77  	int ret = 0;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   78  
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  @79  	status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   80  	if (ACPI_FAILURE(status)) {
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   81  		ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   82  		return -ENODEV;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   83  	}
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   84  	obj = parsed.pointer;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   85  	if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2 ||
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   86  	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   87  	    obj->package.elements[1].type != ACPI_TYPE_INTEGER) {
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   88  		ret = -EINVAL;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   89  		goto out;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   90  	}
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   91  
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   92  	phys_addr = (obj->package.elements[0].integer.value << 0) |
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   93  		    (obj->package.elements[1].integer.value << 32);
657fab4d1001e1 Sudan Landge       2024-03-19   94  
657fab4d1001e1 Sudan Landge       2024-03-19   95  	ret = setup_vmgenid_state(state,
657fab4d1001e1 Sudan Landge       2024-03-19   96  				  devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB)
657fab4d1001e1 Sudan Landge       2024-03-19   97  				 );
657fab4d1001e1 Sudan Landge       2024-03-19   98  	if (ret)
657fab4d1001e1 Sudan Landge       2024-03-19   99  		goto out;
657fab4d1001e1 Sudan Landge       2024-03-19  100  
657fab4d1001e1 Sudan Landge       2024-03-19  101  	dev->driver_data = state;
657fab4d1001e1 Sudan Landge       2024-03-19  102  	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
657fab4d1001e1 Sudan Landge       2024-03-19  103  					     vmgenid_acpi_handler, dev);
657fab4d1001e1 Sudan Landge       2024-03-19  104  	if (ACPI_FAILURE(status)) {
657fab4d1001e1 Sudan Landge       2024-03-19  105  		dev_err(dev, "Failed to install acpi notify handler");
657fab4d1001e1 Sudan Landge       2024-03-19  106  		ret = -ENODEV;
657fab4d1001e1 Sudan Landge       2024-03-19  107  		dev->driver_data = NULL;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  108  		goto out;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  109  	}
657fab4d1001e1 Sudan Landge       2024-03-19  110  out:
657fab4d1001e1 Sudan Landge       2024-03-19  111  	ACPI_FREE(parsed.pointer);
657fab4d1001e1 Sudan Landge       2024-03-19  112  	return ret;
657fab4d1001e1 Sudan Landge       2024-03-19  113  }
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  114  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by kernel test robot 1 year, 10 months ago
Hi Sudan,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.8 next-20240320]
[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/Sudan-Landge/virt-vmgenid-rearrange-code-to-make-review-easier/20240319-223642
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240319143253.22317-5-sudanl%40amazon.com
patch subject: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240321/202403210035.LODSw2s6-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 8f68022f8e6e54d1aeae4ed301f5a015963089b7)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240321/202403210035.LODSw2s6-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403210035.LODSw2s6-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/virt/vmgenid.c:16:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from drivers/virt/vmgenid.c:16:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from drivers/virt/vmgenid.c:16:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
>> drivers/virt/vmgenid.c:79:38: error: incomplete definition of type 'struct acpi_device'
      79 |         status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
         |                                       ~~~~~~^
   include/linux/acpi.h:795:8: note: forward declaration of 'struct acpi_device'
     795 | struct acpi_device;
         |        ^
   drivers/virt/vmgenid.c:96:28: error: incomplete definition of type 'struct acpi_device'
      96 |                                   devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB)
         |                                                  ~~~~~~^
   include/linux/acpi.h:795:8: note: forward declaration of 'struct acpi_device'
     795 | struct acpi_device;
         |        ^
   drivers/virt/vmgenid.c:102:45: error: incomplete definition of type 'struct acpi_device'
     102 |         status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
         |                                              ~~~~~~^
   include/linux/acpi.h:795:8: note: forward declaration of 'struct acpi_device'
     795 | struct acpi_device;
         |        ^
   6 warnings and 3 errors generated.


vim +79 drivers/virt/vmgenid.c

657fab4d1001e1 Sudan Landge       2024-03-19   69  
657fab4d1001e1 Sudan Landge       2024-03-19   70  static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
657fab4d1001e1 Sudan Landge       2024-03-19   71  {
657fab4d1001e1 Sudan Landge       2024-03-19   72  	struct acpi_device *device = ACPI_COMPANION(dev);
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   73  	struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   74  	union acpi_object *obj;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   75  	phys_addr_t phys_addr;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   76  	acpi_status status;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   77  	int ret = 0;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   78  
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  @79  	status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   80  	if (ACPI_FAILURE(status)) {
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   81  		ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   82  		return -ENODEV;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   83  	}
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   84  	obj = parsed.pointer;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   85  	if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2 ||
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   86  	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   87  	    obj->package.elements[1].type != ACPI_TYPE_INTEGER) {
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   88  		ret = -EINVAL;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   89  		goto out;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   90  	}
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   91  
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   92  	phys_addr = (obj->package.elements[0].integer.value << 0) |
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23   93  		    (obj->package.elements[1].integer.value << 32);
657fab4d1001e1 Sudan Landge       2024-03-19   94  
657fab4d1001e1 Sudan Landge       2024-03-19   95  	ret = setup_vmgenid_state(state,
657fab4d1001e1 Sudan Landge       2024-03-19   96  				  devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB)
657fab4d1001e1 Sudan Landge       2024-03-19   97  				 );
657fab4d1001e1 Sudan Landge       2024-03-19   98  	if (ret)
657fab4d1001e1 Sudan Landge       2024-03-19   99  		goto out;
657fab4d1001e1 Sudan Landge       2024-03-19  100  
657fab4d1001e1 Sudan Landge       2024-03-19  101  	dev->driver_data = state;
657fab4d1001e1 Sudan Landge       2024-03-19  102  	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
657fab4d1001e1 Sudan Landge       2024-03-19  103  					     vmgenid_acpi_handler, dev);
657fab4d1001e1 Sudan Landge       2024-03-19  104  	if (ACPI_FAILURE(status)) {
657fab4d1001e1 Sudan Landge       2024-03-19  105  		dev_err(dev, "Failed to install acpi notify handler");
657fab4d1001e1 Sudan Landge       2024-03-19  106  		ret = -ENODEV;
657fab4d1001e1 Sudan Landge       2024-03-19  107  		dev->driver_data = NULL;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  108  		goto out;
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  109  	}
657fab4d1001e1 Sudan Landge       2024-03-19  110  out:
657fab4d1001e1 Sudan Landge       2024-03-19  111  	ACPI_FREE(parsed.pointer);
657fab4d1001e1 Sudan Landge       2024-03-19  112  	return ret;
657fab4d1001e1 Sudan Landge       2024-03-19  113  }
af6b54e2b5baa5 Jason A. Donenfeld 2022-02-23  114  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by kernel test robot 1 year, 10 months ago
Hi Sudan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on linus/master v6.8 next-20240320]
[cannot apply to crng-random/master]
[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/Sudan-Landge/virt-vmgenid-rearrange-code-to-make-review-easier/20240319-223642
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240319143253.22317-5-sudanl%40amazon.com
patch subject: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
config: x86_64-randconfig-121-20240320 (https://download.01.org/0day-ci/archive/20240320/202403202139.GabdWRiZ-lkp@intel.com/config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240320/202403202139.GabdWRiZ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403202139.GabdWRiZ-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/virt/vmgenid.c:133:50: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected unsigned char [usertype] *next_id @@     got void [noderef] __iomem * @@
   drivers/virt/vmgenid.c:133:50: sparse:     expected unsigned char [usertype] *next_id
   drivers/virt/vmgenid.c:133:50: sparse:     got void [noderef] __iomem *

vim +133 drivers/virt/vmgenid.c

   114	
   115	static int vmgenid_add_of(struct device *dev, struct vmgenid_state *state)
   116	{
   117		struct resource res;
   118		int ret = 0;
   119	
   120		if (of_address_to_resource(dev->of_node, 0, &res)) {
   121			dev_err(dev, "Failed to get resources from device tree");
   122			ret = -EINVAL;
   123			goto out;
   124		}
   125	
   126		if (!__request_mem_region(res.start, resource_size(&res),
   127					  "vmgenid", IORESOURCE_EXCLUSIVE)) {
   128			dev_err(dev, "Failed to request mem region");
   129			ret = -EINVAL;
   130			goto out;
   131		}
   132	
 > 133		ret = setup_vmgenid_state(state, of_iomap(dev->of_node, 0));
   134		if (ret)
   135			goto out;
   136	
   137		state->irq = irq_of_parse_and_map(dev->of_node, 0);
   138		dev->driver_data = state;
   139	
   140		if (request_irq(state->irq, vmgenid_of_irq_handler,
   141				IRQF_SHARED, "vmgenid", dev) < 0) {
   142			dev_err(dev, "request_irq failed");
   143			dev->driver_data = NULL;
   144			ret = -EINVAL;
   145			goto out;
   146		}
   147	
   148	out:
   149		return ret;
   150	}
   151	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by kernel test robot 1 year, 10 months ago
Hi Sudan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on linus/master v6.8 next-20240320]
[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/Sudan-Landge/virt-vmgenid-rearrange-code-to-make-review-easier/20240319-223642
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240319143253.22317-5-sudanl%40amazon.com
patch subject: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20240320/202403201544.8xvAuo13-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240320/202403201544.8xvAuo13-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403201544.8xvAuo13-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/virt/vmgenid.c: In function 'vmgenid_add_acpi':
   drivers/virt/vmgenid.c:79:45: error: invalid use of undefined type 'struct acpi_device'
      79 |         status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
         |                                             ^~
   drivers/virt/vmgenid.c:96:56: error: invalid use of undefined type 'struct acpi_device'
      96 |                                   devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB)
         |                                                        ^~
   drivers/virt/vmgenid.c:102:52: error: invalid use of undefined type 'struct acpi_device'
     102 |         status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
         |                                                    ^~
   drivers/virt/vmgenid.c: At top level:
>> drivers/virt/vmgenid.c:196:36: warning: 'vmgenid_acpi_ids' defined but not used [-Wunused-const-variable=]
     196 | static const struct acpi_device_id vmgenid_acpi_ids[] = {
         |                                    ^~~~~~~~~~~~~~~~


vim +/vmgenid_acpi_ids +196 drivers/virt/vmgenid.c

   195	
 > 196	static const struct acpi_device_id vmgenid_acpi_ids[] = {
   197		{ "VMGENCTR", 0 },
   198		{ "VM_GEN_COUNTER", 0 },
   199		{ }
   200	};
   201	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 4/4] virt: vmgenid: add support for devicetree bindings
Posted by Krzysztof Kozlowski 1 year, 10 months ago
On 19/03/2024 15:32, Sudan Landge wrote:
> Extend the vmgenid platform driver to support devicetree bindings.
> With this support, hypervisors can send vmgenid notifications to
> the virtual machine without the need to enable ACPI.
> 
> The bindings are located at:
> - Documentation/devicetree/bindings/vmgenid/vmgenid.yaml
> 
> Signed-off-by: Sudan Landge <sudanl@amazon.com>
> ---
>  drivers/virt/Kconfig   |  2 +-
>  drivers/virt/vmgenid.c | 90 +++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 86 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
> index 40129b6f0eca..4f33ee2f0372 100644
> --- a/drivers/virt/Kconfig
> +++ b/drivers/virt/Kconfig
> @@ -16,7 +16,7 @@ if VIRT_DRIVERS
>  config VMGENID
>  	tristate "Virtual Machine Generation ID driver"
>  	default y
> -	depends on ACPI
> +	depends on (ACPI || OF)
>  	help
>  	  Say Y here to use the hypervisor-provided Virtual Machine Generation ID
>  	  to reseed the RNG when the VM is cloned. This is highly recommended if
> diff --git a/drivers/virt/vmgenid.c b/drivers/virt/vmgenid.c
> index e82b344a9d61..96a3ff8ec05a 100644
> --- a/drivers/virt/vmgenid.c
> +++ b/drivers/virt/vmgenid.c
> @@ -2,7 +2,7 @@
>  /*
>   * Copyright (C) 2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
>   *
> - * The "Virtual Machine Generation ID" is exposed via ACPI and changes when a
> + * The "Virtual Machine Generation ID" is exposed via ACPI or DT and changes when a
>   * virtual machine forks or is cloned. This driver exists for shepherding that
>   * information to random.c.
>   */
> @@ -12,6 +12,12 @@
>  #include <linux/acpi.h>
>  #include <linux/random.h>
>  #include <acpi/actypes.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
>  #include <linux/platform_device.h>
>  
>  ACPI_MODULE_NAME("vmgenid");
> @@ -21,6 +27,7 @@ enum { VMGENID_SIZE = 16 };
>  struct vmgenid_state {
>  	u8 *next_id;
>  	u8 this_id[VMGENID_SIZE];
> +	unsigned int irq;
>  };
>  
>  static void vmgenid_notify(struct device *device)
> @@ -42,6 +49,13 @@ static void vmgenid_acpi_handler(acpi_handle handle, u32 event, void *dev)
>  	vmgenid_notify(dev);
>  }
>  
> +static irqreturn_t vmgenid_of_irq_handler(int irq, void *dev)
> +{
> +	vmgenid_notify(dev);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int setup_vmgenid_state(struct vmgenid_state *state, u8 *next_id)
>  {
>  	if (IS_ERR(next_id))
> @@ -98,6 +112,43 @@ static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
>  	return ret;
>  }
>  
> +static int vmgenid_add_of(struct device *dev, struct vmgenid_state *state)
> +{
> +	struct resource res;
> +	int ret = 0;
> +
> +	if (of_address_to_resource(dev->of_node, 0, &res)) {
> +		dev_err(dev, "Failed to get resources from device tree");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	if (!__request_mem_region(res.start, resource_size(&res),
> +				  "vmgenid", IORESOURCE_EXCLUSIVE)) {
> +		dev_err(dev, "Failed to request mem region");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	ret = setup_vmgenid_state(state, of_iomap(dev->of_node, 0));
> +	if (ret)
> +		goto out;
> +
> +	state->irq = irq_of_parse_and_map(dev->of_node, 0);
> +	dev->driver_data = state;
> +
> +	if (request_irq(state->irq, vmgenid_of_irq_handler,
> +			IRQF_SHARED, "vmgenid", dev) < 0) {
> +		dev_err(dev, "request_irq failed");
> +		dev->driver_data = NULL;
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static int vmgenid_add(struct platform_device *pdev)
>  {
>  	struct vmgenid_state *state;
> @@ -108,7 +159,10 @@ static int vmgenid_add(struct platform_device *pdev)
>  	if (!state)
>  		return -ENOMEM;
>  
> -	ret = vmgenid_add_acpi(dev, state);
> +	if (dev->of_node)
> +		ret = vmgenid_add_of(dev, state);
> +	else
> +		ret = vmgenid_add_acpi(dev, state);
>  
>  	if (ret)
>  		devm_kfree(dev, state);
> @@ -116,7 +170,30 @@ static int vmgenid_add(struct platform_device *pdev)
>  	return ret;
>  }
>  
> -static const struct acpi_device_id vmgenid_ids[] = {
> +static int vmgenid_remove(struct platform_device *pdev)
> +{
> +	struct vmgenid_state *state = NULL;
> +

How is this related to the patch? Removal is valid (or invalid)
regardless your bind method.

> +	if (!pdev)
> +		return -EINVAL;
> +
> +	state = pdev->dev.driver_data;
> +
> +	if (state && pdev->dev.of_node)
> +		free_irq(state->irq, &pdev->dev);
> +
> +	if (state)
> +		devm_kfree(&pdev->dev, state);

Why do you free devm memory? Which driver callback allocated it?

> +
> +	return 0;
> +}
> +
> +static const struct of_device_id vmgenid_of_ids[] = {
> +	{ .compatible = "linux,vmgenctr", },
> +	{},
> +};
> +
> +static const struct acpi_device_id vmgenid_acpi_ids[] = {
>  	{ "VMGENCTR", 0 },
>  	{ "VM_GEN_COUNTER", 0 },
>  	{ }
> @@ -124,9 +201,11 @@ static const struct acpi_device_id vmgenid_ids[] = {
>  
>  static struct platform_driver vmgenid_plaform_driver = {
>  	.probe      = vmgenid_add,
> +	.remove     = vmgenid_remove,
>  	.driver     = {
>  		.name   = "vmgenid",
> -		.acpi_match_table = ACPI_PTR(vmgenid_ids),
> +		.acpi_match_table = ACPI_PTR(vmgenid_acpi_ids),
> +		.of_match_table = vmgenid_of_ids,
>  		.owner = THIS_MODULE,
>  	},
>  };
> @@ -144,7 +223,8 @@ static void vmgenid_platform_device_exit(void)
>  module_init(vmgenid_platform_device_init)
>  module_exit(vmgenid_platform_device_exit)
>  
> -MODULE_DEVICE_TABLE(acpi, vmgenid_ids);
> +MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids);
> +MODULE_DEVICE_TABLE(of, vmgenid_of_ids);

MODULE_DEVICE_TABLE goes immediately after the table.


Best regards,
Krzysztof