On 17.02.2022 14:45, Chao Peng wrote:
On Tue, Jan 25, 2022 at 09:20:39PM +0100, Maciej S. Szmigiero wrote:
On 18.01.2022 14:21, Chao Peng wrote:
KVM_MEM_PRIVATE is not exposed by default but architecture code can turn
on it by implementing kvm_arch_private_memory_supported().
Also private memslot cannot be movable and the same file+offset can not
be mapped into different GFNs.
Signed-off-by: Yu Zhang <yu.c.zhang@xxxxxxxxxxxxxxx>
Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx>
---
(..)
static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id,
- gfn_t start, gfn_t end)
+ struct file *file,
+ gfn_t start, gfn_t end,
+ loff_t start_off, loff_t end_off)
{
struct kvm_memslot_iter iter;
+ struct kvm_memory_slot *slot;
+ struct inode *inode;
+ int bkt;
kvm_for_each_memslot_in_gfn_range(&iter, slots, start, end) {
if (iter.slot->id != id)
return true;
}
+ /* Disallow mapping the same file+offset into multiple gfns. */
+ if (file) {
+ inode = file_inode(file);
+ kvm_for_each_memslot(slot, bkt, slots) {
+ if (slot->private_file &&
+ file_inode(slot->private_file) == inode &&
+ !(end_off <= slot->private_offset ||
+ start_off >= slot->private_offset
+ + (slot->npages >> PAGE_SHIFT)))
+ return true;
+ }
+ }
That's a linear scan of all memslots on each CREATE (and MOVE) operation
with a fd - we just spent more than a year rewriting similar linear scans
into more efficient operations in KVM.
In the last version I tried to solve this problem by using interval tree
(just like existing hva_tree), but finally we realized that in one VM we
can have multiple fds with overlapped offsets so that approach is
incorrect. See https://lkml.org/lkml/2021/12/28/480 for the discussion.
That's right, in this case a two-level structure would be necessary:
the first level matching a file, then the second level matching that
file ranges.
However, if such data is going to be used just for checking possible
overlap at memslot add or move time it is almost certainly an overkill.
So linear scan is used before I can find a better way.
Another option would be to simply not check for overlap at add or move
time, declare such configuration undefined behavior under KVM API and
make sure in MMU notifiers that nothing bad happens to the host kernel
if it turns out somebody actually set up a VM this way (it could be
inefficient in this case, since it's not supposed to ever happen
unless there is a bug somewhere in the userspace part).
Chao
Thanks,
Maciej