On 06/02/2020 10.07, Christian Borntraeger wrote: > On 05.02.20 18:00, Thomas Huth wrote: > >>>> >>>> Uh, why the mix of a new ioctl with the existing mem_op stuff? Could you >>>> please either properly integrate this into the MEM_OP ioctl (and e.g. >>>> use gaddr as offset for the new SIDA_READ and SIDA_WRITE subcodes), or >>>> completely separate it for a new ioctl, i.e. introduce a new struct for >>>> the new ioctl instead of recycling the struct kvm_s390_mem_op here? >>>> (and in case you ask me, I'd slightly prefer to integrate everything >>>> into MEM_OP instead of introducing a new ioctl here). >>> >>> *cough* David and Christian didn't like the memop solution and it took >>> me a long time to get this to work properly in QEMU... >> >> I also don't like to re-use MEMOP_LOGICAL_READ and MEMOP_LOGICAL_WRITE >> for the SIDA like you've had it in RFC v1 ... but what's wrong with >> using KVM_S390_MEMOP_SIDA_READ and KVM_S390_MEMOP_SIDA_WRITE with the >> MEM_OP ioctl directly? >> >> Thomas >> > > In essence something like the following? > > @@ -4583,6 +4618,9 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, > } > r = write_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); > break; > + case KVM_S390_MEMOP_SIDA_READ: > + case KVM_S390_MEMOP_SIDA_WRITE: > + kvm_s390_guest_sida_op(vcpu, mop); > default: > r = -EINVAL; > } > > > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index ea2b4d66e0c3..6e029753c955 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -1519,7 +1519,6 @@ struct kvm_pv_cmd { > /* Available with KVM_CAP_S390_PROTECTED */ > #define KVM_S390_PV_COMMAND _IOW(KVMIO, 0xc5, struct kvm_pv_cmd) > #define KVM_S390_PV_COMMAND_VCPU _IOW(KVMIO, 0xc6, struct kvm_pv_cmd) > -#define KVM_S390_SIDA_OP _IOW(KVMIO, 0xc7, struct kvm_s390_mem_op) > > /* Secure Encrypted Virtualization command */ > enum sev_cmd_id { Right! But maybe you should also fence the other subcodes in case of PV: diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index d9e6bf3d54f0..f99e7d7af6ea 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4274,6 +4274,10 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, switch (mop->op) { case KVM_S390_MEMOP_LOGICAL_READ: + if (kvm_s390_pv_is_protected(vcpu->kvm)) + r = -EINVAL; + break; + } if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, GACC_FETCH); @@ -4286,6 +4290,10 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, } break; case KVM_S390_MEMOP_LOGICAL_WRITE: + if (kvm_s390_pv_is_protected(vcpu->kvm)) + r = -EINVAL; + break; + } if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, GACC_STORE); ... not sure whether it's maybe easier in the end to move everything to a new ioctl with a new struct instead ... whatever you prefer. But I guess there should be a check like the above in kvm_s390_guest_mem_op() anyway to avoid that userspace can write to protected pages with this MEM_OP ioctl. Thomas