On 2/17/20 12:08 PM, David Hildenbrand wrote: >> @@ -4460,6 +4489,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; >> + } > > Could we have a possible race with disabling code, especially while > concurrently freeing? (sorry if I ask again, there was just a flood of > emails) > >> if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { >> r = check_gva_range(vcpu, mop->gaddr, mop->ar, >> mop->size, GACC_FETCH); >> @@ -4472,6 +4505,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; >> + } > > dito > >> if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { >> r = check_gva_range(vcpu, mop->gaddr, mop->ar, >> mop->size, GACC_STORE); >> @@ -4483,6 +4520,11 @@ 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: >> + /* we are locked against sida going away by the vcpu->mutex */ >> + r = kvm_s390_guest_sida_op(vcpu, mop); >> + break; >> default: >> r = -EINVAL; >> } >> diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c >> index 09573e36c329..80169a9b43ec 100644 >> --- a/arch/s390/kvm/pv.c >> +++ b/arch/s390/kvm/pv.c >> @@ -92,6 +92,7 @@ int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) >> >> free_pages(vcpu->arch.pv.stor_base, >> get_order(uv_info.guest_cpu_stor_len)); >> + free_page(sida_origin(vcpu->arch.sie_block)); >> vcpu->arch.sie_block->pv_handle_cpu = 0; >> vcpu->arch.sie_block->pv_handle_config = 0; >> memset(&vcpu->arch.pv, 0, sizeof(vcpu->arch.pv)); >> @@ -121,6 +122,14 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) >> uvcb.state_origin = (u64)vcpu->arch.sie_block; >> uvcb.stor_origin = (u64)vcpu->arch.pv.stor_base; >> >> + /* Alloc Secure Instruction Data Area Designation */ >> + vcpu->arch.sie_block->sidad = __get_free_page(GFP_KERNEL | __GFP_ZERO); >> + if (!vcpu->arch.sie_block->sidad) { >> + free_pages(vcpu->arch.pv.stor_base, >> + get_order(uv_info.guest_cpu_stor_len)); >> + return -ENOMEM; >> + } >> + >> cc = uv_call(0, (u64)&uvcb); >> *rc = uvcb.header.rc; >> *rrc = uvcb.header.rrc; >> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h >> index 207915488502..0fdee1bc3798 100644 >> --- a/include/uapi/linux/kvm.h >> +++ b/include/uapi/linux/kvm.h >> @@ -475,11 +475,15 @@ struct kvm_s390_mem_op { >> __u32 op; /* type of operation */ >> __u64 buf; /* buffer in userspace */ >> __u8 ar; /* the access register number */ >> - __u8 reserved[31]; /* should be set to 0 */ >> + __u8 reserved21[3]; /* should be set to 0 */ >> + __u32 sida_offset; /* offset into the sida */ >> + __u8 reserved28[24]; /* should be set to 0 */ >> }; > > As discussed, I'd prefer an overlaying layout for the sida, as the ar > does not make any sense (correct me if I'm wrong :) ) That wouldn't work, because we still check mop->ar < 16 in kvm_s390_guest_mem_op(). Also we currently check mop contents twice because we overload mem_op() with the SIDA operations. Using a separate IOCTL is cleaner... > > __u32 op; /* type of operation */ > __u64 buf; /* buffer in userspace */ > uinon { > __u8 ar; /* the access register number */ > __u32 sida_offset; /* offset into the sida */ > __u8 reserved[32]; /* should be set to 0 */ > }; > > With something like that > > Reviewed-by: David Hildenbrand <david@xxxxxxxxxx>
Attachment:
signature.asc
Description: OpenPGP digital signature