Skip to content

Commit 55d09dd

Browse files
committed
Merge branch 'apv11' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kernelorgnext
2 parents af4bf6c + 492a6be commit 55d09dd

File tree

15 files changed

+2380
-60
lines changed

15 files changed

+2380
-60
lines changed

Documentation/s390/vfio-ap.txt

Lines changed: 837 additions & 0 deletions
Large diffs are not rendered by default.

MAINTAINERS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12668,6 +12668,18 @@ W: http://www.ibm.com/developerworks/linux/linux390/
1266812668
S: Supported
1266912669
F: drivers/s390/crypto/
1267012670

12671+
S390 VFIO AP DRIVER
12672+
M: Tony Krowiak <akrowiak@linux.ibm.com>
12673+
M: Pierre Morel <pmorel@linux.ibm.com>
12674+
M: Halil Pasic <pasic@linux.ibm.com>
12675+
L: linux-s390@vger.kernel.org
12676+
W: http://www.ibm.com/developerworks/linux/linux390/
12677+
S: Supported
12678+
F: drivers/s390/crypto/vfio_ap_drv.c
12679+
F: drivers/s390/crypto/vfio_ap_private.h
12680+
F: drivers/s390/crypto/vfio_ap_ops.c
12681+
F: Documentation/s390/vfio-ap.txt
12682+
1267112683
S390 ZFCP DRIVER
1267212684
M: Steffen Maier <maier@linux.ibm.com>
1267312685
M: Benjamin Block <bblock@linux.ibm.com>

arch/s390/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,17 @@ config VFIO_CCW
773773
To compile this driver as a module, choose M here: the
774774
module will be called vfio_ccw.
775775

776+
config VFIO_AP
777+
def_tristate n
778+
prompt "VFIO support for AP devices"
779+
depends on S390_AP_IOMMU && VFIO_MDEV_DEVICE && KVM
780+
help
781+
This driver grants access to Adjunct Processor (AP) devices
782+
via the VFIO mediated device interface.
783+
784+
To compile this driver as a module, choose M here: the module
785+
will be called vfio_ap.
786+
776787
endmenu
777788

778789
menu "Dump support"

arch/s390/include/asm/kvm_host.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define KVM_REQ_ICPT_OPEREXC KVM_ARCH_REQ(2)
4545
#define KVM_REQ_START_MIGRATION KVM_ARCH_REQ(3)
4646
#define KVM_REQ_STOP_MIGRATION KVM_ARCH_REQ(4)
47+
#define KVM_REQ_VSIE_RESTART KVM_ARCH_REQ(5)
4748

