ANDROID: KVM: arm64: iommu: Add arg to finalize to pass state

Add an argument to finalize HVC/function that should be used from EL1
driver.
The argument holds standard error code. Incase of any error, pKVM
will erase pvmfw.

Bug: 268607700
Change-Id: I9f6a6bfc89d3381ab88938586d3b73dd5d94102a
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2023-02-14 13:13:21 +00:00
parent 3e8a2f0f1a
commit 0f00f01625
5 changed files with 22 additions and 7 deletions

View File

@@ -401,8 +401,12 @@ int pkvm_iommu_register(struct device *dev, u64 drv,
int pkvm_iommu_suspend(struct device *dev);
int pkvm_iommu_resume(struct device *dev);
/* Reject future calls to pkvm_iommu_driver_init() and pkvm_iommu_register(). */
int pkvm_iommu_finalize(void);
/*
* Reject future calls to pkvm_iommu_driver_init() and pkvm_iommu_register()
* and report errors if found. Incase of errors pKVM can take proper actions
* as erasing pvmfw.
*/
int pkvm_iommu_finalize(int err);
struct vcpu_reset_state {
unsigned long pc;

View File

@@ -91,7 +91,7 @@ int __pkvm_iommu_register(unsigned long dev_id, unsigned long drv_id,
void *kern_mem_va, size_t mem_size);
int __pkvm_iommu_pm_notify(unsigned long dev_id,
enum pkvm_iommu_pm_event event);
int __pkvm_iommu_finalize(void);
int __pkvm_iommu_finalize(int err);
int pkvm_iommu_host_stage2_adjust_range(phys_addr_t addr, phys_addr_t *start,
phys_addr_t *end);
bool pkvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u32 esr,

View File

@@ -1171,7 +1171,9 @@ static void handle___pkvm_iommu_pm_notify(struct kvm_cpu_context *host_ctxt)
static void handle___pkvm_iommu_finalize(struct kvm_cpu_context *host_ctxt)
{
cpu_reg(host_ctxt, 1) = __pkvm_iommu_finalize();
DECLARE_REG(int, err, host_ctxt, 1);
cpu_reg(host_ctxt, 1) = __pkvm_iommu_finalize(err);
}
static void handle___pkvm_alloc_module_va(struct kvm_cpu_context *host_ctxt)

View File

@@ -14,6 +14,7 @@
#include <hyp/adjust_pc.h>
#include <nvhe/iommu.h>
#include <nvhe/mm.h>
#include <nvhe/pkvm.h>
#define DRV_ID(drv_addr) ((unsigned long)drv_addr)
@@ -450,7 +451,7 @@ out_unlock:
return ret;
}
int __pkvm_iommu_finalize(void)
int __pkvm_iommu_finalize(int err)
{
int ret = 0;
@@ -460,6 +461,14 @@ int __pkvm_iommu_finalize(void)
else
ret = -EPERM;
hyp_spin_unlock(&iommu_registration_lock);
/*
* If finalize failed in EL1 driver for any reason, this means we can't trust the DMA
* isolation. So we have to inform pKVM to properly protect itself.
*/
if (!ret && err)
pkvm_handle_system_misconfiguration(NO_DMA_ISOLATION);
return ret;
}

View File

@@ -58,8 +58,8 @@ int pkvm_iommu_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(pkvm_iommu_resume);
int pkvm_iommu_finalize(void)
int pkvm_iommu_finalize(int err)
{
return kvm_call_hyp_nvhe(__pkvm_iommu_finalize);
return kvm_call_hyp_nvhe(__pkvm_iommu_finalize, err);
}
EXPORT_SYMBOL_GPL(pkvm_iommu_finalize);