* [GIT PULL 1/3] KVM: s390: SCA must not cross page boundaries
2015-10-29 15:08 [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Christian Borntraeger
@ 2015-10-29 15:08 ` Christian Borntraeger
2015-10-29 15:08 ` [GIT PULL 2/3] KVM: s390: drop useless newline in debugging data Christian Borntraeger
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Christian Borntraeger @ 2015-10-29 15:08 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Alexander Graf, KVM, Cornelia Huck, Jens Freimann, linux-s390,
David Hildenbrand, stable, #, v3.15+, Christian Borntraeger
From: David Hildenbrand <dahi@linux.vnet.ibm.com>
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.
Cc: stable@vger.kernel.org # v3.15+
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>
---
arch/s390/kvm/kvm-s390.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 618c854..3559617 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1098,7 +1098,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
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);
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [GIT PULL 2/3] KVM: s390: drop useless newline in debugging data
2015-10-29 15:08 [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Christian Borntraeger
2015-10-29 15:08 ` [GIT PULL 1/3] KVM: s390: SCA must not cross page boundaries Christian Borntraeger
@ 2015-10-29 15:08 ` Christian Borntraeger
2015-10-29 15:08 ` [GIT PULL 3/3] KVM: s390: use simple switch statement as multiplexer Christian Borntraeger
2015-11-02 9:27 ` [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Paolo Bonzini
3 siblings, 0 replies; 6+ messages in thread
From: Christian Borntraeger @ 2015-10-29 15:08 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Alexander Graf, KVM, Cornelia Huck, Jens Freimann, linux-s390,
Christian Borntraeger
the s390 debug feature does not need newlines. In fact it will
result in empty lines. Get rid of 4 leftovers.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
arch/s390/kvm/kvm-s390.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 3559617..07a6aa8 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -514,7 +514,7 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
if (gtod_high != 0)
return -EINVAL;
- VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x\n", gtod_high);
+ VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x", gtod_high);
return 0;
}
@@ -527,7 +527,7 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
return -EFAULT;
kvm_s390_set_tod_clock(kvm, gtod);
- VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx\n", gtod);
+ VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod);
return 0;
}
@@ -559,7 +559,7 @@ static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
if (copy_to_user((void __user *)attr->addr, >od_high,
sizeof(gtod_high)))
return -EFAULT;
- VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x\n", gtod_high);
+ VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x", gtod_high);
return 0;
}
@@ -571,7 +571,7 @@ static int kvm_s390_get_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
gtod = kvm_s390_get_tod_clock_fast(kvm);
if (copy_to_user((void __user *)attr->addr, >od, sizeof(gtod)))
return -EFAULT;
- VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx\n", gtod);
+ VM_EVENT(kvm, 3, "QUERY: TOD base: 0x%llx", gtod);
return 0;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [GIT PULL 3/3] KVM: s390: use simple switch statement as multiplexer
2015-10-29 15:08 [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Christian Borntraeger
2015-10-29 15:08 ` [GIT PULL 1/3] KVM: s390: SCA must not cross page boundaries Christian Borntraeger
2015-10-29 15:08 ` [GIT PULL 2/3] KVM: s390: drop useless newline in debugging data Christian Borntraeger
@ 2015-10-29 15:08 ` Christian Borntraeger
2015-10-29 15:50 ` Alexander Graf
2015-11-02 9:27 ` [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Paolo Bonzini
3 siblings, 1 reply; 6+ messages in thread
From: Christian Borntraeger @ 2015-10-29 15:08 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Alexander Graf, KVM, Cornelia Huck, Jens Freimann, linux-s390,
Christian Borntraeger
We currently do some magic shifting (by exploiting that exit codes
are always a multiple of 4) and a table lookup to jump into the
exit handlers. This causes some calculations and checks, just to
do an potentially expensive function call.
Changing that to a switch statement gives the compiler the chance
to inline and dynamically decide between jump tables or inline
compare and branches. In addition it makes the code more readable.
bloat-o-meter gives me a small reduction in code size:
add/remove: 0/7 grow/shrink: 1/1 up/down: 986/-1334 (-348)
function old new delta
kvm_handle_sie_intercept 72 1058 +986
handle_prog 704 696 -8
handle_noop 54 - -54
handle_partial_execution 60 - -60
intercept_funcs 120 - -120
handle_instruction 198 - -198
handle_validity 210 - -210
handle_stop 316 - -316
handle_external_interrupt 368 - -368
Right now my gcc does conditional branches instead of jump tables.
The inlining seems to give us enough cycles as some micro-benchmarking
shows minimal improvements, but still in noise.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
arch/s390/kvm/intercept.c | 42 +++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 7365e8a..b4a5aa1 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -336,28 +336,28 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
return -EOPNOTSUPP;
}
-static const intercept_handler_t intercept_funcs[] = {
- [0x00 >> 2] = handle_noop,
- [0x04 >> 2] = handle_instruction,
- [0x08 >> 2] = handle_prog,
- [0x10 >> 2] = handle_noop,
- [0x14 >> 2] = handle_external_interrupt,
- [0x18 >> 2] = handle_noop,
- [0x1C >> 2] = kvm_s390_handle_wait,
- [0x20 >> 2] = handle_validity,
- [0x28 >> 2] = handle_stop,
- [0x38 >> 2] = handle_partial_execution,
-};
-
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
{
- intercept_handler_t func;
- u8 code = vcpu->arch.sie_block->icptcode;
-
- if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
+ switch (vcpu->arch.sie_block->icptcode) {
+ case 0x00:
+ case 0x10:
+ case 0x18:
+ return handle_noop(vcpu);
+ case 0x04:
+ return handle_instruction(vcpu);
+ case 0x08:
+ return handle_prog(vcpu);
+ case 0x14:
+ return handle_external_interrupt(vcpu);
+ case 0x1c:
+ return kvm_s390_handle_wait(vcpu);
+ case 0x20:
+ return handle_validity(vcpu);
+ case 0x28:
+ return handle_stop(vcpu);
+ case 0x38:
+ return handle_partial_execution(vcpu);
+ default:
return -EOPNOTSUPP;
- func = intercept_funcs[code >> 2];
- if (func)
- return func(vcpu);
- return -EOPNOTSUPP;
+ }
}
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [GIT PULL 3/3] KVM: s390: use simple switch statement as multiplexer
2015-10-29 15:08 ` [GIT PULL 3/3] KVM: s390: use simple switch statement as multiplexer Christian Borntraeger
@ 2015-10-29 15:50 ` Alexander Graf
0 siblings, 0 replies; 6+ messages in thread
From: Alexander Graf @ 2015-10-29 15:50 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Paolo Bonzini, KVM, Cornelia Huck, Jens Freimann, linux-s390
> Am 29.10.2015 um 16:08 schrieb Christian Borntraeger <borntraeger@de.ibm.com>:
>
> We currently do some magic shifting (by exploiting that exit codes
> are always a multiple of 4) and a table lookup to jump into the
> exit handlers. This causes some calculations and checks, just to
> do an potentially expensive function call.
>
> Changing that to a switch statement gives the compiler the chance
> to inline and dynamically decide between jump tables or inline
> compare and branches. In addition it makes the code more readable.
>
> bloat-o-meter gives me a small reduction in code size:
>
> add/remove: 0/7 grow/shrink: 1/1 up/down: 986/-1334 (-348)
> function old new delta
> kvm_handle_sie_intercept 72 1058 +986
> handle_prog 704 696 -8
> handle_noop 54 - -54
> handle_partial_execution 60 - -60
> intercept_funcs 120 - -120
> handle_instruction 198 - -198
> handle_validity 210 - -210
> handle_stop 316 - -316
> handle_external_interrupt 368 - -368
>
> Right now my gcc does conditional branches instead of jump tables.
> The inlining seems to give us enough cycles as some micro-benchmarking
> shows minimal improvements, but still in noise.
Awesome. I ended up with the same conclusions on switch vs table lookups in the ppc code back in the day.
>
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
> arch/s390/kvm/intercept.c | 42 +++++++++++++++++++++---------------------
> 1 file changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
> index 7365e8a..b4a5aa1 100644
> --- a/arch/s390/kvm/intercept.c
> +++ b/arch/s390/kvm/intercept.c
> @@ -336,28 +336,28 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
> return -EOPNOTSUPP;
> }
>
> -static const intercept_handler_t intercept_funcs[] = {
> - [0x00 >> 2] = handle_noop,
> - [0x04 >> 2] = handle_instruction,
> - [0x08 >> 2] = handle_prog,
> - [0x10 >> 2] = handle_noop,
> - [0x14 >> 2] = handle_external_interrupt,
> - [0x18 >> 2] = handle_noop,
> - [0x1C >> 2] = kvm_s390_handle_wait,
> - [0x20 >> 2] = handle_validity,
> - [0x28 >> 2] = handle_stop,
> - [0x38 >> 2] = handle_partial_execution,
> -};
> -
> int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
> {
> - intercept_handler_t func;
> - u8 code = vcpu->arch.sie_block->icptcode;
> -
> - if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
> + switch (vcpu->arch.sie_block->icptcode) {
> + case 0x00:
> + case 0x10:
> + case 0x18:
... if you could convert these magic numbers to something more telling however, I think readability would improve even more! That can easily be a follow up patch though.
Alex
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4)
2015-10-29 15:08 [GIT PULL 0/3] KVM: s390: Bugfix and cleanups for kvm/next (4.4) Christian Borntraeger
` (2 preceding siblings ...)
2015-10-29 15:08 ` [GIT PULL 3/3] KVM: s390: use simple switch statement as multiplexer Christian Borntraeger
@ 2015-11-02 9:27 ` Paolo Bonzini
3 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2015-11-02 9:27 UTC (permalink / raw)
To: Christian Borntraeger
Cc: Alexander Graf, KVM, Cornelia Huck, Jens Freimann, linux-s390
On 29/10/2015 16:08, Christian Borntraeger wrote:
> git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git tags/kvm-s390-next-20151028
Pulled, thanks!
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread