mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
Revert "ANDROID: KVM: arm64: s2mpu: Replace SMC handler with PM callbacks"
This reverts commit e3f32a19c3.
Bug: 233587962
Signed-off-by: Will Deacon <willdeacon@google.com>
Change-Id: I463c075c307db6cec46c3b72ccd4cb5fc2551ef5
This commit is contained in:
@@ -56,6 +56,11 @@ static bool is_powered_on(struct pkvm_iommu *dev)
|
||||
return dev->powered;
|
||||
}
|
||||
|
||||
static bool is_in_power_domain(struct pkvm_iommu *dev, u64 power_domain_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static u32 __context_cfg_valid_vid(struct pkvm_iommu *dev, u32 vid_bmap)
|
||||
{
|
||||
struct s2mpu_drv_data *data = (struct s2mpu_drv_data *)dev->data;
|
||||
@@ -346,27 +351,60 @@ static void s2mpu_host_stage2_set_owner(phys_addr_t addr, size_t size,
|
||||
hyp_spin_unlock(&s2mpu_lock);
|
||||
}
|
||||
|
||||
static int s2mpu_resume(struct pkvm_iommu *dev)
|
||||
static bool s2mpu_host_smc_handler(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
/*
|
||||
* Initialize the S2MPU with the host stage-2 MPT. It is paramount
|
||||
* that the S2MPU reset state is enabled and blocking all traffic,
|
||||
* otherwise the host would not be forced to call the resume HVC
|
||||
* before issuing DMA traffic.
|
||||
*/
|
||||
return initialize_with_mpt(dev, &host_mpt);
|
||||
}
|
||||
DECLARE_REG(u64, fn, host_ctxt, 0);
|
||||
DECLARE_REG(u64, mode, host_ctxt, 1);
|
||||
DECLARE_REG(u64, domain_id, host_ctxt, 2);
|
||||
DECLARE_REG(u64, group, host_ctxt, 3);
|
||||
|
||||
struct arm_smccc_res res;
|
||||
struct pkvm_iommu *dev;
|
||||
int ret;
|
||||
|
||||
if (fn != SMC_CMD_PREPARE_PD_ONOFF)
|
||||
return false; /* SMC not handled */
|
||||
|
||||
static int s2mpu_suspend(struct pkvm_iommu *dev)
|
||||
{
|
||||
/*
|
||||
* Stop updating the S2MPU when the host informs us about the intention
|
||||
* to suspend it. Writes to powered-down MMIO registers would trigger
|
||||
* SErrors in EL1 otherwise. However, hyp must put S2MPU back to
|
||||
* blocking state first, in case the host does not actually power it
|
||||
* down and continues issuing DMA traffic.
|
||||
* Host is notifying EL3 that a power domain was turned on/off.
|
||||
* Use this SMC as a trigger to program the S2MPUs.
|
||||
* Note that the host may be malicious and issue this SMC arbitrarily.
|
||||
*
|
||||
* Power on:
|
||||
* It is paramount that the S2MPU reset state is enabled and blocking
|
||||
* all traffic. That way the host is forced to issue a power-on SMC to
|
||||
* unblock the S2MPUs.
|
||||
*
|
||||
* Power down:
|
||||
* A power-down SMC is a hint for hyp to stop updating the S2MPU, lest
|
||||
* writes to powered-down MMIO registers produce SErrors in the host.
|
||||
* However, hyp must perform one last update - putting the S2MPUs back
|
||||
* to their blocking reset state - in case the host does not actually
|
||||
* power them down and continues issuing DMA traffic.
|
||||
*/
|
||||
return initialize_with_prot(dev, MPT_PROT_NONE);
|
||||
|
||||
hyp_spin_lock(&s2mpu_lock);
|
||||
arm_smccc_1_1_smc(fn, mode, domain_id, group, &res);
|
||||
ret = res.a0;
|
||||
|
||||
if (ret == SMCCC_RET_SUCCESS) {
|
||||
for_each_s2mpu(dev) {
|
||||
if (!is_in_power_domain(dev, domain_id))
|
||||
continue;
|
||||
|
||||
if (mode == SMC_MODE_POWER_UP) {
|
||||
dev->powered = true;
|
||||
ret = initialize_with_mpt(dev, &host_mpt);
|
||||
} else {
|
||||
ret = initialize_with_prot(dev, MPT_PROT_NONE);
|
||||
dev->powered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
hyp_spin_unlock(&s2mpu_lock);
|
||||
|
||||
cpu_reg(host_ctxt, 0) = ret;
|
||||
return true; /* SMC handled */
|
||||
}
|
||||
|
||||
static struct pkvm_iommu *find_s2mpu_by_addr(phys_addr_t addr)
|
||||
@@ -496,12 +534,11 @@ static int s2mpu_validate(phys_addr_t pa, size_t size)
|
||||
const struct pkvm_iommu_ops pkvm_s2mpu_ops = (struct pkvm_iommu_ops){
|
||||
.init = s2mpu_init,
|
||||
.validate = s2mpu_validate,
|
||||
.resume = s2mpu_resume,
|
||||
.suspend = s2mpu_suspend,
|
||||
.data_size = sizeof(struct s2mpu_drv_data),
|
||||
};
|
||||
|
||||
const struct kvm_iommu_ops kvm_s2mpu_ops = (struct kvm_iommu_ops){
|
||||
.host_smc_handler = s2mpu_host_smc_handler,
|
||||
.host_mmio_dabt_handler = s2mpu_host_mmio_dabt_handler,
|
||||
.host_stage2_set_owner = s2mpu_host_stage2_set_owner,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user