All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16
@ 2018-02-14 15:56 Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 1/6] KVM: s390: optimize wakeup for exitless interrupts Christian Borntraeger
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

Paolo, Radim,

some fixes and improvements for 4.16. (via kvm/master).
Either for features new in 4.16 or to improve the speculative
execution handling.

The following changes since commit 7928b2cbe55b2a410a0f5c1f154610059c57b1b2:

  Linux 4.16-rc1 (2018-02-11 15:04:29 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git  tags/kvm-s390-master-4.16-1

for you to fetch changes up to baabee67f4135e3de87bc874929ac50637aacb0d:

  KVM: s390: use switch vs jump table in interrupt.c (2018-02-14 13:53:43 +0000)

----------------------------------------------------------------
KVM: s390: Fixes and improvements for 4.16

- optimization for the exitless interrupt support that was merged
  in 4.16-rc1
- improve the branch prediction blocking for nested KVM
- replace some jump tables with switch statements to improve
  expoline performance

----------------------------------------------------------------
Christian Borntraeger (5):
      KVM: s390: optimize wakeup for exitless interrupts
      KVM: s390: do not set intervention requests for GISA interrupts
      KVM: s390: force bp isolation for VSIE
      KVM: s390: use switch vs jump table in priv.c
      KVM: s390: use switch vs jump table in intercept.c

David Hildenbrand (1):
      KVM: s390: use switch vs jump table in interrupt.c

 arch/s390/kvm/intercept.c |  51 +++++++------
 arch/s390/kvm/interrupt.c |  98 +++++++++++++++----------
 arch/s390/kvm/kvm-s390.h  |   2 -
 arch/s390/kvm/priv.c      | 183 +++++++++++++++++++++++-----------------------
 arch/s390/kvm/vsie.c      |  20 +++++
 5 files changed, 200 insertions(+), 154 deletions(-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [GIT PULL 1/6] KVM: s390: optimize wakeup for exitless interrupts
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 2/6] KVM: s390: do not set intervention requests for GISA interrupts Christian Borntraeger
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

For interrupt injection of floating interrupts we queue the interrupt
either in the GISA or in the floating  interrupt list. The first CPU
that looks at these data structures - either in KVM code or hardware
will then deliver that interrupt. To minimize latency we also:
-a: choose a VCPU to deliver that interrupt. We prefer idle CPUs
-b: we wake up the host thread that runs the VCPU
-c: set an I/O intervention bit for that CPU so that it exits guest
    context as soon as the PSW I/O mask is enabled
This will make sure that this CPU will execute the interrupt delivery
code of KVM very soon.

We can now optimize the injection case if we have exitless interrupts.
The wakeup is still necessary in case the target CPU sleeps. We can
avoid the I/O intervention request bit though. Whenever this
intervention request would be handled, the hardware could also directly
inject the interrupt on that CPU, no need to go through the interrupt
injection loop of KVM.

Cc: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/interrupt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index aabf46f5f883..337a69bc04db 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1701,7 +1701,8 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
 		kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT);
 		break;
 	case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
-		kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
+		if (!(type & KVM_S390_INT_IO_AI_MASK && kvm->arch.gisa))
+			kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
 		break;
 	default:
 		kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_EXT_INT);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [GIT PULL 2/6] KVM: s390: do not set intervention requests for GISA interrupts
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 1/6] KVM: s390: optimize wakeup for exitless interrupts Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 3/6] KVM: s390: force bp isolation for VSIE Christian Borntraeger
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

If GISA is available, we do not have to kick CPUs out of SIE to deliver
interrupts. The hardware can deliver such interrupts while running.

Cc: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/interrupt.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 337a69bc04db..e399495001ca 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -236,10 +236,15 @@ static inline int kvm_s390_gisa_tac_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gis
 	return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
 }
 
-static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
+static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu)
 {
 	return vcpu->kvm->arch.float_int.pending_irqs |
-		vcpu->arch.local_int.pending_irqs |
+		vcpu->arch.local_int.pending_irqs;
+}
+
+static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
+{
+	return pending_irqs_no_gisa(vcpu) |
 		kvm_s390_gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7;
 }
 
