Alexander Graf d14cb2
From: Christian Borntraeger <borntraeger@de.ibm.com>
Alexander Graf d14cb2
Date: Wed, 17 Jan 2018 14:44:34 +0100
Alexander Graf d14cb2
Subject: KVM: s390: wire up bpb feature
Alexander Graf d14cb2
MIME-Version: 1.0
Alexander Graf d14cb2
Content-Type: text/plain; charset=UTF-8
Alexander Graf d14cb2
Content-Transfer-Encoding: 8bit
Alexander Graf d14cb2
Patch-mainline: v4.15-rc9
Alexander Graf d14cb2
Git-commit: 35b3fde6203b932b2b1a5b53b3d8808abc9c4f60
Alexander Graf d14cb2
References: bsc#1077761
Alexander Graf d14cb2
Alexander Graf d14cb2
The new firmware interfaces for branch prediction behaviour changes
Alexander Graf d14cb2
are transparently available for the guest. Nevertheless, there is
Alexander Graf d14cb2
new state attached that should be migrated and properly resetted.
Alexander Graf d14cb2
Provide a mechanism for handling reset, migration and VSIE.
Alexander Graf d14cb2
Alexander Graf d14cb2
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Alexander Graf d14cb2
Reviewed-by: David Hildenbrand <david@redhat.com>
Alexander Graf d14cb2
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Alexander Graf d14cb2
[Changed capability number to 152. - Radim]
Alexander Graf d14cb2
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Alexander Graf d14cb2
Acked-by: Alexander Graf <agraf@suse.de>
Alexander Graf d14cb2
---
Alexander Graf d14cb2
 arch/s390/include/asm/kvm_host.h |    3 ++-
Alexander Graf d14cb2
 arch/s390/include/uapi/asm/kvm.h |    5 ++++-
Alexander Graf d14cb2
 arch/s390/kvm/kvm-s390.c         |   12 ++++++++++++
Alexander Graf d14cb2
 arch/s390/kvm/vsie.c             |   10 ++++++++++
Alexander Graf d14cb2
 include/uapi/linux/kvm.h         |    1 +
Alexander Graf d14cb2
 5 files changed, 29 insertions(+), 2 deletions(-)
Alexander Graf d14cb2
Alexander Graf d14cb2
--- a/arch/s390/include/asm/kvm_host.h
Alexander Graf d14cb2
+++ b/arch/s390/include/asm/kvm_host.h
Alexander Graf d14cb2
@@ -210,7 +210,8 @@
Alexander Graf d14cb2
 	__u16	ipa;			/* 0x0056 */
Alexander Graf d14cb2
 	__u32	ipb;			/* 0x0058 */
Alexander Graf d14cb2
 	__u32	scaoh;			/* 0x005c */
Alexander Graf d14cb2
-	__u8	reserved60;		/* 0x0060 */
Alexander Graf d14cb2
+#define FPF_BPBC 	0x20
Alexander Graf d14cb2
+	__u8	fpf;			/* 0x0060 */
Alexander Graf d14cb2
 #define ECB_GS		0x40
Alexander Graf d14cb2
 #define ECB_TE		0x10
Alexander Graf d14cb2
 #define ECB_SRSI	0x04
Alexander Graf d14cb2
--- a/arch/s390/include/uapi/asm/kvm.h
Alexander Graf d14cb2
+++ b/arch/s390/include/uapi/asm/kvm.h
Alexander Graf d14cb2
@@ -227,6 +227,7 @@
Alexander Graf d14cb2
 #define KVM_SYNC_RICCB  (1UL << 7)
Alexander Graf d14cb2
 #define KVM_SYNC_FPRS   (1UL << 8)
Alexander Graf d14cb2
 #define KVM_SYNC_GSCB   (1UL << 9)
Alexander Graf d14cb2
+#define KVM_SYNC_BPBC   (1UL << 10)
Alexander Graf d14cb2
 /* length and alignment of the sdnx as a power of two */
Alexander Graf d14cb2
 #define SDNXC 8
Alexander Graf d14cb2
 #define SDNXL (1UL << SDNXC)
