On 11/4/19 9:18 AM, Christian Borntraeger wrote: > > > On 24.10.19 13:40, Janosch Frank wrote: >> Let's add a KVM interface to create and destroy protected VMs. >> >> Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx> >> --- >> arch/s390/include/asm/kvm_host.h | 24 +++- >> arch/s390/include/asm/uv.h | 110 ++++++++++++++ >> arch/s390/kvm/Makefile | 2 +- >> arch/s390/kvm/kvm-s390.c | 173 +++++++++++++++++++++- >> arch/s390/kvm/kvm-s390.h | 47 ++++++ >> arch/s390/kvm/pv.c | 237 +++++++++++++++++++++++++++++++ >> include/uapi/linux/kvm.h | 33 +++++ >> 7 files changed, 622 insertions(+), 4 deletions(-) >> create mode 100644 arch/s390/kvm/pv.c > [...] > >> + case KVM_PV_VM_UNPACK: { >> + struct kvm_s390_pv_unp unp = {}; >> + >> + r = -EFAULT; >> + if (copy_from_user(&unp, argp, sizeof(unp))) >> + break; >> + >> + r = kvm_s390_pv_unpack(kvm, unp.addr, unp.size, unp.tweak); >> + break; >> + } > > > > [....] > >> +int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size, >> + unsigned long tweak) >> +{ >> + int i, rc = 0; >> + struct uv_cb_unp uvcb = { >> + .header.cmd = UVC_CMD_UNPACK_IMG, >> + .header.len = sizeof(uvcb), >> + .guest_handle = kvm_s390_pv_handle(kvm), >> + .tweak[0] = tweak >> + }; >> + >> + if (addr & ~PAGE_MASK || size & ~PAGE_MASK) >> + return -EINVAL; >> + >> + >> + VM_EVENT(kvm, 3, "PROTVIRT VM UNPACK: start addr %lx size %lx", >> + addr, size); > > Does it make sense to check for addr and addr+size to be within the memory > size of the guest? The uv_call or gmap_fault will fail later on, but we > could do an early exit if the the site is wrong. Yeah, Marc already brought that up because of a testcase of his. I'll add a check, but before that I need to understand what makes us loop so long that we get RCU warnings. > > > > >> + for (i = 0; i < size / PAGE_SIZE; i++) { >> + uvcb.gaddr = addr + i * PAGE_SIZE; >> + uvcb.tweak[1] = i * PAGE_SIZE; > > >> +retry: > >> + rc = uv_call(0, (u64)&uvcb); >> + if (!rc) >> + continue; >> + /* If not yet mapped fault and retry */ >> + if (uvcb.header.rc == 0x10a) { >> + rc = gmap_fault(kvm->arch.gmap, uvcb.gaddr, >> + FAULT_FLAG_WRITE); >> + if (rc) >> + return rc; >> + goto retry; >> + } >> + VM_EVENT(kvm, 3, "PROTVIRT VM UNPACK: failed addr %llx rc %x rrc %x", >> + uvcb.gaddr, uvcb.header.rc, uvcb.header.rrc); >> + break; >> + } > [...] >
Attachment:
signature.asc
Description: OpenPGP digital signature