@@ -337,7 +342,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
 
 static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
 {
-	if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK))
+	if (!(pending_irqs_no_gisa(vcpu) & IRQ_PEND_IO_MASK))
 		return;
 	else if (psw_ioint_disabled(vcpu))
 		kvm_s390_set_cpuflags(vcpu, CPUSTAT_IO_INT);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [GIT PULL 3/6] KVM: s390: force bp isolation for VSIE
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 1/6] KVM: s390: optimize wakeup for exitless interrupts Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 2/6] KVM: s390: do not set intervention requests for GISA interrupts Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 4/6] KVM: s390: use switch vs jump table in priv.c Christian Borntraeger
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

If the guest runs with bp isolation when doing a SIE instruction,
we must also run the nested guest with bp isolation when emulating
that SIE instruction.
This is done by activating BPBC in the lpar, which acts as an override
for lower level guests.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/vsie.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index ec772700ff96..8961e3970901 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -821,6 +821,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 {
 	struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
 	struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
+	int guest_bp_isolation;
 	int rc;
 
 	handle_last_fault(vcpu, vsie_page);
@@ -831,6 +832,20 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 		s390_handle_mcck();
 
 	srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
+
+	/* save current guest state of bp isolation override */
+	guest_bp_isolation = test_thread_flag(TIF_ISOLATE_BP_GUEST);
+
+	/*
+	 * The guest is running with BPBC, so we have to force it on for our
+	 * nested guest. This is done by enabling BPBC globally, so the BPBC
+	 * control in the SCB (which the nested guest can modify) is simply
+	 * ignored.
+	 */
+	if (test_kvm_facility(vcpu->kvm, 82) &&
+	    vcpu->arch.sie_block->fpf & FPF_BPBC)
+		set_thread_flag(TIF_ISOLATE_BP_GUEST);
+
 	local_irq_disable();
 	guest_enter_irqoff();
 	local_irq_enable();
@@ -840,6 +855,11 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 	local_irq_disable();
 	guest_exit_irqoff();
 	local_irq_enable();
+
+	/* restore guest state for bp isolation override */
+	if (!guest_bp_isolation)
+		clear_thread_flag(TIF_ISOLATE_BP_GUEST);
+
 	vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 
 	if (rc == -EINTR) {
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [GIT PULL 4/6] KVM: s390: use switch vs jump table in priv.c
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
                   ` (2 preceding siblings ...)
  2018-02-14 15:56 ` [GIT PULL 3/6] KVM: s390: force bp isolation for VSIE Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 5/6] KVM: s390: use switch vs jump table in intercept.c Christian Borntraeger
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

Instead of having huge jump tables for function selection,
let's use normal switch/case statements for the instruction
handlers in priv.c

This allows the compiler to make the right decision depending
on the situation (e.g. avoid jump-tables for thunks).

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/priv.c | 183 +++++++++++++++++++++++++--------------------------
 1 file changed, 91 insertions(+), 92 deletions(-)

diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index c4c4e157c036..a74578cdd3f3 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -795,55 +795,60 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
 	return rc;
 }
 
