hw/arm/smmuv3: Post-load stage 1 configurations to the host
In nested mode, we call the set_pasid_table() callback on each STE update to pass the guest stage 1 configuration to the host and apply it at physical level. In the case of live migration, we need to manually call the set_pasid_table() to load the guest stage 1 configurations to the host. If this operation fails, the migration fails. Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com> Signed-off-by: imxcc <xingchaochao@huawei.com> (cherry picked from commit db24e228d7511ab6cb54795db3237bafb275d14e)
This commit is contained in:
parent
24d054989e
commit
e923b443e1
110
hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch
Normal file
110
hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 1b95c995f032c21bf6607dda8ede0f5856bb190a Mon Sep 17 00:00:00 2001
|
||||
From: Kunkun Jiang <jiangkunkun@huawei.com>
|
||||
Date: Tue, 11 May 2021 10:08:16 +0800
|
||||
Subject: [PATCH] hw/arm/smmuv3: Post-load stage 1 configurations to the host
|
||||
|
||||
In nested mode, we call the set_pasid_table() callback on each
|
||||
STE update to pass the guest stage 1 configuration to the host
|
||||
and apply it at physical level.
|
||||
|
||||
In the case of live migration, we need to manually call the
|
||||
set_pasid_table() to load the guest stage 1 configurations to
|
||||
the host. If this operation fails, the migration fails.
|
||||
|
||||
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
|
||||
---
|
||||
hw/arm/smmuv3.c | 33 ++++++++++++++++++++++++++++-----
|
||||
1 file changed, 28 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
|
||||
index 45f21c53fe..291e3a12e8 100644
|
||||
--- a/hw/arm/smmuv3.c
|
||||
+++ b/hw/arm/smmuv3.c
|
||||
@@ -932,7 +932,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
-static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
|
||||
+static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
|
||||
{
|
||||
#ifdef __linux__
|
||||
IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
|
||||
@@ -941,9 +941,10 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
|
||||
IOMMUConfig iommu_config = {};
|
||||
SMMUTransCfg *cfg;
|
||||
SMMUDevice *sdev;
|
||||
+ int ret;
|
||||
|
||||
if (!mr) {
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
sdev = container_of(mr, SMMUDevice, iommu);
|
||||
@@ -952,13 +953,13 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
|
||||
smmuv3_flush_config(sdev);
|
||||
|
||||
if (!pci_device_is_pasid_ops_set(sdev->bus, sdev->devfn)) {
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
cfg = smmuv3_get_config(sdev, &event);
|
||||
|
||||
if (!cfg) {
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
iommu_config.pasid_cfg.argsz = sizeof(struct iommu_pasid_table_config);
|
||||
@@ -980,10 +981,13 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid)
|
||||
iommu_config.pasid_cfg.config,
|
||||
iommu_config.pasid_cfg.base_ptr);
|
||||
|
||||
- if (pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config)) {
|
||||
+ ret = pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config);
|
||||
+ if (ret) {
|
||||
error_report("Failed to pass PASID table to host for iommu mr %s (%m)",
|
||||
mr->parent_obj.name);
|
||||
}
|
||||
+
|
||||
+ return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1553,6 +1557,24 @@ static void smmu_realize(DeviceState *d, Error **errp)
|
||||
smmu_init_irq(s, dev);
|
||||
}
|
||||
|
||||
+static int smmuv3_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+ SMMUv3State *s3 = opaque;
|
||||
+ SMMUState *s = &(s3->smmu_state);
|
||||
+ SMMUDevice *sdev;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
|
||||
+ uint32_t sid = smmu_get_sid(sdev);
|
||||
+ ret = smmuv3_notify_config_change(s, sid);
|
||||
+ if (ret) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static const VMStateDescription vmstate_smmuv3_queue = {
|
||||
.name = "smmuv3_queue",
|
||||
.version_id = 1,
|
||||
@@ -1571,6 +1593,7 @@ static const VMStateDescription vmstate_smmuv3 = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.priority = MIG_PRI_IOMMU,
|
||||
+ .post_load = smmuv3_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(features, SMMUv3State),
|
||||
VMSTATE_UINT8(sid_size, SMMUv3State),
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user