s390x: fix storage attributes migration for non-small guests

Fix storage attribute migration so that it does not fail for guests
with more than a few GB of RAM.
With such guests, the index in the buffer would go out of bounds,
usually by large amounts, thus receiving -EFAULT from the kernel.
Migration itself would be successful, but storage attributes would then
not be migrated completely.

This patch fixes the out of bounds access, and thus migration of all
storage attributes when the guest have large amounts of memory.

Cc: qemu-stable@nongnu.org
Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Fixes: 903fd80b03 ("s390x/migration: Storage attributes device")
Message-Id: <1516297904-18188-1-git-send-email-imbrenda@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
Claudio Imbrenda 2018-01-18 18:51:44 +01:00 committed by Cornelia Huck
parent 74a69e03c1
commit 46fa893355

View File

@ -116,7 +116,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
for (cx = 0; cx + len <= max; cx += len) { for (cx = 0; cx + len <= max; cx += len) {
clog.start_gfn = cx; clog.start_gfn = cx;
clog.count = len; clog.count = len;
clog.values = (uint64_t)(sas->incoming_buffer + cx * len); clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) { if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
@ -126,7 +126,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
if (cx < max) { if (cx < max) {
clog.start_gfn = cx; clog.start_gfn = cx;
clog.count = max - cx; clog.count = max - cx;
clog.values = (uint64_t)(sas->incoming_buffer + cx * len); clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) { if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));