-static const intercept_handler_t b2_handlers[256] = {
-	[0x02] = handle_stidp,
-	[0x04] = handle_set_clock,
-	[0x10] = handle_set_prefix,
-	[0x11] = handle_store_prefix,
-	[0x12] = handle_store_cpu_address,
-	[0x14] = kvm_s390_handle_vsie,
-	[0x21] = handle_ipte_interlock,
-	[0x29] = handle_iske,
-	[0x2a] = handle_rrbe,
-	[0x2b] = handle_sske,
-	[0x2c] = handle_test_block,
-	[0x30] = handle_io_inst,
-	[0x31] = handle_io_inst,
-	[0x32] = handle_io_inst,
-	[0x33] = handle_io_inst,
-	[0x34] = handle_io_inst,
-	[0x35] = handle_io_inst,
-	[0x36] = handle_io_inst,
-	[0x37] = handle_io_inst,
-	[0x38] = handle_io_inst,
-	[0x39] = handle_io_inst,
-	[0x3a] = handle_io_inst,
-	[0x3b] = handle_io_inst,
-	[0x3c] = handle_io_inst,
-	[0x50] = handle_ipte_interlock,
-	[0x56] = handle_sthyi,
-	[0x5f] = handle_io_inst,
-	[0x74] = handle_io_inst,
-	[0x76] = handle_io_inst,
-	[0x7d] = handle_stsi,
-	[0xb1] = handle_stfl,
-	[0xb2] = handle_lpswe,
-};
-
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
 {
-	intercept_handler_t handler;
-
-	/*
-	 * A lot of B2 instructions are priviledged. Here we check for
-	 * the privileged ones, that we can handle in the kernel.
-	 * Anything else goes to userspace.
-	 */
-	handler = b2_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler)
-		return handler(vcpu);
-
-	return -EOPNOTSUPP;
+	switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+	case 0x02:
+		return handle_stidp(vcpu);
+	case 0x04:
+		return handle_set_clock(vcpu);
+	case 0x10:
+		return handle_set_prefix(vcpu);
+	case 0x11:
+		return handle_store_prefix(vcpu);
+	case 0x12:
+		return handle_store_cpu_address(vcpu);
+	case 0x14:
+		return kvm_s390_handle_vsie(vcpu);
+	case 0x21:
+	case 0x50:
+		return handle_ipte_interlock(vcpu);
+	case 0x29:
+		return handle_iske(vcpu);
+	case 0x2a:
+		return handle_rrbe(vcpu);
+	case 0x2b:
+		return handle_sske(vcpu);
+	case 0x2c:
+		return handle_test_block(vcpu);
+	case 0x30:
+	case 0x31:
+	case 0x32:
+	case 0x33:
+	case 0x34:
+	case 0x35:
+	case 0x36:
+	case 0x37:
+	case 0x38:
+	case 0x39:
+	case 0x3a:
+	case 0x3b:
+	case 0x3c:
+	case 0x5f:
+	case 0x74:
+	case 0x76:
+		return handle_io_inst(vcpu);
+	case 0x56:
+		return handle_sthyi(vcpu);
+	case 0x7d:
+		return handle_stsi(vcpu);
+	case 0xb1:
+		return handle_stfl(vcpu);
+	case 0xb2:
+		return handle_lpswe(vcpu);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static int handle_epsw(struct kvm_vcpu *vcpu)
@@ -1105,25 +1110,22 @@ static int handle_essa(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-static const intercept_handler_t b9_handlers[256] = {
-	[0x8a] = handle_ipte_interlock,
-	[0x8d] = handle_epsw,
-	[0x8e] = handle_ipte_interlock,
-	[0x8f] = handle_ipte_interlock,
-	[0xab] = handle_essa,
-	[0xaf] = handle_pfmf,
-};
-
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu)
 {
-	intercept_handler_t handler;
-
-	/* This is handled just as for the B2 instructions. */
-	handler = b9_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler)
-		return handler(vcpu);
-
-	return -EOPNOTSUPP;
+	switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+	case 0x8a:
+	case 0x8e:
+	case 0x8f:
+		return handle_ipte_interlock(vcpu);
+	case 0x8d:
+		return handle_epsw(vcpu);
+	case 0xab:
+		return handle_essa(vcpu);
+	case 0xaf:
+		return handle_pfmf(vcpu);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu)
@@ -1271,22 +1273,20 @@ static int handle_stctg(struct kvm_vcpu *vcpu)
 	return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0;
 }
 
