Message ID | 20250117190938.93793-4-imbrenda@linux.ibm.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | KVM: s390: Stop using page->index and other things | expand |
On 17.01.25 20:09, Claudio Imbrenda wrote: > Create a fake memslot for ucontrol VMs. The fake memslot identity-maps > userspace. > > Now memslots will always be present, and ucontrol is not a special case > anymore. > > Suggested-by: Sean Christopherson <seanjc@google.com> > Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> > --- Reviewed-by: David Hildenbrand <david@redhat.com>
On Fri Jan 17, 2025 at 8:09 PM CET, Claudio Imbrenda wrote: > Create a fake memslot for ucontrol VMs. The fake memslot identity-maps > userspace. > > Now memslots will always be present, and ucontrol is not a special case > anymore. > > Suggested-by: Sean Christopherson <seanjc@google.com> > Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> LGTM assuming the triggered warning about the slot_lock can be resolved in another patch. Tested in G1 and G2 using the ucontrol selftests. Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com> Tested-by: Christoph Schlameuss <schlameuss@linux.ibm.com> > --- > Documentation/virt/kvm/api.rst | 2 +- > arch/s390/include/asm/kvm_host.h | 2 ++ > arch/s390/kvm/kvm-s390.c | 15 ++++++++++++++- > arch/s390/kvm/kvm-s390.h | 2 ++ > 4 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index f15b61317aad..cc98115a96d7 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -1419,7 +1419,7 @@ fetch) is injected in the guest. > S390: > ^^^^^ > > -Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set. > +Returns -EINVAL or -EEXIST if the VM has the KVM_VM_S390_UCONTROL flag set. > Returns -EINVAL if called on a protected VM. > > 4.36 KVM_SET_TSS_ADDR > diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h > index 97c7c8127543..9df37361bc64 100644 > --- a/arch/s390/include/asm/kvm_host.h > +++ b/arch/s390/include/asm/kvm_host.h > @@ -30,6 +30,8 @@ > #define KVM_S390_ESCA_CPU_SLOTS 248 > #define KVM_MAX_VCPUS 255 > > +#define KVM_INTERNAL_MEM_SLOTS 1 > + > /* > * These seem to be used for allocating ->chip in the routing table, which we > * don't use. 1 is as small as we can get to reduce the needed memory. If we > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c > index ecbdd7d41230..58cc7f7444e5 100644 > --- a/arch/s390/kvm/kvm-s390.c > +++ b/arch/s390/kvm/kvm-s390.c > @@ -3428,8 +3428,18 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) > VM_EVENT(kvm, 3, "vm created with type %lu", type); > > if (type & KVM_VM_S390_UCONTROL) { > + struct kvm_userspace_memory_region2 fake_memslot = { > + .slot = KVM_S390_UCONTROL_MEMSLOT, > + .guest_phys_addr = 0, > + .userspace_addr = 0, > + .memory_size = ALIGN_DOWN(TASK_SIZE, _SEGMENT_SIZE), > + .flags = 0, > + }; > + > kvm->arch.gmap = NULL; > kvm->arch.mem_limit = KVM_S390_NO_MEM_LIMIT; > + /* one flat fake memslot covering the whole address-space */ > + KVM_BUG_ON(kvm_set_internal_memslot(kvm, &fake_memslot), kvm); In the current state of kvm_set_internal_memslot this does not acquire the slot_lock and issues a warning. I did bring this up on Seans patch introducing the method. So I assume at this point this here is fine. > } else { > if (sclp.hamax == U64_MAX) > kvm->arch.mem_limit = TASK_SIZE_MAX; > @@ -5854,7 +5864,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, > { > gpa_t size; > > - if (kvm_is_ucontrol(kvm)) > + if (kvm_is_ucontrol(kvm) && new->id < KVM_USER_MEM_SLOTS) > return -EINVAL; > > /* When we are protected, we should not change the memory slots */ > @@ -5906,6 +5916,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, > { > int rc = 0; > > + if (kvm_is_ucontrol(kvm)) > + return; > + > switch (change) { > case KVM_MR_DELETE: > rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE, > diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h > index 597d7a71deeb..30736ac16f84 100644 > --- a/arch/s390/kvm/kvm-s390.h > +++ b/arch/s390/kvm/kvm-s390.h > @@ -20,6 +20,8 @@ > #include <asm/processor.h> > #include <asm/sclp.h> > > +#define KVM_S390_UCONTROL_MEMSLOT (KVM_USER_MEM_SLOTS + 0) > + > static inline void kvm_s390_fpu_store(struct kvm_run *run) > { > fpu_stfpc(&run->s.regs.fpc);
On 1/17/25 8:09 PM, Claudio Imbrenda wrote: > Create a fake memslot for ucontrol VMs. The fake memslot identity-maps > userspace. > > Now memslots will always be present, and ucontrol is not a special case > anymore. Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
On Mon, 20 Jan 2025 16:27:53 +0100 "Christoph Schlameuss" <schlameuss@linux.ibm.com> wrote: > On Fri Jan 17, 2025 at 8:09 PM CET, Claudio Imbrenda wrote: > > Create a fake memslot for ucontrol VMs. The fake memslot identity-maps > > userspace. > > > > Now memslots will always be present, and ucontrol is not a special case > > anymore. > > > > Suggested-by: Sean Christopherson <seanjc@google.com> > > Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> > > LGTM assuming the triggered warning about the slot_lock can be resolved in > another patch. > Tested in G1 and G2 using the ucontrol selftests. > > Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com> > Tested-by: Christoph Schlameuss <schlameuss@linux.ibm.com> > > > --- > > Documentation/virt/kvm/api.rst | 2 +- > > arch/s390/include/asm/kvm_host.h | 2 ++ > > arch/s390/kvm/kvm-s390.c | 15 ++++++++++++++- > > arch/s390/kvm/kvm-s390.h | 2 ++ > > 4 files changed, 19 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > > index f15b61317aad..cc98115a96d7 100644 > > --- a/Documentation/virt/kvm/api.rst > > +++ b/Documentation/virt/kvm/api.rst > > @@ -1419,7 +1419,7 @@ fetch) is injected in the guest. > > S390: > > ^^^^^ > > > > -Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set. > > +Returns -EINVAL or -EEXIST if the VM has the KVM_VM_S390_UCONTROL flag set. > > Returns -EINVAL if called on a protected VM. > > > > 4.36 KVM_SET_TSS_ADDR > > diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h > > index 97c7c8127543..9df37361bc64 100644 > > --- a/arch/s390/include/asm/kvm_host.h > > +++ b/arch/s390/include/asm/kvm_host.h > > @@ -30,6 +30,8 @@ > > #define KVM_S390_ESCA_CPU_SLOTS 248 > > #define KVM_MAX_VCPUS 255 > > > > +#define KVM_INTERNAL_MEM_SLOTS 1 > > + > > /* > > * These seem to be used for allocating ->chip in the routing table, which we > > * don't use. 1 is as small as we can get to reduce the needed memory. If we > > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c > > index ecbdd7d41230..58cc7f7444e5 100644 > > --- a/arch/s390/kvm/kvm-s390.c > > +++ b/arch/s390/kvm/kvm-s390.c > > @@ -3428,8 +3428,18 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) > > VM_EVENT(kvm, 3, "vm created with type %lu", type); > > > > if (type & KVM_VM_S390_UCONTROL) { > > + struct kvm_userspace_memory_region2 fake_memslot = { > > + .slot = KVM_S390_UCONTROL_MEMSLOT, > > + .guest_phys_addr = 0, > > + .userspace_addr = 0, > > + .memory_size = ALIGN_DOWN(TASK_SIZE, _SEGMENT_SIZE), > > + .flags = 0, > > + }; > > + > > kvm->arch.gmap = NULL; > > kvm->arch.mem_limit = KVM_S390_NO_MEM_LIMIT; > > + /* one flat fake memslot covering the whole address-space */ > > + KVM_BUG_ON(kvm_set_internal_memslot(kvm, &fake_memslot), kvm); > > In the current state of kvm_set_internal_memslot this does not acquire the > slot_lock and issues a warning. I did bring this up on Seans patch introducing Oops, I have missed that > the method. So I assume at this point this here is fine. not really; I will add proper locking around the call > > > } else { > > if (sclp.hamax == U64_MAX) > > kvm->arch.mem_limit = TASK_SIZE_MAX; > > @@ -5854,7 +5864,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, > > { > > gpa_t size; > > > > - if (kvm_is_ucontrol(kvm)) > > + if (kvm_is_ucontrol(kvm) && new->id < KVM_USER_MEM_SLOTS) > > return -EINVAL; > > > > /* When we are protected, we should not change the memory slots */ > > @@ -5906,6 +5916,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, > > { > > int rc = 0; > > > > + if (kvm_is_ucontrol(kvm)) > > + return; > > + > > switch (change) { > > case KVM_MR_DELETE: > > rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE, > > diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h > > index 597d7a71deeb..30736ac16f84 100644 > > --- a/arch/s390/kvm/kvm-s390.h > > +++ b/arch/s390/kvm/kvm-s390.h > > @@ -20,6 +20,8 @@ > > #include <asm/processor.h> > > #include <asm/sclp.h> > > > > +#define KVM_S390_UCONTROL_MEMSLOT (KVM_USER_MEM_SLOTS + 0) > > + > > static inline void kvm_s390_fpu_store(struct kvm_run *run) > > { > > fpu_stfpc(&run->s.regs.fpc); >
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index f15b61317aad..cc98115a96d7 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1419,7 +1419,7 @@ fetch) is injected in the guest. S390: ^^^^^ -Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set. +Returns -EINVAL or -EEXIST if the VM has the KVM_VM_S390_UCONTROL flag set. Returns -EINVAL if called on a protected VM. 4.36 KVM_SET_TSS_ADDR diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 97c7c8127543..9df37361bc64 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -30,6 +30,8 @@ #define KVM_S390_ESCA_CPU_SLOTS 248 #define KVM_MAX_VCPUS 255 +#define KVM_INTERNAL_MEM_SLOTS 1 + /* * These seem to be used for allocating ->chip in the routing table, which we * don't use. 1 is as small as we can get to reduce the needed memory. If we diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ecbdd7d41230..58cc7f7444e5 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -3428,8 +3428,18 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) VM_EVENT(kvm, 3, "vm created with type %lu", type); if (type & KVM_VM_S390_UCONTROL) { + struct kvm_userspace_memory_region2 fake_memslot = { + .slot = KVM_S390_UCONTROL_MEMSLOT, + .guest_phys_addr = 0, + .userspace_addr = 0, + .memory_size = ALIGN_DOWN(TASK_SIZE, _SEGMENT_SIZE), + .flags = 0, + }; + kvm->arch.gmap = NULL; kvm->arch.mem_limit = KVM_S390_NO_MEM_LIMIT; + /* one flat fake memslot covering the whole address-space */ + KVM_BUG_ON(kvm_set_internal_memslot(kvm, &fake_memslot), kvm); } else { if (sclp.hamax == U64_MAX) kvm->arch.mem_limit = TASK_SIZE_MAX; @@ -5854,7 +5864,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, { gpa_t size; - if (kvm_is_ucontrol(kvm)) + if (kvm_is_ucontrol(kvm) && new->id < KVM_USER_MEM_SLOTS) return -EINVAL; /* When we are protected, we should not change the memory slots */ @@ -5906,6 +5916,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, { int rc = 0; + if (kvm_is_ucontrol(kvm)) + return; + switch (change) { case KVM_MR_DELETE: rc = gmap_unmap_segment(kvm->arch.gmap, old->base_gfn * PAGE_SIZE, diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 597d7a71deeb..30736ac16f84 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -20,6 +20,8 @@ #include <asm/processor.h> #include <asm/sclp.h> +#define KVM_S390_UCONTROL_MEMSLOT (KVM_USER_MEM_SLOTS + 0) + static inline void kvm_s390_fpu_store(struct kvm_run *run) { fpu_stfpc(&run->s.regs.fpc);
Create a fake memslot for ucontrol VMs. The fake memslot identity-maps userspace. Now memslots will always be present, and ucontrol is not a special case anymore. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> --- Documentation/virt/kvm/api.rst | 2 +- arch/s390/include/asm/kvm_host.h | 2 ++ arch/s390/kvm/kvm-s390.c | 15 ++++++++++++++- arch/s390/kvm/kvm-s390.h | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-)