On 06.02.20 10:54, David Hildenbrand wrote: >> #define CPUSTAT_STOPPED 0x80000000 >> #define CPUSTAT_WAIT 0x10000000 >> #define CPUSTAT_ECALL_PEND 0x08000000 >> @@ -315,7 +321,10 @@ struct kvm_s390_sie_block { >> #define CRYCB_FORMAT2 0x00000003 >> __u32 crycbd; /* 0x00fc */ >> __u64 gcr[16]; /* 0x0100 */ >> - __u64 gbea; /* 0x0180 */ >> + union { >> + __u64 gbea; /* 0x0180 */ >> + __u64 sidad; >> + }; >> __u8 reserved188[8]; /* 0x0188 */ >> __u64 sdnxo; /* 0x0190 */ >> __u8 reserved198[8]; /* 0x0198 */ >> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c >> index 6f90d16cad92..56488f9ed190 100644 >> --- a/arch/s390/kvm/kvm-s390.c >> +++ b/arch/s390/kvm/kvm-s390.c >> @@ -4435,6 +4435,41 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, >> return r; >> } >> >> +static long kvm_s390_guest_sida_op(struct kvm_vcpu *vcpu, >> + struct kvm_s390_mem_op *mop) >> +{ >> + void __user *uaddr = (void __user *)mop->buf; >> + int r = 0; >> + >> + if (mop->flags || !mop->size) >> + return -EINVAL; >> + >> + if (mop->size > sida_size(vcpu->arch.sie_block)) >> + return -E2BIG; >> + >> + if (mop->sida_offset > sida_size(vcpu->arch.sie_block)) >> + return -E2BIG; >> + >> + if (mop->size + mop->sida_offset > sida_size(vcpu->arch.sie_block)) >> + return -E2BIG; >> + > > if (mop->size + mop->sida_offset > mop->size) > return -EINVAL; > if (mop->size + mop->sida_offset > sida_size(vcpu->arch.sie_block)) > return -E2BIG; > > Should be sufficient (instead of 3 checks). Will have a look. [..] >> >> switch (mop->op) { >> case KVM_S390_MEMOP_LOGICAL_READ: >> + if (kvm_s390_pv_is_protected(vcpu->kvm)) { >> + r = -EINVAL; >> + break; >> + } > > Race with PV_VM_DESTROY (freeing sidad) As I said in my other mail, the sida is freed in PV_CPU_DESTROY and this ioctl is locked against MEMOP.