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
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
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
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
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
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
© 2016 - 2026 Red Hat, Inc.