ANDROID: Flush deferred probe list before dropping host priv

Some IOMMU devices might be deferred after the driver being
loaded early, so we need to flush the deferred probe list,
this will work if all dependencies already exist.

Bug: 290582379
Change-Id: I5fb3af9b0f7d1b4dbf57078707112dfdb8a3dc23
Signed-off-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Saravana Kannan 2023-09-14 18:10:14 -07:00 committed by Mostafa Saleh
parent 6625133137
commit 9290fc3e8d
3 changed files with 30 additions and 4 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 */