| From c5c2c393468576bad6d10b2b5fefff8cd25df3f4 Mon Sep 17 00:00:00 2001 |
| From: David Hildenbrand <dahi@linux.vnet.ibm.com> |
| Date: Mon, 26 Oct 2015 08:41:29 +0100 |
| Subject: KVM: s390: SCA must not cross page boundaries |
| |
| From: David Hildenbrand <dahi@linux.vnet.ibm.com> |
| |
| commit c5c2c393468576bad6d10b2b5fefff8cd25df3f4 upstream. |
| |
| We seemed to have missed a few corner cases in commit f6c137ff00a4 |
| ("KVM: s390: randomize sca address"). |
| |
| The SCA has a maximum size of 2112 bytes. By setting the sca_offset to |
| some unlucky numbers, we exceed the page. |
| |
| 0x7c0 (1984) -> Fits exactly |
| 0x7d0 (2000) -> 16 bytes out |
| 0x7e0 (2016) -> 32 bytes out |
| 0x7f0 (2032) -> 48 bytes out |
| |
| One VCPU entry is 32 bytes long. |
| |
| For the last two cases, we actually write data to the other page. |
| 1. The address of the VCPU. |
| 2. Injection/delivery/clearing of SIGP externall calls via SIGP IF. |
| |
| Especially the 2. happens regularly. So this could produce two problems: |
| 1. The guest losing/getting external calls. |
| 2. Random memory overwrites in the host. |
| |
| So this problem happens on every 127 + 128 created VM with 64 VCPUs. |
| |
| Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> |
| Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> |
| Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/s390/kvm/kvm-s390.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/arch/s390/kvm/kvm-s390.c |
| +++ b/arch/s390/kvm/kvm-s390.c |
| @@ -1031,7 +1031,9 @@ int kvm_arch_init_vm(struct kvm *kvm, un |
| if (!kvm->arch.sca) |
| goto out_err; |
| spin_lock(&kvm_lock); |
| - sca_offset = (sca_offset + 16) & 0x7f0; |
| + sca_offset += 16; |
| + if (sca_offset + sizeof(struct sca_block) > PAGE_SIZE) |
| + sca_offset = 0; |
| kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset); |
| spin_unlock(&kvm_lock); |
| |