blob: 119f6df75d207ec506f372b0dfdb6c4c7ef0ec9e [file] [log] [blame]
From 127a9ab49776e756582d539b383ad5e481cd977e Mon Sep 17 00:00:00 2001
From: Yan Zhao <yan.y.zhao@intel.com>
Date: Fri, 5 Jan 2024 17:13:46 +0800
Subject: [PATCH] BACKPORT: FROMLIST: KVM: Introduce a new memslot flag
KVM_MEM_NON_COHERENT_DMA
Introduce a new flag KVM_MEM_NON_COHERENT_DMA to provide user space a
channel to notify KVM that guest memory specified by the memslot may be
accessed by noncoherent DMA devices.
KVM can start honoring guest memory type for this range of guest memory in
platforms that do not always honoring guest PAT, e.g. in Intel's platform.
Previously, the only way to let KVM be aware of noncoherent DMA devices
is through KVM device for VFIO pass-through devices, in which case, KVM is
notified that all guest memory may be accessed by noncoherent DMA devices.
To avoid complication, flag KVM_MEM_NON_COHERENT_DMA is not allowed to be
dynamically modified for a memslot.
A KVM_CAP_USER_CONFIGURE_NONCOHERENT_DMA is added to let user space know if
this new memslot flag is supported in KVM.
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Tested-by: Yongwei Ma <yongwei.ma@intel.com>
Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
Signed-off-by: Dawn Han <dawnhan@google.com>
(am from https://lore.kernel.org/all/20240105091346.24637-1-yan.y.zhao@intel.com/)
Conflicts:
include/uapi/linux/kvm.h
virt/kvm/kvm_main.c
BUG=b:335525888
UPSTREAM-TASK=b:321924870
TEST=run against ARCVM with change patch
Change-Id: If47b890c45ed20179a578704f3b1fd186769a422
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5479187
Tested-by: Dawn Han <dawnhan@google.com>
Commit-Queue: Dawn Han <dawnhan@google.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
---
include/uapi/linux/kvm.h | 3 +++
virt/kvm/kvm_main.c | 6 +++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9637d8c953abd94d0a1563e2ffcb2afd23ba3b4d..bb4b45752da5384f4584eeea0d296ccb17b739a2 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -51,6 +51,8 @@ struct kvm_userspace_memory_region2 {
#define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0)
#define KVM_MEM_READONLY (1UL << 1)
#define KVM_MEM_GUEST_MEMFD (1UL << 2)
+/* KVM_MEM_GUEST_MEMFD (1UL << 2)*/
+#define KVM_MEM_NON_COHERENT_DMA (1UL << 3)
/* for KVM_IRQ_LINE */
struct kvm_irq_level {
@@ -933,6 +935,7 @@ struct kvm_enable_cap {
#define KVM_CAP_PRE_FAULT_MEMORY 236
#define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
#define KVM_CAP_X86_GUEST_MODE 238
+#define KVM_CAP_USER_CONFIGURE_NONCOHERENT_DMA 239
#define KVM_CAP_GET_CUR_CPUFREQ 512
#define KVM_CAP_UTIL_HINT 513
#define KVM_CAP_GET_CPUFREQ_TBL 514
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d2a5a061c9d9b19c1b42b010de1ffb610141896c..758ece99863c0ef0c65555d9fc68dea790773411 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1739,6 +1739,8 @@ static int check_memory_region_flags(struct kvm *kvm,
valid_flags |= KVM_MEM_READONLY;
#endif
+ valid_flags |= KVM_MEM_NON_COHERENT_DMA;
+
if (mem->flags & ~valid_flags)
return -EINVAL;
@@ -2209,7 +2211,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
return -EINVAL;
if ((mem->userspace_addr != old->userspace_addr) ||
(npages != old->npages) ||
- ((mem->flags ^ old->flags) & KVM_MEM_READONLY))
+ ((mem->flags ^ old->flags) &
+ (KVM_MEM_READONLY | KVM_MEM_NON_COHERENT_DMA)))
return -EINVAL;
if (base_gfn != old->base_gfn)
@@ -5096,6 +5099,7 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
case KVM_CAP_USER_MEMORY2:
case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
+ case KVM_CAP_USER_CONFIGURE_NONCOHERENT_DMA:
case KVM_CAP_INTERNAL_ERROR_DATA:
#ifdef CONFIG_HAVE_KVM_MSI
case KVM_CAP_SIGNAL_MSI:
--
2.46.0.rc2.264.g509ed76dc8-goog