-static const intercept_handler_t eb_handlers[256] = {
-	[0x2f] = handle_lctlg,
-	[0x25] = handle_stctg,
-	[0x60] = handle_ri,
-	[0x61] = handle_ri,
-	[0x62] = handle_ri,
-};
-
 int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
 {
-	intercept_handler_t handler;
-
-	handler = eb_handlers[vcpu->arch.sie_block->ipb & 0xff];
-	if (handler)
-		return handler(vcpu);
-	return -EOPNOTSUPP;
+	switch (vcpu->arch.sie_block->ipb & 0x000000ff) {
+	case 0x25:
+		return handle_stctg(vcpu);
+	case 0x2f:
+		return handle_lctlg(vcpu);
+	case 0x60:
+	case 0x61:
+	case 0x62:
+		return handle_ri(vcpu);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static int handle_tprot(struct kvm_vcpu *vcpu)
@@ -1346,10 +1346,12 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
 
 int kvm_s390_handle_e5(struct kvm_vcpu *vcpu)
 {
-	/* For e5xx... instructions we only handle TPROT */
-	if ((vcpu->arch.sie_block->ipa & 0x00ff) == 0x01)
+	switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+	case 0x01:
 		return handle_tprot(vcpu);
-	return -EOPNOTSUPP;
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static int handle_sckpf(struct kvm_vcpu *vcpu)
@@ -1380,17 +1382,14 @@ static int handle_ptff(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-static const intercept_handler_t x01_handlers[256] = {
-	[0x04] = handle_ptff,
-	[0x07] = handle_sckpf,
-};
-
 int kvm_s390_handle_01(struct kvm_vcpu *vcpu)
 {
-	intercept_handler_t handler;
-
-	handler = x01_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler)
-		return handler(vcpu);
-	return -EOPNOTSUPP;
+	switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+	case 0x04:
+		return handle_ptff(vcpu);
+	case 0x07:
+		return handle_sckpf(vcpu);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [GIT PULL 5/6] KVM: s390: use switch vs jump table in intercept.c
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
                   ` (3 preceding siblings ...)
  2018-02-14 15:56 ` [GIT PULL 4/6] KVM: s390: use switch vs jump table in priv.c Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 15:56 ` [GIT PULL 6/6] KVM: s390: use switch vs jump table in interrupt.c Christian Borntraeger
  2018-02-14 16:19 ` [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

Instead of having huge jump tables for function selection,
let's use normal switch/case statements for the instruction
handlers in intercept.c We can now also get rid of
intercept_handler_t.

This allows the compiler to make the right decision depending
on the situation (e.g. avoid jump-tables for thunks).

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/intercept.c | 51 +++++++++++++++++++++++++++--------------------
 arch/s390/kvm/kvm-s390.h  |  2 --
 2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 9c7d70715862..07c6e81163bf 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -22,22 +22,6 @@
 #include "trace.h"
 #include "trace-s390.h"
 
-
-static const intercept_handler_t instruction_handlers[256] = {
-	[0x01] = kvm_s390_handle_01,
-	[0x82] = kvm_s390_handle_lpsw,
-	[0x83] = kvm_s390_handle_diag,
-	[0xaa] = kvm_s390_handle_aa,
-	[0xae] = kvm_s390_handle_sigp,
-	[0xb2] = kvm_s390_handle_b2,
-	[0xb6] = kvm_s390_handle_stctl,
-	[0xb7] = kvm_s390_handle_lctl,
-	[0xb9] = kvm_s390_handle_b9,
-	[0xe3] = kvm_s390_handle_e3,
-	[0xe5] = kvm_s390_handle_e5,
-	[0xeb] = kvm_s390_handle_eb,
-};
-
 u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
 {
 	struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
@@ -129,16 +113,39 @@ static int handle_validity(struct kvm_vcpu *vcpu)
 
 static int handle_instruction(struct kvm_vcpu *vcpu)
 {
-	intercept_handler_t handler;
-
 	vcpu->stat.exit_instruction++;
 	trace_kvm_s390_intercept_instruction(vcpu,
 					     vcpu->arch.sie_block->ipa,
 					     vcpu->arch.sie_block->ipb);
-	handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
-	if (handler)
-		return handler(vcpu);
-	return -EOPNOTSUPP;
+
+	switch (vcpu->arch.sie_block->ipa >> 8) {
+	case 0x01:
+		return kvm_s390_handle_01(vcpu);
+	case 0x82:
+		return kvm_s390_handle_lpsw(vcpu);
+	case 0x83:
+		return kvm_s390_handle_diag(vcpu);
+	case 0xaa:
+		return kvm_s390_handle_aa(vcpu);
+	case 0xae:
+		return kvm_s390_handle_sigp(vcpu);
+	case 0xb2:
+		return kvm_s390_handle_b2(vcpu);
+	case 0xb6:
+		return kvm_s390_handle_stctl(vcpu);
+	case 0xb7:
+		return kvm_s390_handle_lctl(vcpu);
+	case 0xb9:
+		return kvm_s390_handle_b9(vcpu);
+	case 0xe3:
+		return kvm_s390_handle_e3(vcpu);
+	case 0xe5:
+		return kvm_s390_handle_e5(vcpu);
+	case 0xeb:
+		return kvm_s390_handle_eb(vcpu);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index bd31b37b0e6f..3c0a975c2477 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -19,8 +19,6 @@
 #include <asm/processor.h>
 #include <asm/sclp.h>
 
-typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
-
 /* Transactional Memory Execution related macros */
 #define IS_TE_ENABLED(vcpu)	((vcpu->arch.sie_block->ecb & ECB_TE))
 #define TDB_FORMAT1		1
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [GIT PULL 6/6] KVM: s390: use switch vs jump table in interrupt.c
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
                   ` (4 preceding siblings ...)
  2018-02-14 15:56 ` [GIT PULL 5/6] KVM: s390: use switch vs jump table in intercept.c Christian Borntraeger
@ 2018-02-14 15:56 ` Christian Borntraeger
  2018-02-14 16:19 ` [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Borntraeger @ 2018-02-14 15:56 UTC (permalink / raw
  To: Paolo Bonzini, Radim Krčmář
  Cc: KVM, Cornelia Huck, Christian Borntraeger, linux-s390,
	Janosch Frank, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Just like for the interception handlers, let's also use a switch-case
in our interrupt delivery code.

Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180206141743.24497-1-david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++-------------------
 1 file changed, 50 insertions(+), 34 deletions(-)

diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index e399495001ca..3f2c49b1a393 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
 	return kvm_s390_get_cpu_timer(vcpu) >> 63;
 }
 
-static inline int is_ioirq(unsigned long irq_type)
-{
-	return ((irq_type >= IRQ_PEND_IO_ISC_7) &&
-		(irq_type <= IRQ_PEND_IO_ISC_0));
-}
-
 static uint64_t isc_to_isc_bits(int isc)
 {
 	return (0x80 >> isc) << 24;
@@ -1016,24 +1010,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
 	return rc;
 }
 
-typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu);
-
-static const deliver_irq_t deliver_irq_funcs[] = {
-	[IRQ_PEND_MCHK_EX]        = __deliver_machine_check,
-	[IRQ_PEND_MCHK_REP]       = __deliver_machine_check,
-	[IRQ_PEND_PROG]           = __deliver_prog,
-	[IRQ_PEND_EXT_EMERGENCY]  = __deliver_emergency_signal,
-	[IRQ_PEND_EXT_EXTERNAL]   = __deliver_external_call,
-	[IRQ_PEND_EXT_CLOCK_COMP] = __deliver_ckc,
-	[IRQ_PEND_EXT_CPU_TIMER]  = __deliver_cpu_timer,
-	[IRQ_PEND_RESTART]        = __deliver_restart,
-	[IRQ_PEND_SET_PREFIX]     = __deliver_set_prefix,
-	[IRQ_PEND_PFAULT_INIT]    = __deliver_pfault_init,
-	[IRQ_PEND_EXT_SERVICE]    = __deliver_service,
-	[IRQ_PEND_PFAULT_DONE]    = __deliver_pfault_done,
-	[IRQ_PEND_VIRTIO]         = __deliver_virtio,
-};
-
 /* Check whether an external call is pending (deliverable or not) */
 int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
 {
@@ -1197,7 +1173,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
 int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
 {
 	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
-	deliver_irq_t func;
 	int rc = 0;
 	unsigned long irq_type;
 	unsigned long irqs;
@@ -1217,16 +1192,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
 	while ((irqs = deliverable_irqs(vcpu)) && !rc) {
 		/* bits are in the reverse order of interrupt priority */
 		irq_type = find_last_bit(&irqs, IRQ_PEND_COUNT);
-		if (is_ioirq(irq_type)) {
+		switch (irq_type) {
+		case IRQ_PEND_IO_ISC_0:
+		case IRQ_PEND_IO_ISC_1:
+		case IRQ_PEND_IO_ISC_2:
+		case IRQ_PEND_IO_ISC_3:
+		case IRQ_PEND_IO_ISC_4:
+		case IRQ_PEND_IO_ISC_5:
+		case IRQ_PEND_IO_ISC_6:
+		case IRQ_PEND_IO_ISC_7:
 			rc = __deliver_io(vcpu, irq_type);
-		} else {
-			func = deliver_irq_funcs[irq_type];
-			if (!func) {
-				WARN_ON_ONCE(func == NULL);
-				clear_bit(irq_type, &li->pending_irqs);
-				continue;
-			}
-			rc = func(vcpu);
+			break;
+		case IRQ_PEND_MCHK_EX:
+		case IRQ_PEND_MCHK_REP:
+			rc = __deliver_machine_check(vcpu);
+			break;
+		case IRQ_PEND_PROG:
+			rc = __deliver_prog(vcpu);
+			break;
+		case IRQ_PEND_EXT_EMERGENCY:
+			rc = __deliver_emergency_signal(vcpu);
+			break;
+		case IRQ_PEND_EXT_EXTERNAL:
+			rc = __deliver_external_call(vcpu);
+			break;
+		case IRQ_PEND_EXT_CLOCK_COMP:
+			rc = __deliver_ckc(vcpu);
+			break;
+		case IRQ_PEND_EXT_CPU_TIMER:
+			rc = __deliver_cpu_timer(vcpu);
+			break;
+		case IRQ_PEND_RESTART:
+			rc = __deliver_restart(vcpu);
+			break;
+		case IRQ_PEND_SET_PREFIX:
+			rc = __deliver_set_prefix(vcpu);
+			break;
+		case IRQ_PEND_PFAULT_INIT:
+			rc = __deliver_pfault_init(vcpu);
+			break;
+		case IRQ_PEND_EXT_SERVICE:
+			rc = __deliver_service(vcpu);
+			break;
+		case IRQ_PEND_PFAULT_DONE:
+			rc = __deliver_pfault_done(vcpu);
+			break;
+		case IRQ_PEND_VIRTIO:
+			rc = __deliver_virtio(vcpu);
+			break;
+		default:
+			WARN_ONCE(1, "Unknown pending irq type %ld", irq_type);
+			clear_bit(irq_type, &li->pending_irqs);
 		}
 	}
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16
  2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
                   ` (5 preceding siblings ...)
  2018-02-14 15:56 ` [GIT PULL 6/6] KVM: s390: use switch vs jump table in interrupt.c Christian Borntraeger
@ 2018-02-14 16:19 ` Paolo Bonzini
  6 siblings, 0 replies; 8+ messages in thread
From: Paolo Bonzini @ 2018-02-14 16:19 UTC (permalink / raw
  To: Christian Borntraeger, Radim Krčmář
  Cc: KVM, Cornelia Huck, linux-s390, Janosch Frank, David Hildenbrand

On 14/02/2018 16:56, Christian Borntraeger wrote:
> Paolo, Radim,
> 
> some fixes and improvements for 4.16. (via kvm/master).
> Either for features new in 4.16 or to improve the speculative
> execution handling.

Pulled, thanks.  Should make it into rc2.

Paolo

> The following changes since commit 7928b2cbe55b2a410a0f5c1f154610059c57b1b2:
> 
>   Linux 4.16-rc1 (2018-02-11 15:04:29 -0800)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git  tags/kvm-s390-master-4.16-1
> 
> for you to fetch changes up to baabee67f4135e3de87bc874929ac50637aacb0d:
> 
>   KVM: s390: use switch vs jump table in interrupt.c (2018-02-14 13:53:43 +0000)
> 
> ----------------------------------------------------------------
> KVM: s390: Fixes and improvements for 4.16
> 
> - optimization for the exitless interrupt support that was merged
>   in 4.16-rc1
> - improve the branch prediction blocking for nested KVM
> - replace some jump tables with switch statements to improve
>   expoline performance
> 
> ----------------------------------------------------------------
> Christian Borntraeger (5):
>       KVM: s390: optimize wakeup for exitless interrupts
>       KVM: s390: do not set intervention requests for GISA interrupts
>       KVM: s390: force bp isolation for VSIE
>       KVM: s390: use switch vs jump table in priv.c
>       KVM: s390: use switch vs jump table in intercept.c
> 
> David Hildenbrand (1):
>       KVM: s390: use switch vs jump table in interrupt.c
> 
>  arch/s390/kvm/intercept.c |  51 +++++++------
>  arch/s390/kvm/interrupt.c |  98 +++++++++++++++----------
>  arch/s390/kvm/kvm-s390.h  |   2 -
>  arch/s390/kvm/priv.c      | 183 +++++++++++++++++++++++-----------------------
>  arch/s390/kvm/vsie.c      |  20 +++++
>  5 files changed, 200 insertions(+), 154 deletions(-)
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-02-14 16:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-14 15:56 [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 1/6] KVM: s390: optimize wakeup for exitless interrupts Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 2/6] KVM: s390: do not set intervention requests for GISA interrupts Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 3/6] KVM: s390: force bp isolation for VSIE Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 4/6] KVM: s390: use switch vs jump table in priv.c Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 5/6] KVM: s390: use switch vs jump table in intercept.c Christian Borntraeger
2018-02-14 15:56 ` [GIT PULL 6/6] KVM: s390: use switch vs jump table in interrupt.c Christian Borntraeger
2018-02-14 16:19 ` [GIT PULL 0/6] KVM: s390: Fixes and improvements for 4.16 Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.