diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index b601ff98e9f2..789753790a28 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -504,10 +504,6 @@ static int __init finalize_pkvm(void) if (pkvm_load_early_modules()) pkvm_firmware_rmem_clear(); - /* If no DMA protection. */ - if (!pkvm_iommu_finalized()) - pkvm_firmware_rmem_clear(); - /* * Exclude HYP sections from kmemleak so that they don't get peeked * at, which would end badly once inaccessible. @@ -516,6 +512,12 @@ static int __init finalize_pkvm(void) kmemleak_free_part(__hyp_data_start, __hyp_data_end - __hyp_data_start); kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size); + flush_deferred_probe_now(); + + /* If no DMA protection. */ + if (!pkvm_iommu_finalized()) + pkvm_firmware_rmem_clear(); + ret = pkvm_drop_host_privileges(); if (ret) { pr_err("Failed to de-privilege the host kernel: %d\n", ret); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c463173f1fb1..1b7378843ceb 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -754,6 +754,29 @@ void wait_for_device_probe(void) } EXPORT_SYMBOL_GPL(wait_for_device_probe); +/** + * flush_deferred_probe_now + * + * This function should be used sparingly. It's meant for when we need to flush + * the deferred probe list at earlier initcall levels. Really meant only for KVM + * needs. This function should never be exported because it makes no sense for + * modules to call this. + */ +void flush_deferred_probe_now(void) +{ + /* + * Really shouldn't using this if deferred probe has already been + * enabled + */ + if (WARN_ON(driver_deferred_probe_enable)) + return; + + driver_deferred_probe_enable = true; + driver_deferred_probe_trigger(); + wait_for_device_probe(); + driver_deferred_probe_enable = false; +} + static int __driver_probe_device(struct device_driver *drv, struct device *dev) { int ret = 0; diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index d2a71e25caab..b2d338904de2 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -134,6 +134,7 @@ extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); extern void wait_for_device_probe(void); +extern void flush_deferred_probe_now(void); void __init wait_for_init_devices_probe(void); /* sysfs interface for exporting driver attributes */