4849
#define SIGP_CTRL_C 0x80
4950
#define SIGP_CTRL_SCN_MASK 0x3f
@@ -186,6 +187,7 @@ struct kvm_s390_sie_block {
186187
#define ECA_AIV 0x00200000
187188
#define ECA_VX 0x00020000
188189
#define ECA_PROTEXCI 0x00002000
190+
#define ECA_APIE 0x00000008
189191
#define ECA_SII 0x00000001
190192
__u32 eca; /* 0x004c */
191193
#define ICPT_INST 0x04
@@ -259,6 +261,8 @@ struct kvm_s390_sie_block {
259261
__u8 reservede4[4]; /* 0x00e4 */
260262
__u64 tecmc; /* 0x00e8 */
261263
__u8 reservedf0[12]; /* 0x00f0 */
264+
#define CRYCB_FORMAT_MASK 0x00000003
265+
#define CRYCB_FORMAT0 0x00000000
262266
#define CRYCB_FORMAT1 0x00000001
263267
#define CRYCB_FORMAT2 0x00000003
264268
__u32 crycbd; /* 0x00fc */
@@ -719,6 +723,7 @@ struct kvm_s390_crypto {
719723
__u32 crycbd;
720724
__u8 aes_kw;
721725
__u8 dea_kw;
726+
__u8 apie;
722727
};
723728

724729
#define APCB0_MASK_SIZE 1
@@ -859,6 +864,8 @@ void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu,
859864
void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
860865
struct kvm_async_pf *work);
861866

867+
void kvm_arch_crypto_clear_masks(struct kvm *kvm);
868+
862869
extern int sie64a(struct kvm_s390_sie_block *, u64 *);
863870
extern char sie_exit;
864871

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ struct kvm_s390_vm_cpu_subfunc {
160160
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
161161
#define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2
162162
#define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3
163+
#define KVM_S390_VM_CRYPTO_ENABLE_APIE 4
164+
#define KVM_S390_VM_CRYPTO_DISABLE_APIE 5
163165

164166
/* kvm attributes for migration mode */
165167
#define KVM_S390_VM_MIGRATION_STOP 0

arch/s390/kvm/kvm-s390.c

Lines changed: 91 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <asm/sclp.h>
4141
#include <asm/cpacf.h>
4242
#include <asm/timex.h>
43+
#include <asm/ap.h>
4344
#include "kvm-s390.h"
4445
#include "gaccess.h"
4546

@@ -844,45 +845,67 @@ void kvm_s390_vcpu_crypto_reset_all(struct kvm *kvm)
844845

845846
kvm_s390_vcpu_block_all(kvm);
846847

847-
kvm_for_each_vcpu(i, vcpu, kvm)
848+
kvm_for_each_vcpu(i, vcpu, kvm) {
848849
kvm_s390_vcpu_crypto_setup(vcpu);
850+
/* recreate the shadow crycb by leaving the VSIE handler */
851+
kvm_s390_sync_request(KVM_REQ_VSIE_RESTART, vcpu);
852+
}
849853

850854
kvm_s390_vcpu_unblock_all(kvm);
851855
}
852856

853857
static int kvm_s390_vm_set_crypto(struct kvm *kvm, struct kvm_device_attr *attr)
854858
{
855-
if (!test_kvm_facility(kvm, 76))
856-
return -EINVAL;
857-
858859
mutex_lock(&kvm->lock);
859860
switch (attr->attr) {
860861
case KVM_S390_VM_CRYPTO_ENABLE_AES_KW:
862+
if (!test_kvm_facility(kvm, 76))
863+
return -EINVAL;
861864
get_random_bytes(
862865
kvm->arch.crypto.crycb->aes_wrapping_key_mask,
863866
sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
864867
kvm->arch.crypto.aes_kw = 1;
865868
VM_EVENT(kvm, 3, "%s", "ENABLE: AES keywrapping support");
866869
break;
867870
case KVM_S390_VM_CRYPTO_ENABLE_DEA_KW:
871+
if (!test_kvm_facility(kvm, 76))
872+
return -EINVAL;
868873
get_random_bytes(
869874
kvm->arch.crypto.crycb->dea_wrapping_key_mask,
870875
sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
871876
kvm->arch.crypto.dea_kw = 1;
872877
VM_EVENT(kvm, 3, "%s", "ENABLE: DEA keywrapping support");
873878
break;
874879
case KVM_S390_VM_CRYPTO_DISABLE_AES_KW:
880+
if (!test_kvm_facility(kvm, 76))
881+
return -EINVAL;
875882
kvm->arch.crypto.aes_kw = 0;
876883
memset(kvm->arch.crypto.crycb->aes_wrapping_key_mask, 0,
877884
sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
878885
VM_EVENT(kvm, 3, "%s", "DISABLE: AES keywrapping support");
879886
break;
880887
case KVM_S390_VM_CRYPTO_DISABLE_DEA_KW:
888+
if (!test_kvm_facility(kvm, 76))
889+
return -EINVAL;
881890
kvm->arch.crypto.dea_kw = 0;
882891
memset(kvm->arch.crypto.crycb->dea_wrapping_key_mask, 0,
883892
sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
884893
VM_EVENT(kvm, 3, "%s", "DISABLE: DEA keywrapping support");
885894
break;
895+
case KVM_S390_VM_CRYPTO_ENABLE_APIE:
896+
if (!ap_instructions_available()) {
897+
mutex_unlock(&kvm->lock);
898+
return -EOPNOTSUPP;
899+
}
900+
kvm->arch.crypto.apie = 1;
901+
break;
902+
case KVM_S390_VM_CRYPTO_DISABLE_APIE:
903+
if (!ap_instructions_available()) {
904+
mutex_unlock(&kvm->lock);
905+
return -EOPNOTSUPP;
906+
}
907+
kvm->arch.crypto.apie = 0;
908+
break;
886909
default:
887910
mutex_unlock(&kvm->lock);
888911
return -ENXIO;
@@ -1491,6 +1514,10 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
14911514
case KVM_S390_VM_CRYPTO_DISABLE_DEA_KW:
14921515
ret = 0;
14931516
break;
1517+
case KVM_S390_VM_CRYPTO_ENABLE_APIE:
1518+
case KVM_S390_VM_CRYPTO_DISABLE_APIE:
1519+
ret = ap_instructions_available() ? 0 : -ENXIO;
1520+
break;
14941521
default:
14951522
ret = -ENXIO;
14961523
break;
@@ -1992,55 +2019,60 @@ long kvm_arch_vm_ioctl(struct file *filp,
19922019
return r;
19932020
}
19942021

1995-
static int kvm_s390_query_ap_config(u8 *config)
1996-
{
1997-
u32 fcn_code = 0x04000000UL;
1998-
u32 cc = 0;
1999-
2000-
memset(config, 0, 128);
2001-
asm volatile(
2002-
"lgr 0,%1\n"
2003-
"lgr 2,%2\n"
2004-
".long 0xb2af0000\n" /* PQAP(QCI) */
2005-
"0: ipm %0\n"
2006-
"srl %0,28\n"
2007-
"1:\n"
2008-
EX_TABLE(0b, 1b)
2009-
: "+r" (cc)
2010-
: "r" (fcn_code), "r" (config)
2011-
: "cc", "0", "2", "memory"
2012-
);
2013-
2014-
return cc;
2015-
}
2016-
20172022
static int kvm_s390_apxa_installed(void)
20182023
{
2019-
u8 config[128];
2020-
int cc;
2021-
2022-
if (test_facility(12)) {
2023-
cc = kvm_s390_query_ap_config(config);
2024+
struct ap_config_info info;
20242025

2025-
if (cc)
2026-
pr_err("PQAP(QCI) failed with cc=%d", cc);
2027-
else
2028-
return config[0] & 0x40;
2026+
if (ap_instructions_available()) {
2027+
if (ap_qci(&info) == 0)
2028+
return info.apxa;
20292029
}
20302030

20312031
return 0;
20322032
}
20332033

2034+
/*
2035+
* The format of the crypto control block (CRYCB) is specified in the 3 low
2036+
* order bits of the CRYCB designation (CRYCBD) field as follows:
2037+
* Format 0: Neither the message security assist extension 3 (MSAX3) nor the
2038+
* AP extended addressing (APXA) facility are installed.
2039+
* Format 1: The APXA facility is not installed but the MSAX3 facility is.
2040+
* Format 2: Both the APXA and MSAX3 facilities are installed
2041+
*/
20342042
static void kvm_s390_set_crycb_format(struct kvm *kvm)
20352043
{
20362044
kvm->arch.crypto.crycbd = (__u32)(unsigned long) kvm->arch.crypto.crycb;
20372045

2046+
/* Clear the CRYCB format bits - i.e., set format 0 by default */
2047+
kvm->arch.crypto.crycbd &= ~(CRYCB_FORMAT_MASK);
2048+
2049+
/* Check whether MSAX3 is installed */
2050+
if (!test_kvm_facility(kvm, 76))
2051+
return;
2052+
20382053
if (kvm_s390_apxa_installed())
20392054
kvm->arch.crypto.crycbd |= CRYCB_FORMAT2;
20402055
else
20412056
kvm->arch.crypto.crycbd |= CRYCB_FORMAT1;
20422057
}
20432058

2059+
void kvm_arch_crypto_clear_masks(struct kvm *kvm)
2060+
{
2061+
mutex_lock(&kvm->lock);
2062+
kvm_s390_vcpu_block_all(kvm);
2063+
2064+
memset(&kvm->arch.crypto.crycb->apcb0, 0,
2065+
sizeof(kvm->arch.crypto.crycb->apcb0));
2066+
memset(&kvm->arch.crypto.crycb->apcb1, 0,
2067+
sizeof(kvm->arch.crypto.crycb->apcb1));
2068+
2069+
/* recreate the shadow crycb for each vcpu */
2070+
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_VSIE_RESTART);
2071+
kvm_s390_vcpu_unblock_all(kvm);
2072+
mutex_unlock(&kvm->lock);
2073+
}
2074+
EXPORT_SYMBOL_GPL(kvm_arch_crypto_clear_masks);
2075+
20442076
static u64 kvm_s390_get_initial_cpuid(void)
20452077
{
20462078
struct cpuid cpuid;
@@ -2052,12 +2084,12 @@ static u64 kvm_s390_get_initial_cpuid(void)
20522084

20532085
static void kvm_s390_crypto_init(struct kvm *kvm)
20542086
{
2055-
if (!test_kvm_facility(kvm, 76))
2056-
return;
2057-
20582087
kvm->arch.crypto.crycb = &kvm->arch.sie_page2->crycb;
20592088
kvm_s390_set_crycb_format(kvm);
20602089

2090+
if (!test_kvm_facility(kvm, 76))
2091+
return;
2092+
20612093
/* Enable AES/DEA protected key functions by default */
20622094
kvm->arch.crypto.aes_kw = 1;
20632095
kvm->arch.crypto.dea_kw = 1;
@@ -2583,17 +2615,25 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
25832615

25842616
static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
25852617
{
2586-
if (!test_kvm_facility(vcpu->kvm, 76))
2618+
/*
2619+
* If the AP instructions are not being interpreted and the MSAX3
2620+
* facility is not configured for the guest, there is nothing to set up.
2621+
*/
2622+
if (!vcpu->kvm->arch.crypto.apie && !test_kvm_facility(vcpu->kvm, 76))
25872623
return;
25882624

2625+
vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd;
25892626
vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA);
2627+
vcpu->arch.sie_block->eca &= ~ECA_APIE;
25902628

2629+
if (vcpu->kvm->arch.crypto.apie)
2630+
vcpu->arch.sie_block->eca |= ECA_APIE;
2631+
2632+
/* Set up protected key support */
25912633
if (vcpu->kvm->arch.crypto.aes_kw)
25922634
vcpu->arch.sie_block->ecb3 |= ECB3_AES;
25932635
if (vcpu->kvm->arch.crypto.dea_kw)
25942636
vcpu->arch.sie_block->ecb3 |= ECB3_DEA;
2595-
2596-
vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd;
25972637
}
25982638

25992639
void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu)
@@ -2770,18 +2810,25 @@ static void kvm_s390_vcpu_request(struct kvm_vcpu *vcpu)
27702810
exit_sie(vcpu);
27712811
}
27722812

2813+
bool kvm_s390_vcpu_sie_inhibited(struct kvm_vcpu *vcpu)
2814+
{
2815+
return atomic_read(&vcpu->arch.sie_block->prog20) &
2816+
(PROG_BLOCK_SIE | PROG_REQUEST);
2817+
}
2818+
27732819
static void kvm_s390_vcpu_request_handled(struct kvm_vcpu *vcpu)
27742820
{
27752821
atomic_andnot(PROG_REQUEST, &vcpu->arch.sie_block->prog20);
27762822
}
27772823

27782824
/*
2779-
* Kick a guest cpu out of SIE and wait until SIE is not running.
2825+
* Kick a guest cpu out of (v)SIE and wait until (v)SIE is not running.
27802826
* If the CPU is not running (e.g. waiting as idle) the function will
27812827
* return immediately. */
27822828
void exit_sie(struct kvm_vcpu *vcpu)
27832829
{
27842830
kvm_s390_set_cpuflags(vcpu, CPUSTAT_STOP_INT);
2831+
kvm_s390_vsie_kick(vcpu);
27852832
while (vcpu->arch.sie_block->prog0c & PROG_IN_SIE)
27862833
cpu_relax();
27872834
}
@@ -3198,6 +3245,8 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
31983245

31993246
/* nothing to do, just clear the request */
32003247
kvm_clear_request(KVM_REQ_UNHALT, vcpu);
3248+
/* we left the vsie handler, nothing to do, just clear the request */
3249+
kvm_clear_request(KVM_REQ_VSIE_RESTART, vcpu);
32013250

32023251
return 0;
32033252
}

arch/s390/kvm/kvm-s390.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu);
290290
void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu);
291291
void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu);
292292
void kvm_s390_vcpu_unblock(struct kvm_vcpu *vcpu);
293+
bool kvm_s390_vcpu_sie_inhibited(struct kvm_vcpu *vcpu);
293294
void exit_sie(struct kvm_vcpu *vcpu);
294295
void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu);
295296
int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu);

0 commit comments

Comments
 (0)