Alexander Graf d14cb2
@@ -250,7 +251,9 @@
Alexander Graf d14cb2
 	};
Alexander Graf d14cb2
 	__u8  reserved[512];	/* for future vector expansion */
Alexander Graf d14cb2
 	__u32 fpc;		/* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
Alexander Graf d14cb2
-	__u8 padding1[52];	/* riccb needs to be 64byte aligned */
Alexander Graf d14cb2
+	__u8 bpbc : 1;		/* bp mode */
Alexander Graf d14cb2
+	__u8 reserved2 : 7;
Alexander Graf d14cb2
+	__u8 padding1[51];	/* riccb needs to be 64byte aligned */
Alexander Graf d14cb2
 	__u8 riccb[64];		/* runtime instrumentation controls block */
Alexander Graf d14cb2
 	__u8 padding2[192];	/* sdnx needs to be 256byte aligned */
Alexander Graf d14cb2
 	union {
Alexander Graf d14cb2
--- a/arch/s390/kvm/kvm-s390.c
Alexander Graf d14cb2
+++ b/arch/s390/kvm/kvm-s390.c
Alexander Graf d14cb2
@@ -421,6 +421,9 @@
Alexander Graf d14cb2
 	case KVM_CAP_S390_GS:
Alexander Graf d14cb2
 		r = test_facility(133);
Alexander Graf d14cb2
 		break;
Alexander Graf d14cb2
+	case KVM_CAP_S390_BPB:
Alexander Graf d14cb2
+		r = test_facility(82);
Alexander Graf d14cb2
+		break;
Alexander Graf d14cb2
 	default:
Alexander Graf d14cb2
 		r = 0;
Alexander Graf d14cb2
 	}
Alexander Graf d14cb2
@@ -2198,6 +2201,8 @@
Alexander Graf d14cb2
 	kvm_s390_set_prefix(vcpu, 0);
Alexander Graf d14cb2
 	if (test_kvm_facility(vcpu->kvm, 64))
Alexander Graf d14cb2
 		vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
Alexander Graf d14cb2
+	if (test_kvm_facility(vcpu->kvm, 82))
Alexander Graf d14cb2
+		vcpu->run->kvm_valid_regs |= KVM_SYNC_BPBC;
Alexander Graf d14cb2
 	if (test_kvm_facility(vcpu->kvm, 133))
Alexander Graf d14cb2
 		vcpu->run->kvm_valid_regs |= KVM_SYNC_GSCB;
Alexander Graf d14cb2
 	/* fprs can be synchronized via vrs, even if the guest has no vx. With
Alexander Graf d14cb2
@@ -2339,6 +2344,7 @@
Alexander Graf d14cb2
 	current->thread.fpu.fpc = 0;
Alexander Graf d14cb2
 	vcpu->arch.sie_block->gbea = 1;
Alexander Graf d14cb2
 	vcpu->arch.sie_block->pp = 0;
Alexander Graf d14cb2
+	vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
Alexander Graf d14cb2
 	vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
Alexander Graf d14cb2
 	kvm_clear_async_pf_completion_queue(vcpu);
Alexander Graf d14cb2
 	if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
Alexander Graf d14cb2
@@ -3298,6 +3304,11 @@
Alexander Graf d14cb2
 		vcpu->arch.sie_block->ecd |= ECD_HOSTREGMGMT;
Alexander Graf d14cb2
 		vcpu->arch.gs_enabled = 1;
Alexander Graf d14cb2
 	}
Alexander Graf d14cb2
+	if ((kvm_run->kvm_dirty_regs & KVM_SYNC_BPBC) &&
Alexander Graf d14cb2
+	    test_kvm_facility(vcpu->kvm, 82)) {
Alexander Graf d14cb2
+		vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
Alexander Graf d14cb2
+		vcpu->arch.sie_block->fpf |= kvm_run->s.regs.bpbc ? FPF_BPBC : 0;
Alexander Graf d14cb2
+	}
Alexander Graf d14cb2
 	save_access_regs(vcpu->arch.host_acrs);
Alexander Graf d14cb2
 	restore_access_regs(vcpu->run->s.regs.acrs);
Alexander Graf d14cb2
 	/* save host (userspace) fprs/vrs */
