Skip to content

Commit 35b3fde

Browse files
borntraegerrkrcmar
authored andcommitted
KVM: s390: wire up bpb feature
The new firmware interfaces for branch prediction behaviour changes are transparently available for the guest. Nevertheless, there is new state attached that should be migrated and properly resetted. Provide a mechanism for handling reset, migration and VSIE. Signed-off-by: Christian Borntraeger <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> Reviewed-by: Cornelia Huck <[email protected]> [Changed capability number to 152. - Radim] Signed-off-by: Radim Krčmář <[email protected]>
1 parent 29d24e3 commit 35b3fde

File tree

5 files changed

+29
-2
lines changed

5 files changed

+29
-2
lines changed

arch/s390/include/asm/kvm_host.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ struct kvm_s390_sie_block {
207207
__u16 ipa; /* 0x0056 */
208208
__u32 ipb; /* 0x0058 */
209209
__u32 scaoh; /* 0x005c */
210-
__u8 reserved60; /* 0x0060 */
210+
#define FPF_BPBC 0x20
211+
__u8 fpf; /* 0x0060 */
211212
#define ECB_GS 0x40
212213
#define ECB_TE 0x10
213214
#define ECB_SRSI 0x04

arch/s390/include/uapi/asm/kvm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ struct kvm_guest_debug_arch {
224224
#define KVM_SYNC_RICCB (1UL << 7)
225225
#define KVM_SYNC_FPRS (1UL << 8)
226226
#define KVM_SYNC_GSCB (1UL << 9)
227+
#define KVM_SYNC_BPBC (1UL << 10)
227228
/* length and alignment of the sdnx as a power of two */
228229
#define SDNXC 8
229230
#define SDNXL (1UL << SDNXC)
@@ -247,7 +248,9 @@ struct kvm_sync_regs {
247248
};
248249
__u8 reserved[512]; /* for future vector expansion */
249250
__u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
250-
__u8 padding1[52]; /* riccb needs to be 64byte aligned */
251+
__u8 bpbc : 1; /* bp mode */
252+
__u8 reserved2 : 7;
253+
__u8 padding1[51]; /* riccb needs to be 64byte aligned */
251254
__u8 riccb[64]; /* runtime instrumentation controls block */
252255
__u8 padding2[192]; /* sdnx needs to be 256byte aligned */
253256
union {

arch/s390/kvm/kvm-s390.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
421421
case KVM_CAP_S390_GS:
422422
r = test_facility(133);
423423
break;
424+
case KVM_CAP_S390_BPB:
425+
r = test_facility(82);
426+
break;
424427
default:
425428
r = 0;
426429
}
@@ -2198,6 +2201,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
21982201
kvm_s390_set_prefix(vcpu, 0);
21992202
if (test_kvm_facility(vcpu->kvm, 64))
22002203
vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
2204+
if (test_kvm_facility(vcpu->kvm, 82))
2205+
vcpu->run->kvm_valid_regs |= KVM_SYNC_BPBC;
22012206
if (test_kvm_facility(vcpu->kvm, 133))
22022207
vcpu->run->kvm_valid_regs |= KVM_SYNC_GSCB;
22032208
/* fprs can be synchronized via vrs, even if the guest has no vx. With
@@ -2339,6 +2344,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
23392344
current->thread.fpu.fpc = 0;
23402345
vcpu->arch.sie_block->gbea = 1;
23412346
vcpu->arch.sie_block->pp = 0;
2347+
vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
23422348
vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
23432349
kvm_clear_async_pf_completion_queue(vcpu);
23442350
if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
@@ -3298,6 +3304,11 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
32983304
vcpu->arch.sie_block->ecd |= ECD_HOSTREGMGMT;
32993305
vcpu->arch.gs_enabled = 1;
33003306
}
3307+
if ((kvm_run->kvm_dirty_regs & KVM_SYNC_BPBC) &&
3308+
test_kvm_facility(vcpu->kvm, 82)) {
3309+
vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
3310+
vcpu->arch.sie_block->fpf |= kvm_run->s.regs.bpbc ? FPF_BPBC : 0;
3311+
}
33013312
save_access_regs(vcpu->arch.host_acrs);
33023313
restore_access_regs(vcpu->run->s.regs.acrs);
33033314
/* save host (userspace) fprs/vrs */
@@ -3344,6 +3355,7 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
33443355
kvm_run->s.regs.pft = vcpu->arch.pfault_token;
33453356
kvm_run->s.regs.pfs = vcpu->arch.pfault_select;
33463357
kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
3358+
kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == FPF_BPBC;
33473359
save_access_regs(vcpu->run->s.regs.acrs);
33483360
restore_access_regs(vcpu->arch.host_acrs);
33493361
/* Save guest register state */

arch/s390/kvm/vsie.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ static void unshadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
223223
memcpy(scb_o->gcr, scb_s->gcr, 128);
224224
scb_o->pp = scb_s->pp;
225225

226+
/* branch prediction */
227+
if (test_kvm_facility(vcpu->kvm, 82)) {
228+
scb_o->fpf &= ~FPF_BPBC;
229+
scb_o->fpf |= scb_s->fpf & FPF_BPBC;
230+
}
231+
226232
/* interrupt intercept */
227233
switch (scb_s->icptcode) {
228234
case ICPT_PROGI:
@@ -265,6 +271,7 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
265271
scb_s->ecb3 = 0;
266272
scb_s->ecd = 0;
267273
scb_s->fac = 0;
274+
scb_s->fpf = 0;
268275

269276
rc = prepare_cpuflags(vcpu, vsie_page);
270277
if (rc)
@@ -324,6 +331,9 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
324331
prefix_unmapped(vsie_page);
325332
scb_s->ecb |= scb_o->ecb & ECB_TE;
326333
}
334+
/* branch prediction */
335+
if (test_kvm_facility(vcpu->kvm, 82))
336+
scb_s->fpf |= scb_o->fpf & FPF_BPBC;
327337
/* SIMD */
328338
if (test_kvm_facility(vcpu->kvm, 129)) {
329339
scb_s->eca |= scb_o->eca & ECA_VX;

include/uapi/linux/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ struct kvm_ppc_resize_hpt {
933933
#define KVM_CAP_HYPERV_VP_INDEX 149
934934
#define KVM_CAP_S390_AIS_MIGRATION 150
935935
#define KVM_CAP_PPC_GET_CPU_CHAR 151
936+
#define KVM_CAP_S390_BPB 152
936937

937938
#ifdef KVM_CAP_IRQ_ROUTING
938939

0 commit comments

Comments
 (0)