Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

virt: vmgenid: add support for devicetree bindings

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/rng/microsoft,vmgenid.yaml

Since this is no longer ACPI-dependent, remove the dependency from
Kconfig and protect the ACPI code with a single ifdef.

Signed-off-by: Sudan Landge <sudanl@amazon.com>
Reviewed-by: Alexander Graf <graf@amazon.com>
Tested-by: Babis Chalios <bchalios@amazon.es>
[Jason: - Small style cleanups and refactoring.
- Re-work ACPI conditionalization. ]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>

authored by

Sudan Landge and committed by
Jason A. Donenfeld
7b1bcd6b a4aded1f

+51 -3
-1
drivers/virt/Kconfig
··· 16 16 config VMGENID 17 17 tristate "Virtual Machine Generation ID driver" 18 18 default y 19 - depends on ACPI 20 19 help 21 20 Say Y here to use the hypervisor-provided Virtual Machine Generation ID 22 21 to reseed the RNG when the VM is cloned. This is highly recommended if
+51 -2
drivers/virt/vmgenid.c
··· 2 2 /* 3 3 * Copyright (C) 2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 4 4 * 5 - * The "Virtual Machine Generation ID" is exposed via ACPI and changes when a 5 + * The "Virtual Machine Generation ID" is exposed via ACPI or DT and changes when a 6 6 * virtual machine forks or is cloned. This driver exists for shepherding that 7 7 * information to random.c. 8 8 */ 9 9 10 10 #include <linux/acpi.h> 11 + #include <linux/interrupt.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/module.h> 13 14 #include <linux/platform_device.h> ··· 42 41 add_device_randomness(state->this_id, sizeof(state->this_id)); 43 42 } 44 43 44 + #ifdef CONFIG_ACPI 45 45 static void vmgenid_acpi_handler(acpi_handle __always_unused handle, 46 46 u32 __always_unused event, void *dev) 47 47 { ··· 94 92 ACPI_FREE(parsed.pointer); 95 93 return ret; 96 94 } 95 + #else 96 + static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state) 97 + { 98 + return -EINVAL; 99 + } 100 + #endif 101 + 102 + static irqreturn_t vmgenid_of_irq_handler(int __always_unused irq, void *dev) 103 + { 104 + vmgenid_notify(dev); 105 + return IRQ_HANDLED; 106 + } 107 + 108 + static int vmgenid_add_of(struct platform_device *pdev, 109 + struct vmgenid_state *state) 110 + { 111 + void *virt_addr; 112 + int ret; 113 + 114 + virt_addr = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 115 + if (IS_ERR(virt_addr)) 116 + return PTR_ERR(virt_addr); 117 + 118 + setup_vmgenid_state(state, virt_addr); 119 + 120 + ret = platform_get_irq(pdev, 0); 121 + if (ret < 0) 122 + return ret; 123 + 124 + ret = devm_request_irq(&pdev->dev, ret, vmgenid_of_irq_handler, 125 + IRQF_SHARED, "vmgenid", &pdev->dev); 126 + if (ret < 0) 127 + return ret; 128 + 129 + pdev->dev.driver_data = state; 130 + return 0; 131 + } 97 132 98 133 static int vmgenid_add(struct platform_device *pdev) 99 134 { ··· 142 103 if (!state) 143 104 return -ENOMEM; 144 105 145 - ret = vmgenid_add_acpi(dev, state); 106 + if (dev->of_node) 107 + ret = vmgenid_add_of(pdev, state); 108 + else 109 + ret = vmgenid_add_acpi(dev, state); 146 110 147 111 if (ret < 0) 148 112 devm_kfree(dev, state); 149 113 return ret; 150 114 } 115 + 116 + static const struct of_device_id vmgenid_of_ids[] = { 117 + { .compatible = "microsoft,vmgenid", }, 118 + { }, 119 + }; 120 + MODULE_DEVICE_TABLE(of, vmgenid_of_ids); 151 121 152 122 static const struct acpi_device_id vmgenid_acpi_ids[] = { 153 123 { "VMGENCTR", 0 }, ··· 170 122 .driver = { 171 123 .name = "vmgenid", 172 124 .acpi_match_table = vmgenid_acpi_ids, 125 + .of_match_table = vmgenid_of_ids, 173 126 }, 174 127 }; 175 128