[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 07/15] KVM: Special handling for fd-based memory invalidation
From: |
Chao Peng |
Subject: |
[PATCH v3 07/15] KVM: Special handling for fd-based memory invalidation |
Date: |
Tue, 21 Dec 2021 23:11:17 +0800 |
For fd-based guest memory, the memory backend (e.g. the fd provider)
should notify KVM to unmap/invalidate the privated memory from KVM
second MMU when userspace punches hole on the fd (e.g. when userspace
converts private memory to shared memory).
To support fd-based memory invalidation, existing hva-based memory
invalidation needs to be extended. A new 'inode' for the fd is passed in
from memfd_falloc_notifier and the 'start/end' will represent start/end
offset in the fd instead of hva range. During the invalidation KVM needs
to check this inode against that in the memslot. Only when the 'inode' in
memslot equals to the passed-in 'inode' we should invalidate the mapping
in KVM.
Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com>
Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
---
virt/kvm/kvm_main.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 856f89ed8ab5..0f2d1002f6a7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -479,6 +479,7 @@ typedef void (*on_lock_fn_t)(struct kvm *kvm, unsigned long
start,
struct kvm_useraddr_range {
unsigned long start;
unsigned long end;
+ struct inode *inode;
pte_t pte;
gfn_handler_t handler;
on_lock_fn_t on_lock;
@@ -519,9 +520,19 @@ static __always_inline int
__kvm_handle_useraddr_range(struct kvm *kvm,
slots = __kvm_memslots(kvm, i);
kvm_for_each_memslot(slot, slots) {
unsigned long useraddr_start, useraddr_end;
+ unsigned long useraddr_base;
- useraddr_start = max(range->start,
slot->userspace_addr);
- useraddr_end = min(range->end, slot->userspace_addr +
+ if (range->inode) {
+ if (!slot->file ||
+ slot->file->f_inode != range->inode)
+ continue;
+ useraddr_base = slot->file_ofs;
+ } else
+ useraddr_base = slot->userspace_addr;
+
+
+ useraddr_start = max(range->start, useraddr_base);
+ useraddr_end = min(range->end, useraddr_base +
(slot->npages << PAGE_SHIFT));
if (useraddr_start >= useraddr_end)
continue;
@@ -540,10 +551,10 @@ static __always_inline int
__kvm_handle_useraddr_range(struct kvm *kvm,
* {gfn_start, gfn_start+1, ..., gfn_end-1}.
*/
gfn_range.start =
useraddr_to_gfn_memslot(useraddr_start,
- slot, true);
+ slot, !range->inode);
gfn_range.end = useraddr_to_gfn_memslot(
useraddr_end + PAGE_SIZE - 1,
- slot, true);
+ slot, !range->inode);
gfn_range.slot = slot;
if (!locked) {
@@ -585,6 +596,7 @@ static __always_inline int kvm_handle_hva_range(struct
mmu_notifier *mn,
.on_lock = (void *)kvm_null_fn,
.flush_on_ret = true,
.may_block = false,
+ .inode = NULL,
};
return __kvm_handle_useraddr_range(kvm, &range);
@@ -604,6 +616,7 @@ static __always_inline int
kvm_handle_hva_range_no_flush(struct mmu_notifier *mn
.on_lock = (void *)kvm_null_fn,
.flush_on_ret = false,
.may_block = false,
+ .inode = NULL,
};
return __kvm_handle_useraddr_range(kvm, &range);
@@ -672,6 +685,7 @@ static int kvm_mmu_notifier_invalidate_range_start(struct
mmu_notifier *mn,
.on_lock = kvm_inc_notifier_count,
.flush_on_ret = true,
.may_block = mmu_notifier_range_blockable(range),
+ .inode = NULL,
};
trace_kvm_unmap_hva_range(range->start, range->end);
@@ -723,6 +737,7 @@ static void kvm_mmu_notifier_invalidate_range_end(struct
mmu_notifier *mn,
.on_lock = kvm_dec_notifier_count,
.flush_on_ret = false,
.may_block = mmu_notifier_range_blockable(range),
+ .inode = NULL,
};
bool wake;
--
2.17.1
- [PATCH v3 00/15] KVM: mm: fd-based approach for supporting KVM guest private memory, Chao Peng, 2021/12/21
- [PATCH v3 01/15] mm/shmem: Introduce F_SEAL_INACCESSIBLE, Chao Peng, 2021/12/21
- [PATCH v3 02/15] mm/memfd: Introduce MFD_INACCESSIBLE flag, Chao Peng, 2021/12/21
- [PATCH v3 03/15] mm/memfd: Introduce MEMFD_OPS, Chao Peng, 2021/12/21
- [PATCH v3 04/15] KVM: Extend the memslot to support fd-based private memory, Chao Peng, 2021/12/21
- [PATCH v3 05/15] KVM: Implement fd-based memory using MEMFD_OPS interfaces, Chao Peng, 2021/12/21
- [PATCH v3 06/15] KVM: Refactor hva based memory invalidation code, Chao Peng, 2021/12/21
- [PATCH v3 07/15] KVM: Special handling for fd-based memory invalidation,
Chao Peng <=
- [PATCH v3 08/15] KVM: Split out common memory invalidation code, Chao Peng, 2021/12/21
- [PATCH v3 09/15] KVM: Implement fd-based memory invalidation, Chao Peng, 2021/12/21
- [PATCH v3 12/15] KVM: Add KVM_EXIT_MEMORY_ERROR exit, Chao Peng, 2021/12/21
- [PATCH v3 13/15] KVM: Handle page fault for private memory, Chao Peng, 2021/12/21
- [PATCH v3 14/15] KVM: Use kvm_userspace_memory_region_ext, Chao Peng, 2021/12/21
- [PATCH v3 10/15] KVM: Add kvm_map_gfn_range, Chao Peng, 2021/12/21
- [PATCH v3 15/15] KVM: Register/unregister private memory slot to memfd, Chao Peng, 2021/12/21
- [PATCH v3 11/15] KVM: Implement fd-based memory fallocation, Chao Peng, 2021/12/21
- Re: [PATCH v3 00/15] KVM: mm: fd-based approach for supporting KVM guest private memory, Sean Christopherson, 2021/12/21