Alexander Graf d14cb2
@@ -3344,6 +3355,7 @@
Alexander Graf d14cb2
 	kvm_run->s.regs.pft = vcpu->arch.pfault_token;
Alexander Graf d14cb2
 	kvm_run->s.regs.pfs = vcpu->arch.pfault_select;
Alexander Graf d14cb2
 	kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
Alexander Graf d14cb2
+	kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == FPF_BPBC;
Alexander Graf d14cb2
 	save_access_regs(vcpu->run->s.regs.acrs);
Alexander Graf d14cb2
 	restore_access_regs(vcpu->arch.host_acrs);
Alexander Graf d14cb2
 	/* Save guest register state */
Alexander Graf d14cb2
--- a/arch/s390/kvm/vsie.c
Alexander Graf d14cb2
+++ b/arch/s390/kvm/vsie.c
Alexander Graf d14cb2
@@ -223,6 +223,12 @@
Alexander Graf d14cb2
 	memcpy(scb_o->gcr, scb_s->gcr, 128);
Alexander Graf d14cb2
 	scb_o->pp = scb_s->pp;
Alexander Graf d14cb2
 
Alexander Graf d14cb2
+	/* branch prediction */
Alexander Graf d14cb2
+	if (test_kvm_facility(vcpu->kvm, 82)) {
Alexander Graf d14cb2
+		scb_o->fpf &= ~FPF_BPBC;
Alexander Graf d14cb2
+		scb_o->fpf |= scb_s->fpf & FPF_BPBC;
Alexander Graf d14cb2
+	}
Alexander Graf d14cb2
+
Alexander Graf d14cb2
 	/* interrupt intercept */
Alexander Graf d14cb2
 	switch (scb_s->icptcode) {
Alexander Graf d14cb2
 	case ICPT_PROGI:
Alexander Graf d14cb2
@@ -265,6 +271,7 @@
Alexander Graf d14cb2
 	scb_s->ecb3 = 0;
Alexander Graf d14cb2
 	scb_s->ecd = 0;
Alexander Graf d14cb2
 	scb_s->fac = 0;
Alexander Graf d14cb2
+	scb_s->fpf = 0;
Alexander Graf d14cb2
 
Alexander Graf d14cb2
 	rc = prepare_cpuflags(vcpu, vsie_page);
Alexander Graf d14cb2
 	if (rc)
Alexander Graf d14cb2
@@ -324,6 +331,9 @@
Alexander Graf d14cb2
 			prefix_unmapped(vsie_page);
Alexander Graf d14cb2
 		scb_s->ecb |= scb_o->ecb & ECB_TE;
Alexander Graf d14cb2
 	}
Alexander Graf d14cb2
+	/* branch prediction */
Alexander Graf d14cb2
+	if (test_kvm_facility(vcpu->kvm, 82))
Alexander Graf d14cb2
+		scb_s->fpf |= scb_o->fpf & FPF_BPBC;
Alexander Graf d14cb2
 	/* SIMD */
Alexander Graf d14cb2
 	if (test_kvm_facility(vcpu->kvm, 129)) {
Alexander Graf d14cb2
 		scb_s->eca |= scb_o->eca & ECA_VX;
Alexander Graf d14cb2
--- a/include/uapi/linux/kvm.h
Alexander Graf d14cb2
+++ b/include/uapi/linux/kvm.h
Alexander Graf d14cb2
@@ -932,6 +932,7 @@
Alexander Graf d14cb2
 #define KVM_CAP_HYPERV_VP_INDEX 149
Alexander Graf d14cb2
 #define KVM_CAP_S390_AIS_MIGRATION 150
Alexander Graf d14cb2
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
Alexander Graf d14cb2
+#define KVM_CAP_S390_BPB 152
Alexander Graf d14cb2
 
Alexander Graf d14cb2
 #ifdef KVM_CAP_IRQ_ROUTING
Alexander Graf d14cb2