Map KVM memslots and IO buses into KVM ASI. Mapping is checking on each
KVM ASI enter because they can change.

Signed-off-by: Alexandre Chartre <alexandre.char...@oracle.com>
---
 arch/x86/kvm/x86.c       |   36 +++++++++++++++++++++++++++++++++++-
 include/linux/kvm_host.h |    2 ++
 2 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9458413..7c52827 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7748,11 +7748,45 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
 
 static void vcpu_isolation_enter(struct kvm_vcpu *vcpu)
 {
-       int err;
+       struct kvm *kvm = vcpu->kvm;
+       struct kvm_io_bus *bus;
+       int i, err;
 
        if (!vcpu->asi)
                return;
 
+       /*
+        * Check memslots and buses mapping as they tend to change.
+        */
+       for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
+               if (vcpu->asi_memslots[i] == kvm->memslots[i])
+                       continue;
+               pr_debug("remapping kvm memslots[%d]: %px -> %px\n",
+                        i, vcpu->asi_memslots[i], kvm->memslots[i]);
+               err = asi_remap(vcpu->asi, &vcpu->asi_memslots[i],
+                               kvm->memslots[i], sizeof(struct kvm_memslots));
+               if (err) {
+                       pr_debug("failed to map kvm memslots[%d]: error %d\n",
+                                i, err);
+               }
+       }
+
+
+       for (i = 0; i < KVM_NR_BUSES; i++) {
+               bus = kvm->buses[i];
+               if (bus == vcpu->asi_buses[i])
+                       continue;
+               pr_debug("remapped kvm buses[%d]: %px -> %px\n",
+                        i, vcpu->asi_buses[i], bus);
+               err = asi_remap(vcpu->asi, &vcpu->asi_buses[i], bus,
+                               sizeof(*bus) + bus->dev_count *
+                               sizeof(struct kvm_io_range));
+               if (err) {
+                       pr_debug("failed to map kvm buses[%d]: error %d\n",
+                                i, err);
+               }
+       }
+
        err = asi_enter(vcpu->asi);
        if (err)
                pr_debug("KVM isolation failed: error %d\n", err);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2a9d073..1f82de4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -324,6 +324,8 @@ struct kvm_vcpu {
 
 #ifdef CONFIG_ADDRESS_SPACE_ISOLATION
        struct asi *asi;
+       void *asi_memslots[KVM_ADDRESS_SPACE_NUM];
+       void *asi_buses[KVM_NR_BUSES];
 #endif
 };
 
-- 
1.7.1

Reply via email to