From f3cfb875d0fd5f4af40cbb992f436ad396f69a71 Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Thu, 31 Aug 2023 17:36:43 +0200 Subject: s390/zcrypt: update list of EP11 operation modes Add additional operation mode strings into the EP11 operation mode table. These strings are returned by sysfs entries /sys/devices/ap/cardxx/op_modes and /sys/devices/ap/cardxx/xx.yyyy/op_modes. Signed-off-by: Ingo Franzki Reviewed-by: Harald Freudenberger Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/zcrypt_cex4.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 9cfce9ff2e65..5c4532ab0040 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c @@ -279,7 +279,11 @@ static const struct { { 1, "BSI2009" }, { 2, "FIPS2011" }, { 3, "BSI2011" }, + { 4, "SIGG-IMPORT" }, + { 5, "SIGG" }, { 6, "BSICC2017" }, + { 7, "FIPS2021" }, + { 8, "FIPS2024" }, { 0, NULL } }; -- cgit From 0c4d01f3952911b766e6394e0053146c24c98357 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:39:55 +0200 Subject: s390/ctlreg: move control register code to separate file Control register handling has nothing to do with low level SMP code. Move it to a separate file. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp_early_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index dbd5c53d8edf..a191d69573fb 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include -- cgit From ebe1cd530fb2f6450656758bd904cfb5767f8d33 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:39:56 +0200 Subject: s390/ctlreg: rename ctl_reg.h to ctlreg.h Rename ctl_reg.h to ctlreg.h so it matches not only ctlreg.c but also other control register related function, union, and structure names, which all come with a ctlreg prefix. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/char/diag_ftp.c | 2 +- drivers/s390/char/sclp_cmd.c | 2 +- drivers/s390/char/sclp_early.c | 2 +- drivers/s390/char/sclp_early_core.c | 2 +- drivers/s390/cio/crw.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/diag_ftp.c b/drivers/s390/char/diag_ftp.c index 65c7f2d565d8..9418a9270d03 100644 --- a/drivers/s390/char/diag_ftp.c +++ b/drivers/s390/char/diag_ftp.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include "hmcdrv_ftp.h" diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 8b4575a0db9f..b73edf0cd725 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index fdc8668f3fba..60a247fdb2a7 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index a191d69573fb..f7067a70c461 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -6,8 +6,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c index 7b02a6349c4d..58f22270d9c4 100644 --- a/drivers/s390/cio/crw.c +++ b/drivers/s390/cio/crw.c @@ -12,8 +12,8 @@ #include #include #include +#include #include -#include #include "ioasm.h" static DEFINE_MUTEX(crw_handler_mutex); -- cgit From 8d5e98f8d6b11dd0e61323ece3b7ccceea55c281 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:39:58 +0200 Subject: s390/ctlreg: add local and system prefix to some functions Add local and system prefix to some functions to clarify they change control register contents on either the local CPU or the on all CPUs. This results in the following API: Two defines which load and save multiple control registers. The defines correlate with the following C prototypes: void __local_ctl_load(unsigned long *, unsigned int cr_low, unsigned int cr_high); void __local_ctl_store(unsigned long *, unsigned int cr_low, unsigned int cr_high); Two functions which locally set or clear one bit for a specified control register: void local_ctl_set_bit(unsigned int cr, unsigned int bit); void local_ctl_clear_bit(unsigned int cr, unsigned int bit); Two functions which set or clear one bit for a specified control register on all CPUs: void system_ctl_set_bit(unsigned int cr, unsigned int bit); void system_ctl_clear_bit(unsigend int cr, unsigned int bit); Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp.c | 6 +++--- drivers/s390/char/sclp_early_core.c | 6 +++--- drivers/s390/cio/crw.c | 2 +- drivers/s390/cio/isc.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 8f74db689a0c..1ebc60d9cedc 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -732,10 +732,10 @@ sclp_sync_wait(void) /* Enable service-signal interruption, disable timer interrupts */ old_tick = local_tick_disable(); trace_hardirqs_on(); - __ctl_store(cr0, 0, 0); + __local_ctl_store(cr0, 0, 0); cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK; cr0_sync |= 1UL << (63 - 54); - __ctl_load(cr0_sync, 0, 0); + __local_ctl_load(cr0_sync, 0, 0); __arch_local_irq_stosm(0x01); /* Loop until driver state indicates finished request */ while (sclp_running_state != sclp_running_state_idle) { @@ -745,7 +745,7 @@ sclp_sync_wait(void) cpu_relax(); } local_irq_disable(); - __ctl_load(cr0, 0, 0); + __local_ctl_load(cr0, 0, 0); if (!irq_context) _local_bh_enable(); local_tick_enable(old_tick); diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index f7067a70c461..fa5b7d63a254 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -32,11 +32,11 @@ void sclp_early_wait_irq(void) psw_t psw_ext_save, psw_wait; union ctlreg0 cr0, cr0_new; - __ctl_store(cr0.val, 0, 0); + __local_ctl_store(cr0.val, 0, 0); cr0_new.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK; cr0_new.lap = 0; cr0_new.sssm = 1; - __ctl_load(cr0_new.val, 0, 0); + __local_ctl_load(cr0_new.val, 0, 0); psw_ext_save = S390_lowcore.external_new_psw; psw_mask = __extract_psw(); @@ -59,7 +59,7 @@ void sclp_early_wait_irq(void) } while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG); S390_lowcore.external_new_psw = psw_ext_save; - __ctl_load(cr0.val, 0, 0); + __local_ctl_load(cr0.val, 0, 0); } int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb) diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c index 58f22270d9c4..872b1f2855cb 100644 --- a/drivers/s390/cio/crw.c +++ b/drivers/s390/cio/crw.c @@ -156,7 +156,7 @@ static int __init crw_machine_check_init(void) task = kthread_run(crw_collect_info, NULL, "kmcheck"); if (IS_ERR(task)) return PTR_ERR(task); - ctl_set_bit(14, 28); /* enable channel report MCH */ + system_ctl_set_bit(14, 28); /* enable channel report MCH */ return 0; } device_initcall(crw_machine_check_init); diff --git a/drivers/s390/cio/isc.c b/drivers/s390/cio/isc.c index 77fde9f5ea8b..dbc2ac7711e5 100644 --- a/drivers/s390/cio/isc.c +++ b/drivers/s390/cio/isc.c @@ -33,7 +33,7 @@ void isc_register(unsigned int isc) spin_lock(&isc_ref_lock); if (isc_refs[isc] == 0) - ctl_set_bit(6, 31 - isc); + system_ctl_set_bit(6, 31 - isc); isc_refs[isc]++; spin_unlock(&isc_ref_lock); } @@ -61,7 +61,7 @@ void isc_unregister(unsigned int isc) goto out_unlock; } if (isc_refs[isc] == 1) - ctl_clear_bit(6, 31 - isc); + system_ctl_clear_bit(6, 31 - isc); isc_refs[isc]--; out_unlock: spin_unlock(&isc_ref_lock); -- cgit From 2372d391421350e318c98844d21ab9ad16e3eac0 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:40:00 +0200 Subject: s390/ctlreg: use local_ctl_load() and local_ctl_store() where possible Convert all single control register usages of __local_ctl_load() and __local_ctl_store() to local_ctl_load() and local_ctl_store(). This also requires to change the type of some struct lowcore members from __u64 to unsigned long. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp.c | 6 +++--- drivers/s390/char/sclp_early_core.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 1ebc60d9cedc..30a7cd9748fe 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -732,10 +732,10 @@ sclp_sync_wait(void) /* Enable service-signal interruption, disable timer interrupts */ old_tick = local_tick_disable(); trace_hardirqs_on(); - __local_ctl_store(cr0, 0, 0); + local_ctl_store(0, &cr0); cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK; cr0_sync |= 1UL << (63 - 54); - __local_ctl_load(cr0_sync, 0, 0); + local_ctl_load(0, &cr0_sync); __arch_local_irq_stosm(0x01); /* Loop until driver state indicates finished request */ while (sclp_running_state != sclp_running_state_idle) { @@ -745,7 +745,7 @@ sclp_sync_wait(void) cpu_relax(); } local_irq_disable(); - __local_ctl_load(cr0, 0, 0); + local_ctl_load(0, &cr0); if (!irq_context) _local_bh_enable(); local_tick_enable(old_tick); diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index fa5b7d63a254..8cb9fb7098e2 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -32,11 +32,11 @@ void sclp_early_wait_irq(void) psw_t psw_ext_save, psw_wait; union ctlreg0 cr0, cr0_new; - __local_ctl_store(cr0.val, 0, 0); + local_ctl_store(0, &cr0.val); cr0_new.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK; cr0_new.lap = 0; cr0_new.sssm = 1; - __local_ctl_load(cr0_new.val, 0, 0); + local_ctl_load(0, &cr0_new.val); psw_ext_save = S390_lowcore.external_new_psw; psw_mask = __extract_psw(); @@ -59,7 +59,7 @@ void sclp_early_wait_irq(void) } while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG); S390_lowcore.external_new_psw = psw_ext_save; - __local_ctl_load(cr0.val, 0, 0); + local_ctl_load(0, &cr0.val); } int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb) -- cgit From 527618abb92793b9d4dba548d55822dcebd95317 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:40:04 +0200 Subject: s390/ctlreg: add struct ctlreg Add struct ctlreg to enforce strict type checking / usage for control register functions. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp.c | 6 +++--- drivers/s390/char/sclp_early_core.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 30a7cd9748fe..ba9b202c5dee 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -706,8 +706,8 @@ void sclp_sync_wait(void) { unsigned long long old_tick; + struct ctlreg cr0, cr0_sync; unsigned long flags; - unsigned long cr0, cr0_sync; static u64 sync_count; u64 timeout; int irq_context; @@ -733,8 +733,8 @@ sclp_sync_wait(void) old_tick = local_tick_disable(); trace_hardirqs_on(); local_ctl_store(0, &cr0); - cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK; - cr0_sync |= 1UL << (63 - 54); + cr0_sync.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK; + cr0_sync.val |= 1UL << (63 - 54); local_ctl_load(0, &cr0_sync); __arch_local_irq_stosm(0x01); /* Loop until driver state indicates finished request */ diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index 8cb9fb7098e2..9f6165cafdc3 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -32,11 +32,11 @@ void sclp_early_wait_irq(void) psw_t psw_ext_save, psw_wait; union ctlreg0 cr0, cr0_new; - local_ctl_store(0, &cr0.val); + local_ctl_store(0, &cr0.reg); cr0_new.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK; cr0_new.lap = 0; cr0_new.sssm = 1; - local_ctl_load(0, &cr0_new.val); + local_ctl_load(0, &cr0_new.reg); psw_ext_save = S390_lowcore.external_new_psw; psw_mask = __extract_psw(); @@ -59,7 +59,7 @@ void sclp_early_wait_irq(void) } while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG); S390_lowcore.external_new_psw = psw_ext_save; - local_ctl_load(0, &cr0.val); + local_ctl_load(0, &cr0.reg); } int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb) -- cgit From 99441a38c391b1115e405d1f47ede237fca37f1b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 11 Sep 2023 21:40:13 +0200 Subject: s390: use control register bit defines Use control register bit defines instead of plain numbers where possible. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/cio/crw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c index 872b1f2855cb..4916dd0a7eb1 100644 --- a/drivers/s390/cio/crw.c +++ b/drivers/s390/cio/crw.c @@ -156,7 +156,7 @@ static int __init crw_machine_check_init(void) task = kthread_run(crw_collect_info, NULL, "kmcheck"); if (IS_ERR(task)) return PTR_ERR(task); - system_ctl_set_bit(14, 28); /* enable channel report MCH */ + system_ctl_set_bit(14, CR14_CHANNEL_REPORT_SUBMASK_BIT); return 0; } device_initcall(crw_machine_check_init); -- cgit From 32d1d9204f8db3360be55e65bd182a1a68f93308 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Tue, 12 Sep 2023 09:54:25 +0200 Subject: s390/ap: re-init AP queues on config on On a state toggle from config off to config on and on the state toggle from checkstop to not checkstop the queue's internal states was set but the state machine was not nudged. This did not care as on the first enqueue of a request the state machine kick ran. However, within an Secure Execution guest a queue is only chosen by the scheduler when it has been bound. But to bind a queue, it needs to run through the initial states (reset, enable interrupts, ...). So this is like a chicken-and-egg problem and the result was in fact that a queue was unusable after a config off/on toggle. With some slight rework of the handling of these states now the new function _ap_queue_init_state() is called which is the core of the ap_queue_init_state() function but without locking handling. This has the benefit that it can be called on all the places where a (re-)init of the AP queue's state machine is needed. Fixes: 2d72eaf036d2 ("s390/ap: implement SE AP bind, unbind and associate") Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/ap_bus.c | 21 ++++++++++----------- drivers/s390/crypto/ap_bus.h | 1 + drivers/s390/crypto/ap_queue.c | 9 +++++++-- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 339812efe822..d09e08b71cfb 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1865,15 +1865,18 @@ static inline void ap_scan_domains(struct ap_card *ac) } /* get it and thus adjust reference counter */ get_device(dev); - if (decfg) + if (decfg) { AP_DBF_INFO("%s(%d,%d) new (decfg) queue dev created\n", __func__, ac->id, dom); - else if (chkstop) + } else if (chkstop) { AP_DBF_INFO("%s(%d,%d) new (chkstop) queue dev created\n", __func__, ac->id, dom); - else + } else { + /* nudge the queue's state machine */ + ap_queue_init_state(aq); AP_DBF_INFO("%s(%d,%d) new queue dev created\n", __func__, ac->id, dom); + } goto put_dev_and_continue; } /* handle state changes on already existing queue device */ @@ -1895,10 +1898,8 @@ static inline void ap_scan_domains(struct ap_card *ac) } else if (!chkstop && aq->chkstop) { /* checkstop off */ aq->chkstop = false; - if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { - aq->dev_state = AP_DEV_STATE_OPERATING; - aq->sm_state = AP_SM_STATE_RESET_START; - } + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) + _ap_queue_init_state(aq); spin_unlock_bh(&aq->lock); AP_DBF_DBG("%s(%d,%d) queue dev checkstop off\n", __func__, ac->id, dom); @@ -1922,10 +1923,8 @@ static inline void ap_scan_domains(struct ap_card *ac) } else if (!decfg && !aq->config) { /* config on this queue device */ aq->config = true; - if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { - aq->dev_state = AP_DEV_STATE_OPERATING; - aq->sm_state = AP_SM_STATE_RESET_START; - } + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) + _ap_queue_init_state(aq); spin_unlock_bh(&aq->lock); AP_DBF_DBG("%s(%d,%d) queue dev config on\n", __func__, ac->id, dom); diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index be54b070c031..3e34912a6050 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -287,6 +287,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); void ap_queue_prepare_remove(struct ap_queue *aq); void ap_queue_remove(struct ap_queue *aq); void ap_queue_init_state(struct ap_queue *aq); +void _ap_queue_init_state(struct ap_queue *aq); struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, int comp_type, unsigned int functions, int ml); diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 1336e632adc4..2943b2529d3a 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -1160,14 +1160,19 @@ void ap_queue_remove(struct ap_queue *aq) spin_unlock_bh(&aq->lock); } -void ap_queue_init_state(struct ap_queue *aq) +void _ap_queue_init_state(struct ap_queue *aq) { - spin_lock_bh(&aq->lock); aq->dev_state = AP_DEV_STATE_OPERATING; aq->sm_state = AP_SM_STATE_RESET_START; aq->last_err_rc = 0; aq->assoc_idx = ASSOC_IDX_INVALID; ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); +} + +void ap_queue_init_state(struct ap_queue *aq) +{ + spin_lock_bh(&aq->lock); + _ap_queue_init_state(aq); spin_unlock_bh(&aq->lock); } EXPORT_SYMBOL(ap_queue_init_state); -- cgit From a19a161482b1739c2207861d086403389dc1bd47 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Tue, 12 Sep 2023 10:08:51 +0200 Subject: s390/zcrypt: introduce new internal AP queue se_bound attribute This patch introduces a new AP queue internal attribute se_bound which reflects the bound state of an APQN within a Secure Execution environment. With introduction of Secure Execution guests now an AP firmware queue needs to be bound to the guest before usage. This patch introduces a new internal attribute reflecting this bound state and some glue code to handle this new field during lifetime of an AP queue device. Together with that now the zcrypt scheduler considers the state of the AP queues when a message is about to be distributed among the existing queues. There is a new function ap_queue_usable() which returns true only when all conditions for using this AP queue device are fulfilled. In details this means: the AP queue needs to be configured, not checkstopped and within an SE environment it needs to be bound. So the new function gives and indication if the AP queue device is ready to serve requests or not. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/ap_bus.h | 2 ++ drivers/s390/crypto/ap_queue.c | 49 +++++++++++++++++++++++++++++++++++++++- drivers/s390/crypto/zcrypt_api.c | 10 ++++---- 3 files changed, 55 insertions(+), 6 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 3e34912a6050..359a35f894d5 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -207,6 +207,7 @@ struct ap_queue { bool chkstop; /* checkstop state */ ap_qid_t qid; /* AP queue id. */ bool interrupt; /* indicate if interrupts are enabled */ + bool se_bound; /* SE bound state */ unsigned int assoc_idx; /* SE association index */ int queue_count; /* # messages currently on AP queue. */ int pendingq_count; /* # requests on pendingq list. */ @@ -271,6 +272,7 @@ enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event); int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg); void ap_cancel_message(struct ap_queue *aq, struct ap_message *ap_msg); void ap_flush_queue(struct ap_queue *aq); +bool ap_queue_usable(struct ap_queue *aq); void *ap_airq_ptr(void); int ap_sb_available(void); diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 2943b2529d3a..993240370ecf 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -33,6 +33,11 @@ static inline bool ap_q_supports_assoc(struct ap_queue *aq) return ap_test_bit(&aq->card->functions, AP_FUNC_EP11); } +static inline bool ap_q_needs_bind(struct ap_queue *aq) +{ + return ap_q_supports_bind(aq) && ap_sb_available(); +} + /** * ap_queue_enable_irq(): Enable interrupt support on this AP queue. * @aq: The AP queue @@ -304,6 +309,7 @@ static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) aq->sm_state = AP_SM_STATE_RESET_WAIT; aq->interrupt = false; aq->rapq_fbit = 0; + aq->se_bound = false; return AP_SM_WAIT_LOW_TIMEOUT; default: aq->dev_state = AP_DEV_STATE_ERROR; @@ -868,7 +874,12 @@ static ssize_t se_bind_store(struct device *dev, } status = ap_bapq(aq->qid); spin_unlock_bh(&aq->lock); - if (status.response_code) { + if (!status.response_code) { + aq->se_bound = true; + AP_DBF_INFO("%s bapq(0x%02x.%04x) success\n", __func__, + AP_QID_CARD(aq->qid), + AP_QID_QUEUE(aq->qid)); + } else { AP_DBF_WARN("%s RC 0x%02x on bapq(0x%02x.%04x)\n", __func__, status.response_code, AP_QID_CARD(aq->qid), @@ -1073,6 +1084,42 @@ int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) } EXPORT_SYMBOL(ap_queue_message); +/** + * ap_queue_usable(): Check if queue is usable just now. + * @aq: The AP queue device to test for usability. + * This function is intended for the scheduler to query if it makes + * sense to enqueue a message into this AP queue device by calling + * ap_queue_message(). The perspective is very short-term as the + * state machine and device state(s) may change at any time. + */ +bool ap_queue_usable(struct ap_queue *aq) +{ + bool rc = true; + + spin_lock_bh(&aq->lock); + + /* check for not configured or checkstopped */ + if (!aq->config || aq->chkstop) { + rc = false; + goto unlock_and_out; + } + + /* device state needs to be ok */ + if (aq->dev_state != AP_DEV_STATE_OPERATING) { + rc = false; + goto unlock_and_out; + } + + /* SE guest's queues additionally need to be bound */ + if (ap_q_needs_bind(aq) && !aq->se_bound) + rc = false; + +unlock_and_out: + spin_unlock_bh(&aq->lock); + return rc; +} +EXPORT_SYMBOL(ap_queue_usable); + /** * ap_cancel_message(): Cancel a crypto request. * @aq: The AP device that has the message queued diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index ce04caa7913f..dcd6c7299fa9 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -693,7 +693,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms, for_each_zcrypt_queue(zq, zc) { /* check if device is usable and eligible */ if (!zq->online || !zq->ops->rsa_modexpo || - !zq->queue->config || zq->queue->chkstop) + !ap_queue_usable(zq->queue)) continue; /* check if device node has admission for this queue */ if (!zcrypt_check_queue(perms, @@ -798,7 +798,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms, for_each_zcrypt_queue(zq, zc) { /* check if device is usable and eligible */ if (!zq->online || !zq->ops->rsa_modexpo_crt || - !zq->queue->config || zq->queue->chkstop) + !ap_queue_usable(zq->queue)) continue; /* check if device node has admission for this queue */ if (!zcrypt_check_queue(perms, @@ -916,7 +916,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms, for_each_zcrypt_queue(zq, zc) { /* check for device usable and eligible */ if (!zq->online || !zq->ops->send_cprb || - !zq->queue->config || zq->queue->chkstop || + !ap_queue_usable(zq->queue) || (tdom != AUTOSEL_DOM && tdom != AP_QID_QUEUE(zq->queue->qid))) continue; @@ -1087,7 +1087,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms, for_each_zcrypt_queue(zq, zc) { /* check if device is usable and eligible */ if (!zq->online || !zq->ops->send_ep11_cprb || - !zq->queue->config || zq->queue->chkstop || + !ap_queue_usable(zq->queue) || (targets && !is_desired_ep11_queue(zq->queue->qid, target_num, targets))) @@ -1186,7 +1186,7 @@ static long zcrypt_rng(char *buffer) for_each_zcrypt_queue(zq, zc) { /* check if device is usable and eligible */ if (!zq->online || !zq->ops->rng || - !zq->queue->config || zq->queue->chkstop) + !ap_queue_usable(zq->queue)) continue; if (!zcrypt_queue_compare(zq, pref_zq, wgt, pref_wgt)) continue; -- cgit From 8d6be876bbd7c09190b025ccc478260f5a40c216 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Tue, 12 Sep 2023 09:02:07 +0200 Subject: s390/ap: show APFS value on error reply 0x8B With Secure Execution the error reply RX 0x8B now carries an APFS value indicating why the request has been filtered by a lower layer of the firmware. So display this value as a warning line in the s390 debug feature trace. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/zcrypt_error.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/crypto/zcrypt_error.h b/drivers/s390/crypto/zcrypt_error.h index d36177e65a3d..a44fcfcec938 100644 --- a/drivers/s390/crypto/zcrypt_error.h +++ b/drivers/s390/crypto/zcrypt_error.h @@ -98,8 +98,22 @@ static inline int convert_error(struct zcrypt_queue *zq, case REP88_ERROR_MESSAGE_MALFORMD: /* 0x22 */ case REP88_ERROR_KEY_TYPE: /* 0x34 */ /* RY indicates malformed request */ - ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => rc=EINVAL\n", - __func__, card, queue, ehdr->reply_code); + if (ehdr->reply_code == REP82_ERROR_FILTERED_BY_HYPERVISOR && + ehdr->type == TYPE86_RSP_CODE) { + struct { + struct type86_hdr hdr; + struct type86_fmt2_ext fmt2; + } __packed * head = reply->msg; + unsigned int apfs = *((u32 *)head->fmt2.apfs); + + ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x apfs=0x%x => rc=EINVAL\n", + __func__, card, queue, + ehdr->reply_code, apfs); + } else { + ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => rc=EINVAL\n", + __func__, card, queue, + ehdr->reply_code); + } return -EINVAL; case REP82_ERROR_MACHINE_FAILURE: /* 0x10 */ case REP82_ERROR_MESSAGE_TYPE: /* 0x20 */ -- cgit From e3f4170ccf20ebe2985b8e166184dd2d54220b60 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Fri, 29 Sep 2023 19:12:04 +0200 Subject: s390/sclp: handle default case in sclp memory notifier When new memory notifier types are added in common code and unimplemented on s390, return success instead of EINVAL return code. This prevents breakage when new memory notifier types are added. Reviewed-by: Heiko Carstens Signed-off-by: Sumanth Korikkar Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp_cmd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index b73edf0cd725..11c428f4c7cf 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -353,7 +353,6 @@ static int sclp_mem_notifier(struct notifier_block *nb, sclp_mem_change_state(start, size, 0); break; default: - rc = -EINVAL; break; } mutex_unlock(&sclp_mem_mutex); -- cgit From f48781d220ee6bb59816383237bf0abd1c65c493 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Aug 2023 15:11:18 +0200 Subject: s390/cio: export CMG value as decimal Change format of the "cmg" sysfs attribute from hex to decimal to make it easier to consume. Note that this should not break any existing users since only values 2 and 3 are currently exported. Also the main user already assumes decimal notation [1]. [1] https://sourceforge.net/p/sblim/gather/ci/master/tree/plugin/metriczCH.c Reviewed-by: Vineeth Vijayan Signed-off-by: Peter Oberparleiter Signed-off-by: Vasily Gorbik --- drivers/s390/cio/chp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 5440f285f349..675d7ed82356 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -334,7 +334,7 @@ static ssize_t chp_cmg_show(struct device *dev, struct device_attribute *attr, return 0; if (chp->cmg == -1) /* channel measurements not available */ return sprintf(buf, "unknown\n"); - return sprintf(buf, "%x\n", chp->cmg); + return sprintf(buf, "%d\n", chp->cmg); } static DEVICE_ATTR(cmg, 0444, chp_cmg_show, NULL); -- cgit From e78002aa9a5a9eaf18bc29ccaef7f405616fd68e Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 18 Aug 2023 15:14:02 +0200 Subject: s390/cio: fix virtual vs physical address confusion Fix virtual vs physical address confusion (which currently are the same). Reviewed-by: Vineeth Vijayan Signed-off-by: Peter Oberparleiter Signed-off-by: Vasily Gorbik --- drivers/s390/cio/chsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 0abd77f4b664..cc6dc5076ffc 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -881,8 +881,8 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) secm_area->request.code = 0x0016; secm_area->key = PAGE_DEFAULT_KEY >> 4; - secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1; - secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2; + secm_area->cub_addr1 = virt_to_phys(css->cub_addr1); + secm_area->cub_addr2 = virt_to_phys(css->cub_addr2); secm_area->operation_code = enable ? 0 : 1; -- cgit From e37988bcd1fddb726cf08e4f04a1b8dc4a2f80aa Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Mon, 23 Oct 2023 19:14:49 +0000 Subject: s390/sclp: replace deprecated strncpy with strtomem Let's move away from using strncpy() as it is deprecated [1]. Instead use strtomem() as `e.id` is already marked as nonstring: | char id[4] __nonstring; We don't need strtomem_pad() because `e` is already memset to 0 -- rendering any additional NUL-padding useless. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] Link: https://github.com/KSPP/linux/issues/90 Cc: linux-hardening@vger.kernel.org Signed-off-by: Justin Stitt Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20231023-strncpy-drivers-s390-char-sclp-c-v1-1-eaeef80522bb@google.com Signed-off-by: Vasily Gorbik --- drivers/s390/char/sclp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index ba9b202c5dee..d53ee34d398f 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -81,7 +81,7 @@ static inline void sclp_trace(int prio, char *id, u32 a, u64 b, bool err) struct sclp_trace_entry e; memset(&e, 0, sizeof(e)); - strncpy(e.id, id, sizeof(e.id)); + strtomem(e.id, id); e.a = a; e.b = b; debug_event(&sclp_debug, prio, &e, sizeof(e)); -- cgit From 991a211aa99f468cd291a97b8dcb448ebc77f6c4 Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Mon, 23 Oct 2023 19:24:38 +0000 Subject: s390/cio: replace deprecated strncpy with strscpy strncpy() is deprecated for use on NUL-terminated destination strings [1] and as such we should prefer more robust and less ambiguous string interfaces. We expect both `params` and `id` to be NUL-terminated based on their usage with format strings: format_node_data(iuparams, iunodeid, &lir->incident_node); format_node_data(auparams, aunodeid, &lir->attached_node); switch (lir->iq.class) { case LIR_IQ_CLASS_DEGRADED: pr_warn("Link degraded: RS=%02x RSID=%04x IC=%02x " "IUPARAMS=%s IUNODEID=%s AUPARAMS=%s AUNODEID=%s\n", sei_area->rs, sei_area->rsid, lir->ic, iuparams, iunodeid, auparams, aunodeid); NUL-padding is not required as both `params` and `id` have been memset to 0: memset(params, 0, PARAMS_LEN); memset(id, 0, NODEID_LEN); Considering the above, a suitable replacement is `strscpy` [2] due to the fact that it guarantees NUL-termination on the destination buffer without unnecessarily NUL-padding. Note that there's no overread bugs in the current implementation as the string literal "n/a" has a size much smaller than PARAMS_LEN or NODEID_LEN. Nonetheless, let's favor strscpy(). Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2] Link: https://github.com/KSPP/linux/issues/90 Cc: linux-hardening@vger.kernel.org Signed-off-by: Justin Stitt Reviewed-by: Vineeth Vijayan Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20231023-strncpy-drivers-s390-cio-chsc-c-v1-1-8b76a7b83260@google.com Signed-off-by: Vasily Gorbik --- drivers/s390/cio/chsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index cc6dc5076ffc..f8b04ce61556 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -393,8 +393,8 @@ static void format_node_data(char *params, char *id, struct node_descriptor *nd) memset(id, 0, NODEID_LEN); if (nd->validity != ND_VALIDITY_VALID) { - strncpy(params, "n/a", PARAMS_LEN - 1); - strncpy(id, "n/a", NODEID_LEN - 1); + strscpy(params, "n/a", PARAMS_LEN); + strscpy(id, "n/a", NODEID_LEN); return; } -- cgit