Re: [PATCH v10 2/9] KVM: Introduce per-page memory attributes
From: Chao Peng <hidden>
Date: 2022-12-19 08:20:06
Also in:
kvm, linux-arch, linux-doc, linux-fsdevel, linux-mm, lkml, qemu-devel
On Fri, Dec 16, 2022 at 04:09:06PM +0100, Borislav Petkov wrote:
On Fri, Dec 02, 2022 at 02:13:40PM +0800, Chao Peng wrote:quoted
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 1782c4555d94..7f0f5e9f2406 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c@@ -1150,6 +1150,9 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) spin_lock_init(&kvm->mn_invalidate_lock); rcuwait_init(&kvm->mn_memslots_update_rcuwait); xa_init(&kvm->vcpu_array); +#ifdef CONFIG_HAVE_KVM_MEMORY_ATTRIBUTES + xa_init(&kvm->mem_attr_array); +#endifif (IS_ENABLED(CONFIG_HAVE_KVM_MEMORY_ATTRIBUTES)) ... would at least remove the ugly ifdeffery. Or you could create wrapper functions for that xa_init() and xa_destroy() and put the ifdeffery in there.
Agreed.
quoted
@@ -2323,6 +2329,49 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *kvm, } #endif /* CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT */ +#ifdef CONFIG_HAVE_KVM_MEMORY_ATTRIBUTES +static u64 kvm_supported_mem_attributes(struct kvm *kvm)I guess that function should have a verb in the name: kvm_get_supported_mem_attributes()
Right!
quoted
+static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm, + struct kvm_memory_attributes *attrs) +{ + gfn_t start, end; + unsigned long i; + void *entry; + u64 supported_attrs = kvm_supported_mem_attributes(kvm); + + /* flags is currently not used. */ + if (attrs->flags) + return -EINVAL; + if (attrs->attributes & ~supported_attrs) + return -EINVAL; + if (attrs->size == 0 || attrs->address + attrs->size < attrs->address) + return -EINVAL; + if (!PAGE_ALIGNED(attrs->address) || !PAGE_ALIGNED(attrs->size)) + return -EINVAL;Dunno, shouldn't those issue some sort of an error message so that the caller knows where it failed? Or at least return different retvals which signal what the problem is?
Tamping down with error number a bit:
if (attrs->flags)
return -ENXIO;
if (attrs->attributes & ~supported_attrs)
return -EOPNOTSUPP;
if (!PAGE_ALIGNED(attrs->address) || !PAGE_ALIGNED(attrs->size) ||
attrs->size == 0)
return -EINVAL;
if (attrs->address + attrs->size < attrs->address)
return -E2BIG;
Chaoquoted
+ start = attrs->address >> PAGE_SHIFT; + end = (attrs->address + attrs->size - 1 + PAGE_SIZE) >> PAGE_SHIFT; + + entry = attrs->attributes ? xa_mk_value(attrs->attributes) : NULL; + + mutex_lock(&kvm->lock); + for (i = start; i < end; i++) + if (xa_err(xa_store(&kvm->mem_attr_array, i, entry, + GFP_KERNEL_ACCOUNT))) + break; + mutex_unlock(&kvm->lock); + + attrs->address = i << PAGE_SHIFT; + attrs->size = (end - i) << PAGE_SHIFT; + + return 0; +}-- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette