diff options
author | Alexandru Elisei <alexandru.elisei@arm.com> | 2021-10-12 14:25:10 +0100 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2021-10-13 08:36:59 +0100 |
commit | 39181fc6429f4e9e71473284940e35857b42772a (patch) | |
tree | cfb5316ffa5e1411b44f7565a9aad4db67af48df | |
parent | b20d6e3029400b4b4b19c654192951f8bedd39cc (diff) | |
download | kvmtool-39181fc6429f4e9e71473284940e35857b42772a.tar.gz |
vfio/pci: Align MSIX Table and PBA size to guest maximum page size
When allocating MMIO space for the MSI-X table, kvmtool rounds the
allocation to the host's page size to make it as easy as possible for the
guest to map the table to a page, if it wants to (and doesn't do BAR
reassignment, like the x86 architecture for example). However, the host's
page size can differ from the guest's on architectures which support
multiple page sizes. For example, arm64 supports three different page size,
and it is possible for the host to be using 4k pages, while the guest is
using 64k pages.
To make sure the allocation is always aligned to a guest's page size, round
it up to the maximum architectural page size. Do the same for the pending
bit array if it lives in its own BAR.
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Link: https://lore.kernel.org/r/20211012132510.42134-8-alexandru.elisei@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r-- | arm/aarch32/include/kvm/kvm-arch.h | 4 | ||||
-rw-r--r-- | arm/aarch64/include/kvm/kvm-arch.h | 4 | ||||
-rw-r--r-- | mips/include/kvm/kvm-arch.h | 3 | ||||
-rw-r--r-- | powerpc/include/kvm/kvm-arch.h | 3 | ||||
-rw-r--r-- | vfio/pci.c | 6 | ||||
-rw-r--r-- | x86/include/kvm/kvm-arch.h | 3 |
6 files changed, 21 insertions, 2 deletions
diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h index a772bb1d..bee2fc25 100644 --- a/arm/aarch32/include/kvm/kvm-arch.h +++ b/arm/aarch32/include/kvm/kvm-arch.h @@ -1,10 +1,14 @@ #ifndef KVM__KVM_ARCH_H #define KVM__KVM_ARCH_H +#include <linux/sizes.h> + #define kvm__arch_get_kern_offset(...) 0x8000 #define ARM_MAX_MEMORY(...) ARM_LOMAP_MAX_MEMORY +#define MAX_PAGE_SIZE SZ_4K + #include "arm-common/kvm-arch.h" #endif /* KVM__KVM_ARCH_H */ diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h index 159567b9..5e5ee412 100644 --- a/arm/aarch64/include/kvm/kvm-arch.h +++ b/arm/aarch64/include/kvm/kvm-arch.h @@ -1,6 +1,8 @@ #ifndef KVM__KVM_ARCH_H #define KVM__KVM_ARCH_H +#include <linux/sizes.h> + struct kvm; unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd); int kvm__arch_get_ipa_limit(struct kvm *kvm); @@ -21,6 +23,8 @@ int kvm__arch_get_ipa_limit(struct kvm *kvm); max_ram; \ }) +#define MAX_PAGE_SIZE SZ_64K + #include "arm-common/kvm-arch.h" #endif /* KVM__KVM_ARCH_H */ diff --git a/mips/include/kvm/kvm-arch.h b/mips/include/kvm/kvm-arch.h index fdc09d83..e2f048a0 100644 --- a/mips/include/kvm/kvm-arch.h +++ b/mips/include/kvm/kvm-arch.h @@ -1,6 +1,7 @@ #ifndef KVM__KVM_ARCH_H #define KVM__KVM_ARCH_H +#include <linux/sizes.h> /* * Guest memory map is: @@ -36,6 +37,8 @@ #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI +#define MAX_PAGE_SIZE SZ_64K + #include <stdbool.h> #include "linux/types.h" diff --git a/powerpc/include/kvm/kvm-arch.h b/powerpc/include/kvm/kvm-arch.h index 26d440b2..8eeca507 100644 --- a/powerpc/include/kvm/kvm-arch.h +++ b/powerpc/include/kvm/kvm-arch.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include <linux/types.h> +#include <linux/sizes.h> #include <time.h> /* @@ -48,6 +49,8 @@ #define KVM_IOEVENTFD_HAS_PIO 0 +#define MAX_PAGE_SIZE SZ_256K + #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI struct spapr_phb; @@ -1,3 +1,5 @@ +#include "linux/sizes.h" + #include "kvm/irq.h" #include "kvm/kvm.h" #include "kvm/kvm-cpu.h" @@ -926,7 +928,7 @@ static int vfio_pci_create_msix_table(struct kvm *kvm, struct vfio_device *vdev) if (!info.size) return -EINVAL; - map_size = ALIGN(info.size, PAGE_SIZE); + map_size = ALIGN(info.size, MAX_PAGE_SIZE); table->guest_phys_addr = pci_get_mmio_block(map_size); if (!table->guest_phys_addr) { pr_err("cannot allocate MMIO space"); @@ -958,7 +960,7 @@ static int vfio_pci_create_msix_table(struct kvm *kvm, struct vfio_device *vdev) if (!info.size) return -EINVAL; - map_size = ALIGN(info.size, PAGE_SIZE); + map_size = ALIGN(info.size, MAX_PAGE_SIZE); pba->guest_phys_addr = pci_get_mmio_block(map_size); if (!pba->guest_phys_addr) { pr_err("cannot allocate MMIO space"); diff --git a/x86/include/kvm/kvm-arch.h b/x86/include/kvm/kvm-arch.h index 85cd336c..d8a7312d 100644 --- a/x86/include/kvm/kvm-arch.h +++ b/x86/include/kvm/kvm-arch.h @@ -5,6 +5,7 @@ #include <stdbool.h> #include <linux/types.h> +#include <linux/sizes.h> #include <time.h> /* @@ -30,6 +31,8 @@ #define KVM_IOEVENTFD_HAS_PIO 1 +#define MAX_PAGE_SIZE SZ_4K + #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI struct kvm_arch { |