From d12292fdea21f9f4ae5865fd41b730c5e32d45a9 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Wed, 19 Jan 2022 23:44:32 +0100 Subject: s390/sysinfo: add variable capacity information If available, add machine variable capacity information to /proc/sysinfo Acked-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/sysinfo.h | 4 ++++ arch/s390/kernel/sysinfo.c | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index ab1c6316055c..edca5a751df4 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h @@ -40,6 +40,10 @@ struct sysinfo_1_1_1 { unsigned int ncr; unsigned int npr; unsigned int ntr; + char reserved_3[4]; + char model_var_cap[16]; + unsigned int model_var_cap_rating; + unsigned int nvr; }; struct sysinfo_1_2_1 { diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index b5e364358ce4..f6f8f498c9be 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -81,10 +81,12 @@ static bool convert_ext_name(unsigned char encoding, char *name, size_t len) static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) { + bool has_var_cap; int i; if (stsi(info, 1, 1, 1)) return; + has_var_cap = !!info->model_var_cap[0]; EBCASC(info->manufacturer, sizeof(info->manufacturer)); EBCASC(info->type, sizeof(info->type)); EBCASC(info->model, sizeof(info->model)); @@ -93,6 +95,8 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) EBCASC(info->model_capacity, sizeof(info->model_capacity)); EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap)); EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap)); + if (has_var_cap) + EBCASC(info->model_var_cap, sizeof(info->model_var_cap)); seq_printf(m, "Manufacturer: %-16.16s\n", info->manufacturer); seq_printf(m, "Type: %-4.4s\n", info->type); if (info->lic) @@ -120,12 +124,18 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) seq_printf(m, "Model Temp. Capacity: %-16.16s %08u\n", info->model_temp_cap, info->model_temp_cap_rating); + if (has_var_cap && info->model_var_cap_rating) + seq_printf(m, "Model Var. Capacity: %-16.16s %08u\n", + info->model_var_cap, + info->model_var_cap_rating); if (info->ncr) seq_printf(m, "Nominal Cap. Rating: %08u\n", info->ncr); if (info->npr) seq_printf(m, "Nominal Perm. Rating: %08u\n", info->npr); if (info->ntr) seq_printf(m, "Nominal Temp. Rating: %08u\n", info->ntr); + if (has_var_cap && info->nvr) + seq_printf(m, "Nominal Var. Rating: %08u\n", info->nvr); if (info->cai) { seq_printf(m, "Capacity Adj. Ind.: %d\n", info->cai); seq_printf(m, "Capacity Ch. Reason: %d\n", info->ccr); -- cgit v1.2.3 From 65f8780e2d70257200547b5a7654974aa7c37ce1 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Sun, 16 Jul 2023 10:56:00 +0200 Subject: s390/boot: always align vmalloc area on segment boundary The size of vmalloc area depends from various factors on boot and could be set to: 1. Default size as determined by VMALLOC_DEFAULT_SIZE macro; 2. One half of the virtual address space not occupied by modules and fixed mappings; 3. The size provided by user with vmalloc= kernel command line parameter; In cases [1] and [2] the vmalloc area base address is aligned on Region3 table type boundary, while in case [3] in might get aligned on page boundary. Limit the waste of page tables and always align vmalloc area size and base address on segment boundary. Acked-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/boot/ipl_parm.c | 2 +- arch/s390/boot/startup.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index 2ab4872fbee1..b24de9aabf7d 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -274,7 +274,7 @@ void parse_boot_command_line(void) memory_limit = round_down(memparse(val, NULL), PAGE_SIZE); if (!strcmp(param, "vmalloc") && val) { - vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); + vmalloc_size = round_up(memparse(val, NULL), _SEGMENT_SIZE); vmalloc_size_set = 1; } diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 8104e0e3d188..9cc76e631759 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -255,7 +255,8 @@ static unsigned long setup_kernel_memory_layout(void) VMALLOC_END = MODULES_VADDR; /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ - vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); + vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE); + vmalloc_size = min(vmalloc_size, vsize); VMALLOC_START = VMALLOC_END - vmalloc_size; /* split remaining virtual space between 1:1 mapping & vmemmap array */ -- cgit v1.2.3 From 7b2d039da622daa9ba259ac6f38701d542b237c3 Mon Sep 17 00:00:00 2001 From: Anthony Krowiak Date: Thu, 9 Nov 2023 11:44:20 -0500 Subject: s390/vfio-ap: unpin pages on gisc registration failure In the vfio_ap_irq_enable function, after the page containing the notification indicator byte (NIB) is pinned, the function attempts to register the guest ISC. If registration fails, the function sets the status response code and returns without unpinning the page containing the NIB. In order to avoid a memory leak, the NIB should be unpinned before returning from the vfio_ap_irq_enable function. Co-developed-by: Janosch Frank Signed-off-by: Janosch Frank Signed-off-by: Anthony Krowiak Reviewed-by: Matthew Rosato Fixes: 783f0a3ccd79 ("s390/vfio-ap: add s390dbf logging to the vfio_ap_irq_enable function") Cc: Link: https://lore.kernel.org/r/20231109164427.460493-2-akrowiak@linux.ibm.com Signed-off-by: Alexander Gordeev --- drivers/s390/crypto/vfio_ap_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 4db538a55192..9cb28978c186 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -457,6 +457,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q, VFIO_AP_DBF_WARN("%s: gisc registration failed: nisc=%d, isc=%d, apqn=%#04x\n", __func__, nisc, isc, q->apqn); + vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1); status.response_code = AP_RESPONSE_INVALID_GISA; return status; } -- cgit v1.2.3 From 3746d48c55aced92c8fc1cbb432600da3e47344c Mon Sep 17 00:00:00 2001 From: Anthony Krowiak Date: Thu, 9 Nov 2023 11:44:21 -0500 Subject: s390/vfio-ap: set status response code to 06 on gisc registration failure The interception handler for the PQAP(AQIC) command calls the kvm_s390_gisc_register function to register the guest ISC with the channel subsystem. If that call fails, the status response code 08 - indicating Invalid ZONE/GISA designation - is returned to the guest. This response code is not valid because setting the ZONE/GISA values is the responsibility of the hypervisor controlling the guest and there is nothing that can be done from the guest perspective to correct that problem. The likelihood of GISC registration failure is nil and there is no status response code to indicate an invalid ISC value, so let's set the response code to 06 indicating 'Invalid address of AP-queue notification byte'. While this is not entirely accurate, it is better than setting a response code which makes no sense for the guest. Signed-off-by: Anthony Krowiak Suggested-by: Halil Pasic Reviewed-by: Halil Pasic Reviewed-by: Harald Freudenberger Link: https://lore.kernel.org/r/20231109164427.460493-3-akrowiak@linux.ibm.com Signed-off-by: Alexander Gordeev --- drivers/s390/crypto/vfio_ap_ops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 9cb28978c186..25d7ce2094f8 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -393,8 +393,8 @@ static int ensure_nib_shared(unsigned long addr, struct gmap *gmap) * Register the guest ISC to GIB interface and retrieve the * host ISC to issue the host side PQAP/AQIC * - * Response.status may be set to AP_RESPONSE_INVALID_ADDRESS in case the - * vfio_pin_pages failed. + * status.response_code may be set to AP_RESPONSE_INVALID_ADDRESS in case the + * vfio_pin_pages or kvm_s390_gisc_register failed. * * Otherwise return the ap_queue_status returned by the ap_aqic(), * all retry handling will be done by the guest. @@ -458,7 +458,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q, __func__, nisc, isc, q->apqn); vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1); - status.response_code = AP_RESPONSE_INVALID_GISA; + status.response_code = AP_RESPONSE_INVALID_ADDRESS; return status; } -- cgit v1.2.3 From c44ce579240d8025da74c6328295aa0a75a581a3 Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Thu, 9 Nov 2023 11:44:22 -0500 Subject: s390/vfio-ap: improve reaction to response code 07 from PQAP(AQIC) command Let's improve the vfio_ap driver's reaction to reception of response code 07 from the PQAP(AQIC) command when enabling interrupts on behalf of a guest: * Unregister the guest's ISC before the pages containing the notification indicator bytes are unpinned. * Capture the return code from the kvm_s390_gisc_unregister function and log a DBF warning if it fails. Suggested-by: Matthew Rosato Signed-off-by: Tony Krowiak Reviewed-by: Matthew Rosato Link: https://lore.kernel.org/r/20231109164427.460493-4-akrowiak@linux.ibm.com Signed-off-by: Alexander Gordeev --- drivers/s390/crypto/vfio_ap_ops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 25d7ce2094f8..4e80c211ba47 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -476,8 +476,11 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q, break; case AP_RESPONSE_OTHERWISE_CHANGED: /* We could not modify IRQ settings: clear new configuration */ + ret = kvm_s390_gisc_unregister(kvm, isc); + if (ret) + VFIO_AP_DBF_WARN("%s: kvm_s390_gisc_unregister: rc=%d isc=%d, apqn=%#04x\n", + __func__, ret, isc, q->apqn); vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1); - kvm_s390_gisc_unregister(kvm, isc); break; default: pr_warn("%s: apqn %04x: response: %02x\n", __func__, q->apqn, -- cgit v1.2.3 From a0d8f4eeb7c4ffaee21702bcc91a09b3988c5b7a Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Wed, 8 Nov 2023 15:11:30 -0500 Subject: s390/vfio-ap: fix sysfs status attribute for AP queue devices The 'status' attribute for AP queue devices bound to the vfio_ap device driver displays incorrect status when the mediated device is attached to a guest, but the queue device is not passed through. In the current implementation, the status displayed is 'in_use' which is not correct; it should be 'assigned'. This can happen if one of the queue devices associated with a given adapter is not bound to the vfio_ap device driver. For example: Queues listed in /sys/bus/ap/drivers/vfio_ap: 14.0005 14.0006 14.000d 16.0006 16.000d Queues listed in /sys/devices/vfio_ap/matrix/$UUID/matrix 14.0005 14.0006 14.000d 16.0005 16.0006 16.000d Queues listed in /sys/devices/vfio_ap/matrix/$UUID/guest_matrix 14.0005 14.0006 14.000d The reason no queues for adapter 0x16 are listed in the guest_matrix is because queue 16.0005 is not bound to the vfio_ap device driver, so no queue associated with the adapter is passed through to the guest; therefore, each queue device for adapter 0x16 should display 'assigned' instead of 'in_use', because those queues are not in use by a guest, but only assigned to the mediated device. Let's check the AP configuration for the guest to determine whether a queue device is passed through before displaying a status of 'in_use'. Signed-off-by: Tony Krowiak Acked-by: Halil Pasic Acked-by: Harald Freudenberger Link: https://lore.kernel.org/r/20231108201135.351419-1-akrowiak@linux.ibm.com Signed-off-by: Alexander Gordeev --- drivers/s390/crypto/vfio_ap_ops.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 4e80c211ba47..0d1adc7d730d 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -1980,6 +1980,7 @@ static ssize_t status_show(struct device *dev, { ssize_t nchars = 0; struct vfio_ap_queue *q; + unsigned long apid, apqi; struct ap_matrix_mdev *matrix_mdev; struct ap_device *apdev = to_ap_dev(dev); @@ -1987,8 +1988,21 @@ static ssize_t status_show(struct device *dev, q = dev_get_drvdata(&apdev->device); matrix_mdev = vfio_ap_mdev_for_queue(q); + /* If the queue is assigned to the matrix mediated device, then + * determine whether it is passed through to a guest; otherwise, + * indicate that it is unassigned. + */ if (matrix_mdev) { - if (matrix_mdev->kvm) + apid = AP_QID_CARD(q->apqn); + apqi = AP_QID_QUEUE(q->apqn); + /* + * If the queue is passed through to the guest, then indicate + * that it is in use; otherwise, indicate that it is + * merely assigned to a matrix mediated device. + */ + if (matrix_mdev->kvm && + test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && + test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) nchars = scnprintf(buf, PAGE_SIZE, "%s\n", AP_QUEUE_IN_USE); else -- cgit v1.2.3 From d4c53ae8e4948f7f733f24cd863da31c8e9379a7 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Sat, 4 Nov 2023 10:04:31 +0100 Subject: s390/ap: store TAPQ hwinfo in struct ap_card As of now the AP card struct held only part of the queue's hwinfo (that is the GR2 register content returned with an TAPQ invocation). This patch reworks struct ap_card to hold the whole hwinfo now. As there is a nice bit field union on top of this ap_tapq_hwinfo struct, all the ugly bit checkings can now get replaced by simple evaluations of the required bit field. Suggested-by: Ingo Franzki Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/ap.h | 21 +++++++----- drivers/s390/crypto/ap_bus.c | 69 ++++++++++++++++++--------------------- drivers/s390/crypto/ap_bus.h | 20 +++--------- drivers/s390/crypto/ap_card.c | 18 +++++----- drivers/s390/crypto/ap_queue.c | 33 +++++++++---------- drivers/s390/crypto/vfio_ap_ops.c | 2 +- drivers/s390/crypto/zcrypt_api.c | 16 ++++----- drivers/s390/crypto/zcrypt_cex4.c | 31 +++++++++--------- 8 files changed, 95 insertions(+), 115 deletions(-) diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h index 40c2b82f083a..43ac4a64f49b 100644 --- a/arch/s390/include/asm/ap.h +++ b/arch/s390/include/asm/ap.h @@ -88,7 +88,7 @@ static inline bool ap_instructions_available(void) } /* TAPQ register GR2 response struct */ -struct ap_tapq_gr2 { +struct ap_tapq_hwinfo { union { unsigned long value; struct { @@ -96,11 +96,13 @@ struct ap_tapq_gr2 { unsigned int apinfo : 32; /* ap type, ... */ }; struct { - unsigned int s : 1; /* APSC */ - unsigned int m : 1; /* AP4KM */ - unsigned int c : 1; /* AP4KC */ - unsigned int mode : 3; - unsigned int n : 1; /* APXA */ + unsigned int apsc : 1; /* APSC */ + unsigned int mex4k : 1; /* AP4KM */ + unsigned int crt4k : 1; /* AP4KC */ + unsigned int cca : 1; /* D */ + unsigned int accel : 1; /* A */ + unsigned int ep11 : 1; /* X */ + unsigned int apxa : 1; /* APXA */ unsigned int : 1; unsigned int class : 8; unsigned int bs : 2; /* SE bind/assoc */ @@ -126,11 +128,12 @@ struct ap_tapq_gr2 { /** * ap_tapq(): Test adjunct processor queue. * @qid: The AP queue number - * @info: Pointer to queue descriptor + * @info: Pointer to tapq hwinfo struct * * Returns AP queue status structure. */ -static inline struct ap_queue_status ap_tapq(ap_qid_t qid, struct ap_tapq_gr2 *info) +static inline struct ap_queue_status ap_tapq(ap_qid_t qid, + struct ap_tapq_hwinfo *info) { union ap_queue_status_reg reg1; unsigned long reg2; @@ -158,7 +161,7 @@ static inline struct ap_queue_status ap_tapq(ap_qid_t qid, struct ap_tapq_gr2 *i * Returns AP queue status structure. */ static inline struct ap_queue_status ap_test_queue(ap_qid_t qid, int tbit, - struct ap_tapq_gr2 *info) + struct ap_tapq_hwinfo *info) { if (tbit) qid |= 1UL << 23; /* set T bit*/ diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5dd33155d5d5..20396eccb33b 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -357,13 +357,12 @@ EXPORT_SYMBOL(ap_test_config_ctrl_domain); * -1 invalid APQN, TAPQ error or AP queue status which * indicates there is no APQN. */ -static int ap_queue_info(ap_qid_t qid, int *q_type, unsigned int *q_fac, - int *q_depth, int *q_ml, bool *q_decfg, bool *q_cstop) +static int ap_queue_info(ap_qid_t qid, struct ap_tapq_hwinfo *hwinfo, + bool *decfg, bool *cstop) { struct ap_queue_status status; - struct ap_tapq_gr2 tapq_info; - tapq_info.value = 0; + hwinfo->value = 0; /* make sure we don't run into a specifiation exception */ if (AP_QID_CARD(qid) > ap_max_adapter_id || @@ -371,7 +370,7 @@ static int ap_queue_info(ap_qid_t qid, int *q_type, unsigned int *q_fac, return -1; /* call TAPQ on this APQN */ - status = ap_test_queue(qid, ap_apft_available(), &tapq_info); + status = ap_test_queue(qid, ap_apft_available(), hwinfo); switch (status.response_code) { case AP_RESPONSE_NORMAL: @@ -389,15 +388,11 @@ static int ap_queue_info(ap_qid_t qid, int *q_type, unsigned int *q_fac, } /* There should be at least one of the mode bits set */ - if (WARN_ON_ONCE(!tapq_info.value)) + if (WARN_ON_ONCE(!hwinfo->value)) return 0; - *q_type = tapq_info.at; - *q_fac = tapq_info.fac; - *q_depth = tapq_info.qd; - *q_ml = tapq_info.ml; - *q_decfg = status.response_code == AP_RESPONSE_DECONFIGURED; - *q_cstop = status.response_code == AP_RESPONSE_CHECKSTOPPED; + *decfg = status.response_code == AP_RESPONSE_DECONFIGURED; + *cstop = status.response_code == AP_RESPONSE_CHECKSTOPPED; return 1; } @@ -642,11 +637,11 @@ static int ap_uevent(const struct device *dev, struct kobj_uevent_env *env) return rc; /* Add MODE= */ - if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) + if (ac->hwinfo.accel) rc = add_uevent_var(env, "MODE=accel"); - else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) + else if (ac->hwinfo.cca) rc = add_uevent_var(env, "MODE=cca"); - else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) + else if (ac->hwinfo.ep11) rc = add_uevent_var(env, "MODE=ep11"); if (rc) return rc; @@ -654,11 +649,11 @@ static int ap_uevent(const struct device *dev, struct kobj_uevent_env *env) struct ap_queue *aq = to_ap_queue(&ap_dev->device); /* Add MODE= */ - if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) + if (aq->card->hwinfo.accel) rc = add_uevent_var(env, "MODE=accel"); - else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) + else if (aq->card->hwinfo.cca) rc = add_uevent_var(env, "MODE=cca"); - else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) + else if (aq->card->hwinfo.ep11) rc = add_uevent_var(env, "MODE=ep11"); if (rc) return rc; @@ -1799,12 +1794,12 @@ static inline void ap_scan_rm_card_dev_and_queue_devs(struct ap_card *ac) */ static inline void ap_scan_domains(struct ap_card *ac) { - int rc, dom, depth, type, ml; + struct ap_tapq_hwinfo hwinfo; bool decfg, chkstop; struct ap_queue *aq; struct device *dev; - unsigned int func; ap_qid_t qid; + int rc, dom; /* * Go through the configuration for the domains and compare them @@ -1827,8 +1822,7 @@ static inline void ap_scan_domains(struct ap_card *ac) goto put_dev_and_continue; } /* domain is valid, get info from this APQN */ - rc = ap_queue_info(qid, &type, &func, &depth, - &ml, &decfg, &chkstop); + rc = ap_queue_info(qid, &hwinfo, &decfg, &chkstop); switch (rc) { case -1: if (dev) { @@ -1955,11 +1949,11 @@ put_dev_and_continue: */ static inline void ap_scan_adapter(int ap) { - int rc, dom, depth, type, comp_type, ml; + struct ap_tapq_hwinfo hwinfo; + int rc, dom, comp_type; bool decfg, chkstop; struct ap_card *ac; struct device *dev; - unsigned int func; ap_qid_t qid; /* Is there currently a card device for this adapter ? */ @@ -1989,8 +1983,7 @@ static inline void ap_scan_adapter(int ap) for (dom = 0; dom <= ap_max_domain_id; dom++) if (ap_test_config_usage_domain(dom)) { qid = AP_MKQID(ap, dom); - if (ap_queue_info(qid, &type, &func, &depth, - &ml, &decfg, &chkstop) > 0) + if (ap_queue_info(qid, &hwinfo, &decfg, &chkstop) > 0) break; } if (dom > ap_max_domain_id) { @@ -2006,7 +1999,7 @@ static inline void ap_scan_adapter(int ap) } return; } - if (!type) { + if (!hwinfo.at) { /* No apdater type info available, an unusable adapter */ if (ac) { AP_DBF_INFO("%s(%d) no valid type (0) info, rm card and queue devs\n", @@ -2019,18 +2012,18 @@ static inline void ap_scan_adapter(int ap) } return; } + hwinfo.value &= TAPQ_CARD_HWINFO_MASK; /* filter card specific hwinfo */ if (ac) { /* Check APQN against existing card device for changes */ - if (ac->raw_hwtype != type) { + if (ac->hwinfo.at != hwinfo.at) { AP_DBF_INFO("%s(%d) hwtype %d changed, rm card and queue devs\n", - __func__, ap, type); + __func__, ap, hwinfo.at); ap_scan_rm_card_dev_and_queue_devs(ac); put_device(dev); ac = NULL; - } else if ((ac->functions & TAPQ_CARD_FUNC_CMP_MASK) != - (func & TAPQ_CARD_FUNC_CMP_MASK)) { + } else if (ac->hwinfo.fac != hwinfo.fac) { AP_DBF_INFO("%s(%d) functions 0x%08x changed, rm card and queue devs\n", - __func__, ap, func); + __func__, ap, hwinfo.fac); ap_scan_rm_card_dev_and_queue_devs(ac); put_device(dev); ac = NULL; @@ -2064,13 +2057,13 @@ static inline void ap_scan_adapter(int ap) if (!ac) { /* Build a new card device */ - comp_type = ap_get_compatible_type(qid, type, func); + comp_type = ap_get_compatible_type(qid, hwinfo.at, hwinfo.fac); if (!comp_type) { AP_DBF_WARN("%s(%d) type %d, can't get compatibility type\n", - __func__, ap, type); + __func__, ap, hwinfo.at); return; } - ac = ap_card_create(ap, depth, type, comp_type, func, ml); + ac = ap_card_create(ap, hwinfo, comp_type); if (!ac) { AP_DBF_WARN("%s(%d) ap_card_create() failed\n", __func__, ap); @@ -2101,13 +2094,13 @@ static inline void ap_scan_adapter(int ap) get_device(dev); if (decfg) AP_DBF_INFO("%s(%d) new (decfg) card dev type=%d func=0x%08x created\n", - __func__, ap, type, func); + __func__, ap, hwinfo.at, hwinfo.fac); else if (chkstop) AP_DBF_INFO("%s(%d) new (chkstop) card dev type=%d func=0x%08x created\n", - __func__, ap, type, func); + __func__, ap, hwinfo.at, hwinfo.fac); else AP_DBF_INFO("%s(%d) new card dev type=%d func=0x%08x created\n", - __func__, ap, type, func); + __func__, ap, hwinfo.at, hwinfo.fac); } /* Verify the domains and the queue devices for this card */ diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index b0771ca0849b..cc256424f70b 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -75,16 +75,6 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) #define AP_DEVICE_TYPE_CEX7 13 #define AP_DEVICE_TYPE_CEX8 14 -/* - * Known function facilities - */ -#define AP_FUNC_MEX4K 1 -#define AP_FUNC_CRT4K 2 -#define AP_FUNC_COPRO 3 -#define AP_FUNC_ACCEL 4 -#define AP_FUNC_EP11 5 -#define AP_FUNC_APXA 6 - /* * AP queue state machine states */ @@ -182,9 +172,7 @@ struct ap_device { struct ap_card { struct ap_device ap_dev; - int raw_hwtype; /* AP raw hardware type. */ - unsigned int functions; /* TAPQ GR2 upper 32 facility bits */ - int queue_depth; /* AP queue depth.*/ + struct ap_tapq_hwinfo hwinfo; /* TAPQ GR2 content */ int id; /* AP card number. */ unsigned int maxmsgsize; /* AP msg limit for this card */ bool config; /* configured state */ @@ -192,7 +180,7 @@ struct ap_card { atomic64_t total_request_count; /* # requests ever for this AP device.*/ }; -#define TAPQ_CARD_FUNC_CMP_MASK 0xFFFF0000 +#define TAPQ_CARD_HWINFO_MASK 0xFEFF0000FFFF0F0FUL #define ASSOC_IDX_INVALID 0x10000 #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) @@ -290,8 +278,8 @@ 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); +struct ap_card *ap_card_create(int id, struct ap_tapq_hwinfo info, + int comp_type); #define APMASKSIZE (BITS_TO_LONGS(AP_DEVICES) * sizeof(unsigned long)) #define AQMASKSIZE (BITS_TO_LONGS(AP_DOMAINS) * sizeof(unsigned long)) diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index b2bd477659a7..ce953cbbd564 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -34,7 +34,7 @@ static ssize_t raw_hwtype_show(struct device *dev, { struct ap_card *ac = to_ap_card(dev); - return sysfs_emit(buf, "%d\n", ac->raw_hwtype); + return sysfs_emit(buf, "%d\n", ac->hwinfo.at); } static DEVICE_ATTR_RO(raw_hwtype); @@ -44,7 +44,7 @@ static ssize_t depth_show(struct device *dev, struct device_attribute *attr, { struct ap_card *ac = to_ap_card(dev); - return sysfs_emit(buf, "%d\n", ac->queue_depth); + return sysfs_emit(buf, "%d\n", ac->hwinfo.qd); } static DEVICE_ATTR_RO(depth); @@ -54,7 +54,7 @@ static ssize_t ap_functions_show(struct device *dev, { struct ap_card *ac = to_ap_card(dev); - return sysfs_emit(buf, "0x%08X\n", ac->functions); + return sysfs_emit(buf, "0x%08X\n", ac->hwinfo.fac); } static DEVICE_ATTR_RO(ap_functions); @@ -229,8 +229,8 @@ static void ap_card_device_release(struct device *dev) kfree(ac); } -struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, - int comp_type, unsigned int functions, int ml) +struct ap_card *ap_card_create(int id, struct ap_tapq_hwinfo hwinfo, + int comp_type) { struct ap_card *ac; @@ -240,12 +240,10 @@ struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, ac->ap_dev.device.release = ap_card_device_release; ac->ap_dev.device.type = &ap_card_type; ac->ap_dev.device_type = comp_type; - ac->raw_hwtype = raw_type; - ac->queue_depth = queue_depth; - ac->functions = functions; + ac->hwinfo = hwinfo; ac->id = id; - ac->maxmsgsize = ml > 0 ? - ml * AP_TAPQ_ML_FIELD_CHUNK_SIZE : AP_DEFAULT_MAX_MSG_SIZE; + ac->maxmsgsize = hwinfo.ml > 0 ? + hwinfo.ml * AP_TAPQ_ML_FIELD_CHUNK_SIZE : AP_DEFAULT_MAX_MSG_SIZE; return ac; } diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 3934a0cc13e7..39f250f1f1c3 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -24,13 +24,12 @@ static void __ap_flush_queue(struct ap_queue *aq); static inline bool ap_q_supports_bind(struct ap_queue *aq) { - return ap_test_bit(&aq->card->functions, AP_FUNC_EP11) || - ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL); + return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; } static inline bool ap_q_supports_assoc(struct ap_queue *aq) { - return ap_test_bit(&aq->card->functions, AP_FUNC_EP11); + return aq->card->hwinfo.ep11; } static inline bool ap_q_needs_bind(struct ap_queue *aq) @@ -257,7 +256,7 @@ static enum ap_sm_wait ap_sm_write(struct ap_queue *aq) list_move_tail(&ap_msg->list, &aq->pendingq); aq->requestq_count--; aq->pendingq_count++; - if (aq->queue_count < aq->card->queue_depth) { + if (aq->queue_count < aq->card->hwinfo.qd) { aq->sm_state = AP_SM_STATE_WORKING; return AP_SM_WAIT_AGAIN; } @@ -421,9 +420,9 @@ static enum ap_sm_wait ap_sm_setirq_wait(struct ap_queue *aq) static enum ap_sm_wait ap_sm_assoc_wait(struct ap_queue *aq) { struct ap_queue_status status; - struct ap_tapq_gr2 info; + struct ap_tapq_hwinfo hwinfo; - status = ap_test_queue(aq->qid, 1, &info); + status = ap_test_queue(aq->qid, 1, &hwinfo); /* handle asynchronous error on this queue */ if (status.async && status.response_code) { aq->dev_state = AP_DEV_STATE_ERROR; @@ -443,7 +442,7 @@ static enum ap_sm_wait ap_sm_assoc_wait(struct ap_queue *aq) } /* check bs bits */ - switch (info.bs) { + switch (hwinfo.bs) { case AP_BS_Q_USABLE: /* association is through */ aq->sm_state = AP_SM_STATE_IDLE; @@ -460,7 +459,7 @@ static enum ap_sm_wait ap_sm_assoc_wait(struct ap_queue *aq) aq->dev_state = AP_DEV_STATE_ERROR; aq->last_err_rc = status.response_code; AP_DBF_WARN("%s bs 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", - __func__, info.bs, + __func__, hwinfo.bs, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return AP_SM_WAIT_NONE; } @@ -687,9 +686,9 @@ static ssize_t ap_functions_show(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_queue_status status; - struct ap_tapq_gr2 info; + struct ap_tapq_hwinfo hwinfo; - status = ap_test_queue(aq->qid, 1, &info); + status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { AP_DBF_DBG("%s RC 0x%02x on tapq(0x%02x.%04x)\n", __func__, status.response_code, @@ -697,7 +696,7 @@ static ssize_t ap_functions_show(struct device *dev, return -EIO; } - return sysfs_emit(buf, "0x%08X\n", info.fac); + return sysfs_emit(buf, "0x%08X\n", hwinfo.fac); } static DEVICE_ATTR_RO(ap_functions); @@ -840,19 +839,19 @@ static ssize_t se_bind_show(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_queue_status status; - struct ap_tapq_gr2 info; + struct ap_tapq_hwinfo hwinfo; if (!ap_q_supports_bind(aq)) return sysfs_emit(buf, "-\n"); - status = ap_test_queue(aq->qid, 1, &info); + status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { AP_DBF_DBG("%s RC 0x%02x on tapq(0x%02x.%04x)\n", __func__, status.response_code, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return -EIO; } - switch (info.bs) { + switch (hwinfo.bs) { case AP_BS_Q_USABLE: case AP_BS_Q_USABLE_NO_SECURE_KEY: return sysfs_emit(buf, "bound\n"); @@ -920,12 +919,12 @@ static ssize_t se_associate_show(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_queue_status status; - struct ap_tapq_gr2 info; + struct ap_tapq_hwinfo hwinfo; if (!ap_q_supports_assoc(aq)) return sysfs_emit(buf, "-\n"); - status = ap_test_queue(aq->qid, 1, &info); + status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { AP_DBF_DBG("%s RC 0x%02x on tapq(0x%02x.%04x)\n", __func__, status.response_code, @@ -933,7 +932,7 @@ static ssize_t se_associate_show(struct device *dev, return -EIO; } - switch (info.bs) { + switch (hwinfo.bs) { case AP_BS_Q_USABLE: if (aq->assoc_idx == ASSOC_IDX_INVALID) { AP_DBF_WARN("%s AP_BS_Q_USABLE but invalid assoc_idx\n", __func__); diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 0d1adc7d730d..243d252bc631 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -2315,7 +2315,7 @@ static void vfio_ap_filter_apid_by_qtype(unsigned long *apm, unsigned long *aqm) bool apid_cleared; struct ap_queue_status status; unsigned long apid, apqi; - struct ap_tapq_gr2 info; + struct ap_tapq_hwinfo info; for_each_set_bit_inv(apid, apm, AP_DEVICES) { apid_cleared = false; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index dcd6c7299fa9..74200f54dfff 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -673,7 +673,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms, for_each_zcrypt_card(zc) { /* Check for usable accelerator or CCA card */ if (!zc->online || !zc->card->config || zc->card->chkstop || - !(zc->card->functions & 0x18000000)) + !(zc->card->hwinfo.accel || zc->card->hwinfo.cca)) continue; /* Check for size limits */ if (zc->min_mod_size > mex->inputdatalength || @@ -778,7 +778,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms, for_each_zcrypt_card(zc) { /* Check for usable accelerator or CCA card */ if (!zc->online || !zc->card->config || zc->card->chkstop || - !(zc->card->functions & 0x18000000)) + !(zc->card->hwinfo.accel || zc->card->hwinfo.cca)) continue; /* Check for size limits */ if (zc->min_mod_size > crt->inputdatalength || @@ -893,7 +893,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms, for_each_zcrypt_card(zc) { /* Check for usable CCA card */ if (!zc->online || !zc->card->config || zc->card->chkstop || - !(zc->card->functions & 0x10000000)) + !zc->card->hwinfo.cca) continue; /* Check for user selected CCA card */ if (xcrb->user_defined != AUTOSELECT && @@ -1064,7 +1064,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms, for_each_zcrypt_card(zc) { /* Check for usable EP11 card */ if (!zc->online || !zc->card->config || zc->card->chkstop || - !(zc->card->functions & 0x04000000)) + !zc->card->hwinfo.ep11) continue; /* Check for user selected EP11 card */ if (targets && @@ -1177,7 +1177,7 @@ static long zcrypt_rng(char *buffer) for_each_zcrypt_card(zc) { /* Check for usable CCA card */ if (!zc->online || !zc->card->config || zc->card->chkstop || - !(zc->card->functions & 0x10000000)) + !zc->card->hwinfo.cca) continue; /* get weight index of the card device */ wgt = zc->speed_rating[func_code]; @@ -1238,7 +1238,7 @@ static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus) queue = AP_QID_QUEUE(zq->queue->qid); stat = &devstatus[card * AP_DOMAINS + queue]; stat->hwtype = zc->card->ap_dev.device_type; - stat->functions = zc->card->functions >> 26; + stat->functions = zc->card->hwinfo.fac >> 26; stat->qid = zq->queue->qid; stat->online = zq->online ? 0x01 : 0x00; } @@ -1263,7 +1263,7 @@ void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus) queue = AP_QID_QUEUE(zq->queue->qid); stat = &devstatus[card * AP_DOMAINS + queue]; stat->hwtype = zc->card->ap_dev.device_type; - stat->functions = zc->card->functions >> 26; + stat->functions = zc->card->hwinfo.fac >> 26; stat->qid = zq->queue->qid; stat->online = zq->online ? 0x01 : 0x00; } @@ -1286,7 +1286,7 @@ int zcrypt_device_status_ext(int card, int queue, if (card == AP_QID_CARD(zq->queue->qid) && queue == AP_QID_QUEUE(zq->queue->qid)) { devstat->hwtype = zc->card->ap_dev.device_type; - devstat->functions = zc->card->functions >> 26; + devstat->functions = zc->card->hwinfo.fac >> 26; devstat->qid = zq->queue->qid; devstat->online = zq->online ? 0x01 : 0x00; spin_unlock(&zcrypt_list_lock); diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 5c4532ab0040..64df7d2f6266 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c @@ -477,7 +477,7 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) return -ENOMEM; zc->card = ac; dev_set_drvdata(&ap_dev->device, zc); - if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) { + if (ac->hwinfo.accel) { if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) { zc->type_string = "CEX4A"; zc->user_space_type = ZCRYPT_CEX4; @@ -506,8 +506,7 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) zc->user_space_type = ZCRYPT_CEX6; } zc->min_mod_size = CEX4A_MIN_MOD_SIZE; - if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) && - ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) { + if (ac->hwinfo.mex4k && ac->hwinfo.crt4k) { zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K; zc->max_exp_bit_length = CEX4A_MAX_MOD_SIZE_4K; @@ -516,7 +515,7 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) zc->max_exp_bit_length = CEX4A_MAX_MOD_SIZE_2K; } - } else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) { + } else if (ac->hwinfo.cca) { if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) { zc->type_string = "CEX4C"; zc->speed_rating = CEX4C_SPEED_IDX; @@ -556,7 +555,7 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) zc->min_mod_size = CEX4C_MIN_MOD_SIZE; zc->max_mod_size = CEX4C_MAX_MOD_SIZE; zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; - } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) { + } else if (ac->hwinfo.ep11) { if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) { zc->type_string = "CEX4P"; zc->user_space_type = ZCRYPT_CEX4; @@ -599,14 +598,14 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) return rc; } - if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) { + if (ac->hwinfo.cca) { rc = sysfs_create_group(&ap_dev->device.kobj, &cca_card_attr_grp); if (rc) { zcrypt_card_unregister(zc); zcrypt_card_free(zc); } - } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) { + } else if (ac->hwinfo.ep11) { rc = sysfs_create_group(&ap_dev->device.kobj, &ep11_card_attr_grp); if (rc) { @@ -627,9 +626,9 @@ static void zcrypt_cex4_card_remove(struct ap_device *ap_dev) struct zcrypt_card *zc = dev_get_drvdata(&ap_dev->device); struct ap_card *ac = to_ap_card(&ap_dev->device); - if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) + if (ac->hwinfo.cca) sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp); - else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) + else if (ac->hwinfo.ep11) sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp); zcrypt_card_unregister(zc); @@ -654,19 +653,19 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev) struct zcrypt_queue *zq; int rc; - if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) { + if (aq->card->hwinfo.accel) { zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT); - } else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { + } else if (aq->card->hwinfo.cca) { zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; zq->ops = zcrypt_msgtype(MSGTYPE06_NAME, MSGTYPE06_VARIANT_DEFAULT); - } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) { + } else if (aq->card->hwinfo.ep11) { zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; @@ -689,14 +688,14 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev) return rc; } - if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { + if (aq->card->hwinfo.cca) { rc = sysfs_create_group(&ap_dev->device.kobj, &cca_queue_attr_grp); if (rc) { zcrypt_queue_unregister(zq); zcrypt_queue_free(zq); } - } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) { + } else if (aq->card->hwinfo.ep11) { rc = sysfs_create_group(&ap_dev->device.kobj, &ep11_queue_attr_grp); if (rc) { @@ -717,9 +716,9 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev) struct zcrypt_queue *zq = dev_get_drvdata(&ap_dev->device); struct ap_queue *aq = to_ap_queue(&ap_dev->device); - if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) + if (aq->card->hwinfo.cca) sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp); - else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) + else if (aq->card->hwinfo.ep11) sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp); zcrypt_queue_unregister(zq); -- cgit v1.2.3 From 207022d39d3b158ca3581e321212f799fa5e7e24 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Thu, 9 Nov 2023 11:24:20 +0100 Subject: s390/ap: handle outband SE bind state change This patch addresses some weird scenarios where an outband manipulation of the SE bind state of a queue assigned and maybe in use by an SE guest with AP pass-through support took place. So for example when the guest has bound and associated a queue and then this domain has been zeroed on the service element. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Alexander Gordeev --- drivers/s390/crypto/ap_bus.c | 3 + drivers/s390/crypto/ap_bus.h | 2 +- drivers/s390/crypto/ap_queue.c | 167 +++++++++++++++++++++++++++++------------ 3 files changed, 122 insertions(+), 50 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 20396eccb33b..f46dd6abacd7 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1847,6 +1847,7 @@ static inline void ap_scan_domains(struct ap_card *ac) aq->card = ac; aq->config = !decfg; aq->chkstop = chkstop; + aq->se_bstate = hwinfo.bs; dev = &aq->ap_dev.device; dev->bus = &ap_bus_type; dev->parent = &ac->ap_dev.device; @@ -1876,6 +1877,8 @@ static inline void ap_scan_domains(struct ap_card *ac) } /* handle state changes on already existing queue device */ spin_lock_bh(&aq->lock); + /* SE bind state */ + aq->se_bstate = hwinfo.bs; /* checkstop state */ if (chkstop && !aq->chkstop) { /* checkstop on */ diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index cc256424f70b..98814839ef30 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -194,7 +194,7 @@ struct ap_queue { bool config; /* configured state */ bool chkstop; /* checkstop state */ ap_qid_t qid; /* AP queue id. */ - bool se_bound; /* SE bound state */ + unsigned int se_bstate; /* SE bind state (BS) */ unsigned int assoc_idx; /* SE association index */ int queue_count; /* # messages currently on AP queue. */ int pendingq_count; /* # requests on pendingq list. */ diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 39f250f1f1c3..682595443145 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -317,7 +317,6 @@ static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) case AP_RESPONSE_RESET_IN_PROGRESS: aq->sm_state = AP_SM_STATE_RESET_WAIT; aq->rapq_fbit = 0; - aq->se_bound = false; return AP_SM_WAIT_LOW_TIMEOUT; default: aq->dev_state = AP_DEV_STATE_ERROR; @@ -338,17 +337,15 @@ static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) static enum ap_sm_wait ap_sm_reset_wait(struct ap_queue *aq) { struct ap_queue_status status; + struct ap_tapq_hwinfo hwinfo; void *lsi_ptr; - if (aq->queue_count > 0 && aq->reply) - /* Try to read a completed message and get the status */ - status = ap_sm_recv(aq); - else - /* Get the status with TAPQ */ - status = ap_tapq(aq->qid, NULL); + /* Get the status with TAPQ */ + status = ap_test_queue(aq->qid, 1, &hwinfo); switch (status.response_code) { case AP_RESPONSE_NORMAL: + aq->se_bstate = hwinfo.bs; lsi_ptr = ap_airq_ptr(); if (lsi_ptr && ap_queue_enable_irq(aq, lsi_ptr) == 0) aq->sm_state = AP_SM_STATE_SETIRQ_WAIT; @@ -441,6 +438,9 @@ static enum ap_sm_wait ap_sm_assoc_wait(struct ap_queue *aq) return AP_SM_WAIT_NONE; } + /* update queue's SE bind state */ + aq->se_bstate = hwinfo.bs; + /* check bs bits */ switch (hwinfo.bs) { case AP_BS_Q_USABLE: @@ -851,6 +851,12 @@ static ssize_t se_bind_show(struct device *dev, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return -EIO; } + + /* update queue's SE bind state */ + spin_lock_bh(&aq->lock); + aq->se_bstate = hwinfo.bs; + spin_unlock_bh(&aq->lock); + switch (hwinfo.bs) { case AP_BS_Q_USABLE: case AP_BS_Q_USABLE_NO_SECURE_KEY: @@ -866,6 +872,7 @@ static ssize_t se_bind_store(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_queue_status status; + struct ap_tapq_hwinfo hwinfo; bool value; int rc; @@ -877,39 +884,80 @@ static ssize_t se_bind_store(struct device *dev, if (rc) return rc; - if (value) { - /* bind, do BAPQ */ - spin_lock_bh(&aq->lock); - if (aq->sm_state < AP_SM_STATE_IDLE) { - spin_unlock_bh(&aq->lock); - return -EBUSY; - } - status = ap_bapq(aq->qid); - spin_unlock_bh(&aq->lock); - 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), - AP_QID_QUEUE(aq->qid)); - return -EIO; - } - } else { - /* unbind, set F bit arg and trigger RAPQ */ + if (!value) { + /* Unbind. Set F bit arg and trigger RAPQ */ spin_lock_bh(&aq->lock); __ap_flush_queue(aq); aq->rapq_fbit = 1; - aq->assoc_idx = ASSOC_IDX_INVALID; - aq->sm_state = AP_SM_STATE_RESET_START; - ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); - spin_unlock_bh(&aq->lock); + _ap_queue_init_state(aq); + rc = count; + goto out; } - return count; + /* Bind. Check current SE bind state */ + status = ap_test_queue(aq->qid, 1, &hwinfo); + if (status.response_code) { + AP_DBF_WARN("%s RC 0x%02x on tapq(0x%02x.%04x)\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return -EIO; + } + + /* Update BS state */ + spin_lock_bh(&aq->lock); + aq->se_bstate = hwinfo.bs; + if (hwinfo.bs != AP_BS_Q_AVAIL_FOR_BINDING) { + AP_DBF_WARN("%s bind attempt with bs %d on queue 0x%02x.%04x\n", + __func__, hwinfo.bs, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = -EINVAL; + goto out; + } + + /* Check SM state */ + if (aq->sm_state < AP_SM_STATE_IDLE) { + rc = -EBUSY; + goto out; + } + + /* invoke BAPQ */ + status = ap_bapq(aq->qid); + if (status.response_code) { + AP_DBF_WARN("%s RC 0x%02x on bapq(0x%02x.%04x)\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = -EIO; + goto out; + } + aq->assoc_idx = ASSOC_IDX_INVALID; + + /* verify SE bind state */ + status = ap_test_queue(aq->qid, 1, &hwinfo); + if (status.response_code) { + AP_DBF_WARN("%s RC 0x%02x on tapq(0x%02x.%04x)\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = -EIO; + goto out; + } + aq->se_bstate = hwinfo.bs; + if (!(hwinfo.bs == AP_BS_Q_USABLE || + hwinfo.bs == AP_BS_Q_USABLE_NO_SECURE_KEY)) { + AP_DBF_WARN("%s BAPQ success, but bs shows %d on queue 0x%02x.%04x\n", + __func__, hwinfo.bs, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = -EIO; + goto out; + } + + /* SE bind was successful */ + AP_DBF_INFO("%s bapq(0x%02x.%04x) success\n", __func__, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = count; + +out: + spin_unlock_bh(&aq->lock); + return rc; } static DEVICE_ATTR_RW(se_bind); @@ -932,6 +980,11 @@ static ssize_t se_associate_show(struct device *dev, return -EIO; } + /* update queue's SE bind state */ + spin_lock_bh(&aq->lock); + aq->se_bstate = hwinfo.bs; + spin_unlock_bh(&aq->lock); + switch (hwinfo.bs) { case AP_BS_Q_USABLE: if (aq->assoc_idx == ASSOC_IDX_INVALID) { @@ -954,6 +1007,7 @@ static ssize_t se_associate_store(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_queue_status status; + struct ap_tapq_hwinfo hwinfo; unsigned int value; int rc; @@ -967,18 +1021,28 @@ static ssize_t se_associate_store(struct device *dev, if (value >= ASSOC_IDX_INVALID) return -EINVAL; + /* check current SE bind state */ + status = ap_test_queue(aq->qid, 1, &hwinfo); + if (status.response_code) { + AP_DBF_WARN("%s RC 0x%02x on tapq(0x%02x.%04x)\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return -EIO; + } spin_lock_bh(&aq->lock); - - /* sm should be in idle state */ - if (aq->sm_state != AP_SM_STATE_IDLE) { - spin_unlock_bh(&aq->lock); - return -EBUSY; + aq->se_bstate = hwinfo.bs; + if (hwinfo.bs != AP_BS_Q_USABLE_NO_SECURE_KEY) { + AP_DBF_WARN("%s association attempt with bs %d on queue 0x%02x.%04x\n", + __func__, hwinfo.bs, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + rc = -EINVAL; + goto out; } - /* already associated or association pending ? */ - if (aq->assoc_idx != ASSOC_IDX_INVALID) { - spin_unlock_bh(&aq->lock); - return -EINVAL; + /* check SM state */ + if (aq->sm_state != AP_SM_STATE_IDLE) { + rc = -EBUSY; + goto out; } /* trigger the asynchronous association request */ @@ -989,17 +1053,20 @@ static ssize_t se_associate_store(struct device *dev, aq->sm_state = AP_SM_STATE_ASSOC_WAIT; aq->assoc_idx = value; ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); - spin_unlock_bh(&aq->lock); break; default: - spin_unlock_bh(&aq->lock); AP_DBF_WARN("%s RC 0x%02x on aapq(0x%02x.%04x)\n", __func__, status.response_code, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); - return -EIO; + rc = -EIO; + goto out; } - return count; + rc = count; + +out: + spin_unlock_bh(&aq->lock); + return rc; } static DEVICE_ATTR_RW(se_associate); @@ -1122,7 +1189,9 @@ bool ap_queue_usable(struct ap_queue *aq) } /* SE guest's queues additionally need to be bound */ - if (ap_q_needs_bind(aq) && !aq->se_bound) + if (ap_q_needs_bind(aq) && + !(aq->se_bstate == AP_BS_Q_USABLE || + aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) rc = false; unlock_and_out: -- cgit v1.2.3 From f88d36845391f8df8faa9d28818bfbdd67af0d91 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 14:09:29 +0100 Subject: s390/ctlreg: return old register contents when changing bits Change local_ctl_set_bit() and local_ctl_clear_bit() so they return the previous value of the to be changed control register. This is useful if a bit is only changed temporarily and the previous content needs to be restored. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/ctlreg.h | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/s390/include/asm/ctlreg.h b/arch/s390/include/asm/ctlreg.h index 6d4b85f2b541..72a9556d04f3 100644 --- a/arch/s390/include/asm/ctlreg.h +++ b/arch/s390/include/asm/ctlreg.h @@ -141,22 +141,26 @@ static __always_inline void local_ctl_store(unsigned int cr, struct ctlreg *reg) : [cr] "i" (cr)); } -static __always_inline void local_ctl_set_bit(unsigned int cr, unsigned int bit) +static __always_inline struct ctlreg local_ctl_set_bit(unsigned int cr, unsigned int bit) { - struct ctlreg reg; + struct ctlreg new, old; - local_ctl_store(cr, ®); - reg.val |= 1UL << bit; - local_ctl_load(cr, ®); + local_ctl_store(cr, &old); + new = old; + new.val |= 1UL << bit; + local_ctl_load(cr, &new); + return old; } -static __always_inline void local_ctl_clear_bit(unsigned int cr, unsigned int bit) +static __always_inline struct ctlreg local_ctl_clear_bit(unsigned int cr, unsigned int bit) { - struct ctlreg reg; + struct ctlreg new, old; - local_ctl_store(cr, ®); - reg.val &= ~(1UL << bit); - local_ctl_load(cr, ®); + local_ctl_store(cr, &old); + new = old; + new.val &= ~(1UL << bit); + local_ctl_load(cr, &new); + return old; } struct lowcore; -- cgit v1.2.3 From 84e599e3adc78800f8517f22f65b7a181cbb824b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 14:09:30 +0100 Subject: s390/nmi: consistently enable machine checks in trap_init() The kernel starts with machine checks disabled (machine check mask bit in the PSW is zero), and machine checks are enabled when trap_init() is called. The rationale is that this allows to assume that the system is initialized up to a certain point before the machine check handler may be invoked. However the implementation is incomplete: all new PSW masks in lowcore have the machine check mask bit. This means that e.g. for any early program check machine checks are enabled within the program check handler. This contradicts the whole point of enabling machine checks at a single place. Change this and initialize all new PSWs in lowcore so they have the machine check mask bit not set. Set the bit in all masks in trap_init(). This way machine check enabling is consistent. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kernel/setup.c | 8 ++++---- arch/s390/kernel/traps.c | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 5701356f4f33..c0e7cfdd7747 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -408,15 +408,15 @@ static void __init setup_lowcore(void) lc->restart_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_DAT; lc->restart_psw.addr = __pa(restart_int_handler); - lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->external_new_psw.mask = PSW_KERNEL_BITS; lc->external_new_psw.addr = (unsigned long) ext_int_handler; - lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->svc_new_psw.mask = PSW_KERNEL_BITS; lc->svc_new_psw.addr = (unsigned long) system_call; - lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->program_new_psw.mask = PSW_KERNEL_BITS; lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS; lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; - lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->io_new_psw.mask = PSW_KERNEL_BITS; lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->clock_comparator = clock_comparator_max; lc->current_task = (unsigned long)&init_task; diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 1d2aa448d103..8cb3832a1621 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -286,6 +286,17 @@ static void __init test_monitor_call(void) void __init trap_init(void) { + unsigned long flags; + struct ctlreg cr0; + + local_irq_save(flags); + cr0 = local_ctl_clear_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT); + psw_bits(S390_lowcore.external_new_psw).mcheck = 1; + psw_bits(S390_lowcore.program_new_psw).mcheck = 1; + psw_bits(S390_lowcore.svc_new_psw).mcheck = 1; + psw_bits(S390_lowcore.io_new_psw).mcheck = 1; + local_ctl_load(0, &cr0); + local_irq_restore(flags); local_mcck_enable(); test_monitor_call(); } -- cgit v1.2.3 From 1c8b8cf28f18ef57d189a170eaf6e0d3d3794ec5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 14:09:31 +0100 Subject: s390/nmi: implement and use local_mcck_save() / local_mcck_restore() Instead of using local_mcck_disable() / local_mcck_enable() implement and use local_mcck_save() / local_mcck_restore() to disable machine checks, and restoring the previous state. The problem with using local_mcck_disable() / local_mcck_enable() is that there is an assumption that machine checks are always enabled. While this is currently the case the code still looks quite odd, readers need to double check if the code is correct. In order to increase readability save and then restore the old machine check mask bit, instead of assuming that it must have been enabled. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/processor.h | 28 +++++++++++++++++++++++++--- arch/s390/kernel/nmi.c | 5 +++-- arch/s390/lib/test_unwind.c | 6 +++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index dc17896a001a..0b625373a255 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -332,14 +332,36 @@ static inline unsigned long __extract_psw(void) return (((unsigned long) reg1) << 32) | ((unsigned long) reg2); } -static inline void local_mcck_enable(void) +static inline unsigned long __local_mcck_save(void) { - __load_psw_mask(__extract_psw() | PSW_MASK_MCHECK); + unsigned long mask = __extract_psw(); + + __load_psw_mask(mask & ~PSW_MASK_MCHECK); + return mask & PSW_MASK_MCHECK; +} + +#define local_mcck_save(mflags) \ +do { \ + typecheck(unsigned long, mflags); \ + mflags = __local_mcck_save(); \ +} while (0) + +static inline void local_mcck_restore(unsigned long mflags) +{ + unsigned long mask = __extract_psw(); + + mask &= ~PSW_MASK_MCHECK; + __load_psw_mask(mask | mflags); } static inline void local_mcck_disable(void) { - __load_psw_mask(__extract_psw() & ~PSW_MASK_MCHECK); + __local_mcck_save(); +} + +static inline void local_mcck_enable(void) +{ + __load_psw_mask(__extract_psw() | PSW_MASK_MCHECK); } /* diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 0daf0f1cdfc9..60bcb451a4eb 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -159,16 +159,17 @@ NOKPROBE_SYMBOL(s390_handle_damage); void s390_handle_mcck(void) { struct mcck_struct mcck; + unsigned long mflags; /* * Disable machine checks and get the current state of accumulated * machine checks. Afterwards delete the old state and enable machine * checks again. */ - local_mcck_disable(); + local_mcck_save(mflags); mcck = *this_cpu_ptr(&cpu_mcck); memset(this_cpu_ptr(&cpu_mcck), 0, sizeof(mcck)); - local_mcck_enable(); + local_mcck_restore(mflags); if (mcck.channel_report) crw_handle_channel_report(); diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c index 7231bf97b93a..2848e3fb2ff5 100644 --- a/arch/s390/lib/test_unwind.c +++ b/arch/s390/lib/test_unwind.c @@ -350,15 +350,15 @@ static noinline int unwindme_func3(struct unwindme *u) /* This function must appear in the backtrace. */ static noinline int unwindme_func2(struct unwindme *u) { - unsigned long flags; + unsigned long flags, mflags; int rc; if (u->flags & UWM_SWITCH_STACK) { local_irq_save(flags); - local_mcck_disable(); + local_mcck_save(mflags); rc = call_on_stack(1, S390_lowcore.nodat_stack, int, unwindme_func3, struct unwindme *, u); - local_mcck_enable(); + local_mcck_restore(mflags); local_irq_restore(flags); return rc; } else { -- cgit v1.2.3 From 8b13601d19c541158a6e18b278c00ba69ae37829 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 30 Nov 2023 18:55:59 +0100 Subject: s390/ptrace: handle setting of fpc register correctly If the content of the floating point control (fpc) register of a traced process is modified with the ptrace interface the new value is tested for validity by temporarily loading it into the fpc register. This may lead to corruption of the fpc register of the tracing process: if an interrupt happens while the value is temporarily loaded into the fpc register, and within interrupt context floating point or vector registers are used, the current fp/vx registers are saved with save_fpu_regs() assuming they belong to user space and will be loaded into fp/vx registers when returning to user space. test_fp_ctl() restores the original user space fpc register value, however it will be discarded, when returning to user space. In result the tracer will incorrectly continue to run with the value that was supposed to be used for the traced process. Fix this by saving fpu register contents with save_fpu_regs() before using test_fp_ctl(). Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kernel/ptrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 046403471c5d..c7ed302a6b59 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -392,6 +392,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if ((unsigned int) data != 0 || test_fp_ctl(data >> (BITS_PER_LONG - 32))) return -EINVAL; @@ -748,6 +749,7 @@ static int __poke_user_compat(struct task_struct *child, /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if (test_fp_ctl(tmp)) return -EINVAL; child->thread.fpu.fpc = data; @@ -911,9 +913,7 @@ static int s390_fpregs_set(struct task_struct *target, int rc = 0; freg_t fprs[__NUM_FPRS]; - if (target == current) - save_fpu_regs(); - + save_fpu_regs(); if (MACHINE_HAS_VX) convert_vx_to_fp(fprs, target->thread.fpu.vxrs); else -- cgit v1.2.3 From b988b1bb0053c0dcd26187d29ef07566a565cf55 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 30 Nov 2023 18:56:00 +0100 Subject: KVM: s390: fix setting of fpc register kvm_arch_vcpu_ioctl_set_fpu() allows to set the floating point control (fpc) register of a guest cpu. The new value is tested for validity by temporarily loading it into the fpc register. This may lead to corruption of the fpc register of the host process: if an interrupt happens while the value is temporarily loaded into the fpc register, and within interrupt context floating point or vector registers are used, the current fp/vx registers are saved with save_fpu_regs() assuming they belong to user space and will be loaded into fp/vx registers when returning to user space. test_fp_ctl() restores the original user space / host process fpc register value, however it will be discarded, when returning to user space. In result the host process will incorrectly continue to run with the value that was supposed to be used for a guest cpu. Fix this by simply removing the test. There is another test right before the SIE context is entered which will handles invalid values. This results in a change of behaviour: invalid values will now be accepted instead of that the ioctl fails with -EINVAL. This seems to be acceptable, given that this interface is most likely not used anymore, and this is in addition the same behaviour implemented with the memory mapped interface (replace invalid values with zero) - see sync_regs() in kvm-s390.c. Reviewed-by: Christian Borntraeger Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kvm/kvm-s390.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 7aa0e668488f..16e32174807f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4316,10 +4316,6 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) vcpu_load(vcpu); - if (test_fp_ctl(fpu->fpc)) { - ret = -EINVAL; - goto out; - } vcpu->run->s.regs.fpc = fpu->fpc; if (MACHINE_HAS_VX) convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, @@ -4327,7 +4323,6 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) else memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); -out: vcpu_put(vcpu); return ret; } -- cgit v1.2.3 From 3b2e00f167f493ca1de7451310f1ce56f0b27fcb Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 30 Nov 2023 18:56:01 +0100 Subject: KVM: s390: use READ_ONCE() to read fpc register value Use READ_ONCE() to read a vcpu's floating point register value from the memory mapped area. This avoids that, depending on code generation, a different value is tested for validity than the one that is used, since user space can modify the area concurrently and the compiler is free to generate code that reads the value multiple times. Reviewed-by: Christian Borntraeger Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kvm/kvm-s390.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 16e32174807f..1a1af4db5afc 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4962,7 +4962,7 @@ static void sync_regs(struct kvm_vcpu *vcpu) current->thread.fpu.regs = vcpu->run->s.regs.vrs; else current->thread.fpu.regs = vcpu->run->s.regs.fprs; - current->thread.fpu.fpc = vcpu->run->s.regs.fpc; + current->thread.fpu.fpc = READ_ONCE(vcpu->run->s.regs.fpc); if (test_fp_ctl(current->thread.fpu.fpc)) /* User space provided an invalid FPC, let's clear it */ current->thread.fpu.fpc = 0; -- cgit v1.2.3 From 702644249d3e03333f16273a3a3ebedecfb7f2c6 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 30 Nov 2023 18:56:02 +0100 Subject: s390/fpu: get rid of test_fp_ctl() It is quite subtle to use test_fp_ctl() correctly. Therefore remove it - instead copy whatever new floating point control (fpc) register values are supposed to be used into its save area. Test the validity of the new value when loading it. If the new value is invalid, load the fpc register with zero. This seems to be a the best way to approach this problem. Even though this changes behavior: - sigreturn with an invalid fpc value on the stack will succeed, and continue with zero value, instead of returning with SIGSEGV - ptraced processes will also use a zero value instead of letting the request fail with -EINVAL However all of this seems to acceptable. After all testing of the value was only implemented to avoid that user space can crash the kernel. It is not there to test values for validity; and the assumption is that there is no existing user space which is doing this. Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/fpu/api.h | 34 ++++++++++++++++++++-------------- arch/s390/kernel/compat_signal.c | 4 ---- arch/s390/kernel/fpu.c | 4 ++-- arch/s390/kernel/ptrace.c | 13 +++++-------- arch/s390/kernel/signal.c | 4 ---- arch/s390/kernel/vmlinux.lds.S | 1 + arch/s390/kvm/kvm-s390.c | 5 +---- 7 files changed, 29 insertions(+), 36 deletions(-) diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h index b714ed0ef688..dc34de234ed7 100644 --- a/arch/s390/include/asm/fpu/api.h +++ b/arch/s390/include/asm/fpu/api.h @@ -51,21 +51,27 @@ void save_fpu_regs(void); void load_fpu_regs(void); void __load_fpu_regs(void); -static inline int test_fp_ctl(u32 fpc) +/** + * sfpc_safe - Set floating point control register safely. + * @fpc: new value for floating point control register + * + * Set floating point control register. This may lead to an exception, + * since a saved value may have been modified by user space (ptrace, + * signal return, kvm registers) to an invalid value. In such a case + * set the floating point control register to zero. + */ +static inline void sfpc_safe(u32 fpc) { - u32 orig_fpc; - int rc; - - asm volatile( - " efpc %1\n" - " sfpc %2\n" - "0: sfpc %1\n" - " la %0,0\n" - "1:\n" - EX_TABLE(0b,1b) - : "=d" (rc), "=&d" (orig_fpc) - : "d" (fpc), "0" (-EINVAL)); - return rc; + asm volatile("\n" + "0: sfpc %[fpc]\n" + "1: nopr %%r7\n" + ".pushsection .fixup, \"ax\"\n" + "2: lghi %[fpc],0\n" + " jg 0b\n" + ".popsection\n" + EX_TABLE(1b, 2b) + : [fpc] "+d" (fpc) + : : "memory"); } #define KERNEL_FPC 1 diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index cecedd01d4ec..8b90bf89b62c 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -98,10 +98,6 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI)) return -EINVAL; - /* Test the floating-point-control word. */ - if (test_fp_ctl(user_sregs.fpregs.fpc)) - return -EINVAL; - /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 | diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c index 4666b29ac8a1..35aaf99bab16 100644 --- a/arch/s390/kernel/fpu.c +++ b/arch/s390/kernel/fpu.c @@ -177,10 +177,10 @@ EXPORT_SYMBOL(__kernel_fpu_end); void __load_fpu_regs(void) { - struct fpu *state = ¤t->thread.fpu; unsigned long *regs = current->thread.fpu.regs; + struct fpu *state = ¤t->thread.fpu; - asm volatile("lfpc %0" : : "Q" (state->fpc)); + sfpc_safe(state->fpc); if (likely(MACHINE_HAS_VX)) { asm volatile("lgr 1,%0\n" "VLM 0,15,0,1\n" diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c7ed302a6b59..df2ee1b88024 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -392,9 +392,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * floating point control reg. is in the thread structure */ - save_fpu_regs(); - if ((unsigned int) data != 0 || - test_fp_ctl(data >> (BITS_PER_LONG - 32))) + if ((unsigned int)data != 0) return -EINVAL; child->thread.fpu.fpc = data >> (BITS_PER_LONG - 32); @@ -749,9 +747,6 @@ static int __poke_user_compat(struct task_struct *child, /* * floating point control reg. is in the thread structure */ - save_fpu_regs(); - if (test_fp_ctl(tmp)) - return -EINVAL; child->thread.fpu.fpc = data; } else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) { @@ -913,7 +908,9 @@ static int s390_fpregs_set(struct task_struct *target, int rc = 0; freg_t fprs[__NUM_FPRS]; - save_fpu_regs(); + if (target == current) + save_fpu_regs(); + if (MACHINE_HAS_VX) convert_vx_to_fp(fprs, target->thread.fpu.vxrs); else @@ -926,7 +923,7 @@ static int s390_fpregs_set(struct task_struct *target, 0, offsetof(s390_fp_regs, fprs)); if (rc) return rc; - if (ufpc[1] != 0 || test_fp_ctl(ufpc[0])) + if (ufpc[1] != 0) return -EINVAL; target->thread.fpu.fpc = ufpc[0]; } diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index d63557d3868c..0e926e896808 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -149,10 +149,6 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI)) return -EINVAL; - /* Test the floating-point-control word. */ - if (test_fp_ctl(user_sregs.fpregs.fpc)) - return -EINVAL; - /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI)); diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 2ae201ebf90b..e32ef446f451 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -52,6 +52,7 @@ SECTIONS SOFTIRQENTRY_TEXT FTRACE_HOTPATCH_TRAMPOLINES_TEXT *(.text.*_indirect_*) + *(.fixup) *(.gnu.warning) . = ALIGN(PAGE_SIZE); _etext = .; /* End of text section */ diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 1a1af4db5afc..432688acc523 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4962,10 +4962,7 @@ static void sync_regs(struct kvm_vcpu *vcpu) current->thread.fpu.regs = vcpu->run->s.regs.vrs; else current->thread.fpu.regs = vcpu->run->s.regs.fprs; - current->thread.fpu.fpc = READ_ONCE(vcpu->run->s.regs.fpc); - if (test_fp_ctl(current->thread.fpu.fpc)) - /* User space provided an invalid FPC, let's clear it */ - current->thread.fpu.fpc = 0; + current->thread.fpu.fpc = vcpu->run->s.regs.fpc; /* Sync fmt2 only data */ if (likely(!kvm_s390_pv_cpu_is_protected(vcpu))) { -- cgit v1.2.3 From d7271ba40155d5e5c28e13516df5d9c69f40ef20 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2023 15:46:41 +0100 Subject: KVM: s390: remove superfluous save_fpu_regs() call The save_fpu_regs() call in kvm_arch_vcpu_ioctl_get_fpu() is pointless: it will save the current user space fpu context to the thread's save area. But the code is accessing only the vcpu's save are / mapped register area, which in this case are not the same. Therefore remove the confusing call. Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kvm/kvm-s390.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 432688acc523..6ca53009c861 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4331,8 +4331,6 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { vcpu_load(vcpu); - /* make sure we have the latest values */ - save_fpu_regs(); if (MACHINE_HAS_VX) convert_vx_to_fp((freg_t *) fpu->fprs, (__vector128 *) vcpu->run->s.regs.vrs); -- cgit v1.2.3 From d7f679ec868e8675c269c742a2ba58c6aceaf52b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 15:42:16 +0100 Subject: s390/fpu: remove ARCH_WANTS_DYNAMIC_TASK_STRUCT support s390 selects ARCH_WANTS_DYNAMIC_TASK_STRUCT in order to make the size of the task structure dependent on the availability of the vector facility. This doesn't make sense anymore because since many years all machines provide the vector facility. Therefore simplify the code a bit and remove s390 support for ARCH_WANTS_DYNAMIC_TASK_STRUCT. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/Kconfig | 1 - arch/s390/include/asm/processor.h | 6 +----- arch/s390/kernel/process.c | 2 +- arch/s390/kernel/setup.c | 17 ----------------- 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 3bec98d20283..b5dbac684bbd 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -123,7 +123,6 @@ config S390 select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_USE_SYM_ANNOTATIONS - select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_WANTS_NO_INSTR select ARCH_WANT_DEFAULT_BPF_JIT select ARCH_WANT_IPC_PARSE_VERSION diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 0b625373a255..92146d63c25e 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -184,11 +184,7 @@ struct thread_struct { struct gs_cb *gs_cb; /* Current guarded storage cb */ struct gs_cb *gs_bc_cb; /* Broadcast guarded storage cb */ struct pgm_tdb trap_tdb; /* Transaction abort diagnose block */ - /* - * Warning: 'fpu' is dynamically-sized. It *MUST* be at - * the end. - */ - struct fpu fpu; /* FP and VX register save area */ + struct fpu fpu; /* FP and VX register save area */ }; /* Flag to disable transactions. */ diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 258000417724..4e3b366589fb 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -89,7 +89,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) */ save_fpu_regs(); - memcpy(dst, src, arch_task_struct_size); + *dst = *src; dst->thread.fpu.regs = dst->thread.fpu.fprs; /* diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c0e7cfdd7747..d1f3b56e7afc 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -819,22 +819,6 @@ static void __init setup_randomness(void) static_branch_enable(&s390_arch_random_available); } -/* - * Find the correct size for the task_struct. This depends on - * the size of the struct fpu at the end of the thread_struct - * which is embedded in the task_struct. - */ -static void __init setup_task_size(void) -{ - int task_size = sizeof(struct task_struct); - - if (!MACHINE_HAS_VX) { - task_size -= sizeof(__vector128) * __NUM_VXRS; - task_size += sizeof(freg_t) * __NUM_FPRS; - } - arch_task_struct_size = task_size; -} - /* * Issue diagnose 318 to set the control program name and * version codes. @@ -927,7 +911,6 @@ void __init setup_arch(char **cmdline_p) os_info_init(); setup_ipl(); - setup_task_size(); setup_control_program_code(); /* Do some memory reservations *before* memory is added to memblock */ -- cgit v1.2.3 From af6ed37eb0bebc5661f653ed3704d606c2e8ec94 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 15:42:17 +0100 Subject: s390/fpu: remove "novx" option Remove the "novx" kernel command line option: the vector code runs without any problems since many years. Reviewed-by: Hendrik Brueckner Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/kernel/early.c | 8 -------- arch/s390/kernel/processor.c | 5 +---- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index eb43e5922a25..a34360652554 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -271,14 +271,6 @@ static inline void setup_access_registers(void) restore_access_regs(acrs); } -static int __init disable_vector_extension(char *str) -{ - S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; - system_ctl_clear_bit(0, CR0_VECTOR_BIT); - return 0; -} -early_param("novx", disable_vector_extension); - char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; static void __init setup_boot_command_line(void) { diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 0a999c8226d7..4a57453bfa6d 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -201,10 +201,7 @@ static int __init setup_hwcaps(void) if (MACHINE_HAS_TE) elf_hwcap |= HWCAP_TE; - /* - * Vector extension can be disabled with the "novx" parameter. - * Use MACHINE_HAS_VX instead of facility bit 129. - */ + /* Use MACHINE_HAS_VX instead of facility bit 129. */ if (MACHINE_HAS_VX) { elf_hwcap |= HWCAP_VXRS; if (test_facility(134)) -- cgit v1.2.3 From 68422c0069990e5fe2a7dc2c6c995a48c0bdec26 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 15:42:18 +0100 Subject: s390/als: add vector facility to z13 architecture level set Add the vector facility to the z13 architecture level set (ALS). All hypervisors support the vector facility since many years. Adding the facility to the ALS allows for compile time optimizations of the kernel: if the kernel is compiled for z13 or later, all tests which verify if the vector facility is present can return "true". This will be implemented with a subsequent patch. Reviewed-by: Hendrik Brueckner Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/tools/gen_facilities.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index cb0aff5c0187..68580cbea4e6 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -46,6 +46,7 @@ static struct facility_def facility_defs[] = { #endif #ifdef CONFIG_HAVE_MARCH_Z13_FEATURES 53, /* load-and-zero-rightmost-byte, etc. */ + 129, /* vector */ #endif #ifdef CONFIG_HAVE_MARCH_Z14_FEATURES 58, /* miscellaneous-instruction-extension 2 */ -- cgit v1.2.3 From 18564756ab328dfdc84d09b8150f5e4d2bb96753 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 1 Dec 2023 15:42:19 +0100 Subject: s390/fpu: get rid of MACHINE_HAS_VX Get rid of MACHINE_HAS_VX and replace it with cpu_has_vx() which is a short readable wrapper for "test_facility(129)". Facility bit 129 is set if the vector facility is present. test_facility() returns also true for all bits which are set in the architecture level set of the cpu that the kernel is compiled for. This means that test_facility(129) is a compile time constant which returns true for z13 and later, since the vector facility bit is part of the z13 kernel ALS. In result the compiled code will have less runtime checks, and less code. Reviewed-by: Hendrik Brueckner Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/crypto/chacha-glue.c | 2 +- arch/s390/include/asm/fpu/api.h | 1 + arch/s390/include/asm/fpu/internal.h | 10 ++++++++-- arch/s390/include/asm/setup.h | 2 -- arch/s390/kernel/compat_signal.c | 12 +++++++----- arch/s390/kernel/crash_dump.c | 5 +++-- arch/s390/kernel/early.c | 4 +--- arch/s390/kernel/fpu.c | 8 ++++---- arch/s390/kernel/machine_kexec.c | 2 +- arch/s390/kernel/nmi.c | 5 +++-- arch/s390/kernel/perf_regs.c | 6 ++++-- arch/s390/kernel/processor.c | 4 ++-- arch/s390/kernel/ptrace.c | 21 +++++++++++---------- arch/s390/kernel/signal.c | 8 ++++---- arch/s390/kernel/smp.c | 6 +++--- arch/s390/kernel/traps.c | 2 +- arch/s390/kvm/interrupt.c | 2 +- arch/s390/kvm/kvm-s390.c | 16 ++++++++-------- lib/raid6/s390vx.uc | 2 +- 19 files changed, 64 insertions(+), 54 deletions(-) diff --git a/arch/s390/crypto/chacha-glue.c b/arch/s390/crypto/chacha-glue.c index 5fae187f947a..ed9959e6f714 100644 --- a/arch/s390/crypto/chacha-glue.c +++ b/arch/s390/crypto/chacha-glue.c @@ -82,7 +82,7 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, * it cannot handle a block of data or less, but otherwise * it can handle data of arbitrary size */ - if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !MACHINE_HAS_VX) + if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !cpu_has_vx()) chacha_crypt_generic(state, dst, src, bytes, nrounds); else chacha20_crypt_s390(state, dst, src, bytes, diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h index dc34de234ed7..b6deca63b4c0 100644 --- a/arch/s390/include/asm/fpu/api.h +++ b/arch/s390/include/asm/fpu/api.h @@ -46,6 +46,7 @@ #include #include +#include void save_fpu_regs(void); void load_fpu_regs(void); diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h index 8634581b9011..d511c4cf5afb 100644 --- a/arch/s390/include/asm/fpu/internal.h +++ b/arch/s390/include/asm/fpu/internal.h @@ -10,8 +10,14 @@ #define _ASM_S390_FPU_INTERNAL_H #include +#include #include +static inline bool cpu_has_vx(void) +{ + return likely(test_facility(129)); +} + static inline void save_vx_regs(__vector128 *vxrs) { asm volatile( @@ -41,7 +47,7 @@ static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu) { fpregs->pad = 0; fpregs->fpc = fpu->fpc; - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs); else memcpy((freg_t *)&fpregs->fprs, fpu->fprs, @@ -51,7 +57,7 @@ static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu) static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu) { fpu->fpc = fpregs->fpc; - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs); else memcpy(fpu->fprs, (freg_t *)&fpregs->fprs, diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index df316436d2e1..03bcaa8effb2 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -28,7 +28,6 @@ #define MACHINE_FLAG_TOPOLOGY BIT(10) #define MACHINE_FLAG_TE BIT(11) #define MACHINE_FLAG_TLB_LC BIT(12) -#define MACHINE_FLAG_VX BIT(13) #define MACHINE_FLAG_TLB_GUEST BIT(14) #define MACHINE_FLAG_NX BIT(15) #define MACHINE_FLAG_GS BIT(16) @@ -90,7 +89,6 @@ extern unsigned long mio_wb_bit_mask; #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) -#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) #define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST) #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 8b90bf89b62c..f8fc6c25d051 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "compat_linux.h" #include "compat_ptrace.h" #include "entry.h" @@ -133,7 +134,7 @@ static int save_sigregs_ext32(struct pt_regs *regs, return -EFAULT; /* Save vector registers to signal stack */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { for (i = 0; i < __NUM_VXRS_LOW; i++) vxrs[i] = current->thread.fpu.vxrs[i].low; if (__copy_to_user(&sregs_ext->vxrs_low, vxrs, @@ -161,7 +162,7 @@ static int restore_sigregs_ext32(struct pt_regs *regs, *(__u32 *)®s->gprs[i] = gprs_high[i]; /* Restore vector registers from signal stack */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { if (__copy_from_user(vxrs, &sregs_ext->vxrs_low, sizeof(sregs_ext->vxrs_low)) || __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW, @@ -261,7 +262,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set, * the machine supports it */ frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved); - if (!MACHINE_HAS_VX) + if (!cpu_has_vx()) frame_size -= sizeof(frame->sregs_ext.vxrs_low) + sizeof(frame->sregs_ext.vxrs_high); frame = get_sigframe(&ksig->ka, regs, frame_size); @@ -344,11 +345,12 @@ static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set, * the machine supports it */ uc_flags = UC_GPRS_HIGH; - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { uc_flags |= UC_VXRS; - } else + } else { frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) + sizeof(frame->uc.uc_mcontext_ext.vxrs_high); + } frame = get_sigframe(&ksig->ka, regs, frame_size); if (frame == (void __user *) -1UL) return -EFAULT; diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 514feadd4c58..5c46c2659305 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -22,6 +22,7 @@ #include #include #include +#include #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y))) #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) @@ -319,7 +320,7 @@ static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa) ptr = nt_init(ptr, NT_S390_TODPREG, &sa->todpreg, sizeof(sa->todpreg)); ptr = nt_init(ptr, NT_S390_CTRS, &sa->ctrs, sizeof(sa->ctrs)); ptr = nt_init(ptr, NT_S390_PREFIX, &sa->prefix, sizeof(sa->prefix)); - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { ptr = nt_init(ptr, NT_S390_VXRS_HIGH, &sa->vxrs_high, sizeof(sa->vxrs_high)); ptr = nt_init(ptr, NT_S390_VXRS_LOW, @@ -343,7 +344,7 @@ static size_t get_cpu_elf_notes_size(void) size += nt_size(NT_S390_TODPREG, sizeof(sa->todpreg)); size += nt_size(NT_S390_CTRS, sizeof(sa->ctrs)); size += nt_size(NT_S390_PREFIX, sizeof(sa->prefix)); - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { size += nt_size(NT_S390_VXRS_HIGH, sizeof(sa->vxrs_high)); size += nt_size(NT_S390_VXRS_LOW, sizeof(sa->vxrs_low)); } diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index a34360652554..2345ea332b97 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -229,10 +229,8 @@ static __init void detect_machine_facilities(void) } if (test_facility(51)) S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC; - if (test_facility(129)) { - S390_lowcore.machine_flags |= MACHINE_FLAG_VX; + if (test_facility(129)) system_ctl_set_bit(0, CR0_VECTOR_BIT); - } if (test_facility(130)) S390_lowcore.machine_flags |= MACHINE_FLAG_NX; if (test_facility(133)) diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c index 35aaf99bab16..9e7c15fccfea 100644 --- a/arch/s390/kernel/fpu.c +++ b/arch/s390/kernel/fpu.c @@ -24,7 +24,7 @@ void __kernel_fpu_begin(struct kernel_fpu *state, u32 flags) /* Save floating point control */ asm volatile("stfpc %0" : "=Q" (state->fpc)); - if (!MACHINE_HAS_VX) { + if (!cpu_has_vx()) { if (flags & KERNEL_VXR_V0V7) { /* Save floating-point registers */ asm volatile("std 0,%0" : "=Q" (state->fprs[0])); @@ -106,7 +106,7 @@ void __kernel_fpu_end(struct kernel_fpu *state, u32 flags) /* Restore floating-point controls */ asm volatile("lfpc %0" : : "Q" (state->fpc)); - if (!MACHINE_HAS_VX) { + if (!cpu_has_vx()) { if (flags & KERNEL_VXR_V0V7) { /* Restore floating-point registers */ asm volatile("ld 0,%0" : : "Q" (state->fprs[0])); @@ -181,7 +181,7 @@ void __load_fpu_regs(void) struct fpu *state = ¤t->thread.fpu; sfpc_safe(state->fpc); - if (likely(MACHINE_HAS_VX)) { + if (likely(cpu_has_vx())) { asm volatile("lgr 1,%0\n" "VLM 0,15,0,1\n" "VLM 16,31,256,1\n" @@ -232,7 +232,7 @@ void save_fpu_regs(void) regs = current->thread.fpu.regs; asm volatile("stfpc %0" : "=Q" (state->fpc)); - if (likely(MACHINE_HAS_VX)) { + if (likely(cpu_has_vx())) { asm volatile("lgr 1,%0\n" "VSTM 0,15,0,1\n" "VSTM 16,31,256,1\n" diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index bb0d4d68fcbe..aa22ffc16bcd 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -91,7 +91,7 @@ static noinline void __machine_kdump(void *image) } /* Store status of the boot CPU */ mcesa = __va(S390_lowcore.mcesad & MCESA_ORIGIN_MASK); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) save_vx_regs((__vector128 *) mcesa->vector_save_area); if (MACHINE_HAS_GS) { local_ctl_store(2, &cr2_old.reg); diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 60bcb451a4eb..9ad44c26d1a2 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -32,6 +32,7 @@ #include #include #include +#include struct mcck_struct { unsigned int kill_task : 1; @@ -45,7 +46,7 @@ static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck); static inline int nmi_needs_mcesa(void) { - return MACHINE_HAS_VX || MACHINE_HAS_GS; + return cpu_has_vx() || MACHINE_HAS_GS; } /* @@ -235,7 +236,7 @@ static int notrace s390_validate_registers(union mci mci) } mcesa = __va(S390_lowcore.mcesad & MCESA_ORIGIN_MASK); - if (!MACHINE_HAS_VX) { + if (!cpu_has_vx()) { /* Validate floating point registers */ asm volatile( " ld 0,0(%0)\n" diff --git a/arch/s390/kernel/perf_regs.c b/arch/s390/kernel/perf_regs.c index 6e9e5d5e927e..3d93656bd948 100644 --- a/arch/s390/kernel/perf_regs.c +++ b/arch/s390/kernel/perf_regs.c @@ -20,8 +20,10 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) return 0; idx -= PERF_REG_S390_FP0; - fp = MACHINE_HAS_VX ? *(freg_t *)(current->thread.fpu.vxrs + idx) - : current->thread.fpu.fprs[idx]; + if (cpu_has_vx()) + fp = *(freg_t *)(current->thread.fpu.vxrs + idx); + else + fp = current->thread.fpu.fprs[idx]; return fp.ui; } diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 4a57453bfa6d..65c1464eea4f 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -201,8 +201,8 @@ static int __init setup_hwcaps(void) if (MACHINE_HAS_TE) elf_hwcap |= HWCAP_TE; - /* Use MACHINE_HAS_VX instead of facility bit 129. */ - if (MACHINE_HAS_VX) { + /* vector */ + if (test_facility(129)) { elf_hwcap |= HWCAP_VXRS; if (test_facility(134)) elf_hwcap |= HWCAP_VXRS_BCD; diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index df2ee1b88024..2e6754b62b20 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "entry.h" @@ -254,7 +255,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) * or the child->thread.fpu.vxrs array */ offset = addr - offsetof(struct user, regs.fp_regs.fprs); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) tmp = *(addr_t *) ((addr_t) child->thread.fpu.vxrs + 2*offset); else @@ -402,7 +403,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) * or the child->thread.fpu.vxrs array */ offset = addr - offsetof(struct user, regs.fp_regs.fprs); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) *(addr_t *)((addr_t) child->thread.fpu.vxrs + 2*offset) = data; else @@ -629,7 +630,7 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr) * or the child->thread.fpu.vxrs array */ offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) tmp = *(__u32 *) ((addr_t) child->thread.fpu.vxrs + 2*offset); else @@ -755,7 +756,7 @@ static int __poke_user_compat(struct task_struct *child, * or the child->thread.fpu.vxrs array */ offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) *(__u32 *)((addr_t) child->thread.fpu.vxrs + 2*offset) = tmp; else @@ -911,7 +912,7 @@ static int s390_fpregs_set(struct task_struct *target, if (target == current) save_fpu_regs(); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_vx_to_fp(fprs, target->thread.fpu.vxrs); else memcpy(&fprs, target->thread.fpu.fprs, sizeof(fprs)); @@ -934,7 +935,7 @@ static int s390_fpregs_set(struct task_struct *target, if (rc) return rc; - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_fp_to_vx(target->thread.fpu.vxrs, fprs); else memcpy(target->thread.fpu.fprs, &fprs, sizeof(fprs)); @@ -985,7 +986,7 @@ static int s390_vxrs_low_get(struct task_struct *target, __u64 vxrs[__NUM_VXRS_LOW]; int i; - if (!MACHINE_HAS_VX) + if (!cpu_has_vx()) return -ENODEV; if (target == current) save_fpu_regs(); @@ -1002,7 +1003,7 @@ static int s390_vxrs_low_set(struct task_struct *target, __u64 vxrs[__NUM_VXRS_LOW]; int i, rc; - if (!MACHINE_HAS_VX) + if (!cpu_has_vx()) return -ENODEV; if (target == current) save_fpu_regs(); @@ -1022,7 +1023,7 @@ static int s390_vxrs_high_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { - if (!MACHINE_HAS_VX) + if (!cpu_has_vx()) return -ENODEV; if (target == current) save_fpu_regs(); @@ -1037,7 +1038,7 @@ static int s390_vxrs_high_set(struct task_struct *target, { int rc; - if (!MACHINE_HAS_VX) + if (!cpu_has_vx()) return -ENODEV; if (target == current) save_fpu_regs(); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 0e926e896808..27bcc43fe1b7 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -178,7 +178,7 @@ static int save_sigregs_ext(struct pt_regs *regs, int i; /* Save vector registers to signal stack */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { for (i = 0; i < __NUM_VXRS_LOW; i++) vxrs[i] = current->thread.fpu.vxrs[i].low; if (__copy_to_user(&sregs_ext->vxrs_low, vxrs, @@ -198,7 +198,7 @@ static int restore_sigregs_ext(struct pt_regs *regs, int i; /* Restore vector registers from signal stack */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { if (__copy_from_user(vxrs, &sregs_ext->vxrs_low, sizeof(sregs_ext->vxrs_low)) || __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW, @@ -296,7 +296,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, * included in the signal frame on a 31-bit system. */ frame_size = sizeof(*frame) - sizeof(frame->sregs_ext); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) frame_size += sizeof(frame->sregs_ext); frame = get_sigframe(ka, regs, frame_size); if (frame == (void __user *) -1UL) @@ -373,7 +373,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, * included in the signal frame on a 31-bit system. */ uc_flags = 0; - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { frame_size += sizeof(_sigregs_ext); uc_flags |= UC_VXRS; } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index f7fcfff09acf..c39d9f0d4b1c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -582,7 +582,7 @@ int smp_store_status(int cpu) if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_STATUS_AT_ADDRESS, pa) != SIGP_CC_ORDER_CODE_ACCEPTED) return -EIO; - if (!MACHINE_HAS_VX && !MACHINE_HAS_GS) + if (!cpu_has_vx() && !MACHINE_HAS_GS) return 0; pa = lc->mcesad & MCESA_ORIGIN_MASK; if (MACHINE_HAS_GS) @@ -638,7 +638,7 @@ void __init smp_save_dump_ipl_cpu(void) copy_oldmem_kernel(regs, __LC_FPREGS_SAVE_AREA, 512); save_area_add_regs(sa, regs); memblock_free(regs, 512); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) save_area_add_vxrs(sa, boot_cpu_vector_save_area); } @@ -671,7 +671,7 @@ void __init smp_save_dump_secondary_cpus(void) panic("could not allocate memory for save area\n"); __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, __pa(page)); save_area_add_regs(sa, page); - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { __pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, __pa(page)); save_area_add_vxrs(sa, page); } diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 8cb3832a1621..f108a611b993 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -193,7 +193,7 @@ static void vector_exception(struct pt_regs *regs) { int si_code, vic; - if (!MACHINE_HAS_VX) { + if (!cpu_has_vx()) { do_trap(regs, SIGILL, ILL_ILLOPN, "illegal operation"); return; } diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index efaebba5ee19..fc4007cc067a 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -639,7 +639,7 @@ static int __write_machine_check(struct kvm_vcpu *vcpu, rc |= put_guest_lc(vcpu, mci.val, (u64 __user *) __LC_MCCK_CODE); /* Register-save areas */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { convert_vx_to_fp(fprs, (__vector128 *) vcpu->run->s.regs.vrs); rc |= write_guest_lc(vcpu, __LC_FPREGS_SAVE_AREA, fprs, 128); } else { diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 6ca53009c861..acc81ca6492e 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -618,7 +618,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = MACHINE_HAS_ESOP; break; case KVM_CAP_S390_VECTOR_REGISTERS: - r = MACHINE_HAS_VX; + r = test_facility(129); break; case KVM_CAP_S390_RI: r = test_facility(64); @@ -767,7 +767,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) mutex_lock(&kvm->lock); if (kvm->created_vcpus) { r = -EBUSY; - } else if (MACHINE_HAS_VX) { + } else if (cpu_has_vx()) { set_kvm_facility(kvm->arch.model.fac_mask, 129); set_kvm_facility(kvm->arch.model.fac_list, 129); if (test_facility(134)) { @@ -3962,9 +3962,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) if (test_kvm_facility(vcpu->kvm, 156)) vcpu->run->kvm_valid_regs |= KVM_SYNC_ETOKEN; /* fprs can be synchronized via vrs, even if the guest has no vx. With - * MACHINE_HAS_VX, (load|store)_fpu_regs() will work with vrs format. + * cpu_has_vx(), (load|store)_fpu_regs() will work with vrs format. */ - if (MACHINE_HAS_VX) + if (cpu_has_vx()) vcpu->run->kvm_valid_regs |= KVM_SYNC_VRS; else vcpu->run->kvm_valid_regs |= KVM_SYNC_FPRS; @@ -4317,7 +4317,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) vcpu_load(vcpu); vcpu->run->s.regs.fpc = fpu->fpc; - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, (freg_t *) fpu->fprs); else @@ -4331,7 +4331,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { vcpu_load(vcpu); - if (MACHINE_HAS_VX) + if (cpu_has_vx()) convert_vx_to_fp((freg_t *) fpu->fprs, (__vector128 *) vcpu->run->s.regs.vrs); else @@ -4956,7 +4956,7 @@ static void sync_regs(struct kvm_vcpu *vcpu) save_fpu_regs(); vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc; vcpu->arch.host_fpregs.regs = current->thread.fpu.regs; - if (MACHINE_HAS_VX) + if (cpu_has_vx()) current->thread.fpu.regs = vcpu->run->s.regs.vrs; else current->thread.fpu.regs = vcpu->run->s.regs.fprs; @@ -5135,7 +5135,7 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) gpa -= __LC_FPREGS_SAVE_AREA; /* manually convert vector registers if necessary */ - if (MACHINE_HAS_VX) { + if (cpu_has_vx()) { convert_vx_to_fp(fprs, (__vector128 *) vcpu->run->s.regs.vrs); rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, fprs, 128); diff --git a/lib/raid6/s390vx.uc b/lib/raid6/s390vx.uc index b25dfc9c7759..cd0b9e95f499 100644 --- a/lib/raid6/s390vx.uc +++ b/lib/raid6/s390vx.uc @@ -158,7 +158,7 @@ static void raid6_s390vx$#_xor_syndrome(int disks, int start, int stop, static int raid6_s390vx$#_valid(void) { - return MACHINE_HAS_VX; + return cpu_has_vx(); } const struct raid6_calls raid6_s390vx$# = { -- cgit v1.2.3 From a6d27ea01a702b51b9dc102aebcae39151bea8e3 Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Tue, 5 Dec 2023 18:32:52 +0100 Subject: s390/mm: convert pgste locking functions to C Convert pgste_get_lock() and pgste_set_unlock() to C. There is no real reasons to keep them in assembler. Having them in C makes them more readable and maintainable, and better instructions are used automatically when available. Signed-off-by: Claudio Imbrenda Acked-by: Alexander Gordeev Reviewed-by: Heiko Carstens Link: https://lore.kernel.org/r/20231205173252.62305-1-imbrenda@linux.ibm.com Signed-off-by: Alexander Gordeev --- arch/s390/mm/pgtable.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 3bd2ab2a9a34..6c4523aa4fdf 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -125,32 +125,23 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm, static inline pgste_t pgste_get_lock(pte_t *ptep) { - unsigned long new = 0; + unsigned long value = 0; #ifdef CONFIG_PGSTE - unsigned long old; - - asm( - " lg %0,%2\n" - "0: lgr %1,%0\n" - " nihh %0,0xff7f\n" /* clear PCL bit in old */ - " oihh %1,0x0080\n" /* set PCL bit in new */ - " csg %0,%1,%2\n" - " jl 0b\n" - : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE]) - : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory"); + unsigned long *ptr = (unsigned long *)(ptep + PTRS_PER_PTE); + + do { + value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr); + } while (value & PGSTE_PCL_BIT); + value |= PGSTE_PCL_BIT; #endif - return __pgste(new); + return __pgste(value); } static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE - asm( - " nihh %1,0xff7f\n" /* clear PCL bit */ - " stg %1,%0\n" - : "=Q" (ptep[PTRS_PER_PTE]) - : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) - : "cc", "memory"); + barrier(); + WRITE_ONCE(*(unsigned long *)(ptep + PTRS_PER_PTE), pgste_val(pgste) & ~PGSTE_PCL_BIT); #endif } -- cgit v1.2.3 From 7fe228e1866f3a270a1f963c9f2ae3ba1eae7411 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 7 Dec 2023 15:24:34 +0100 Subject: s390: update defconfigs Signed-off-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/configs/debug_defconfig | 11 ++++++----- arch/s390/configs/defconfig | 11 ++++++----- arch/s390/configs/zfcpdump_defconfig | 3 +-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 438cd92e6080..e37e4119f7bd 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -44,8 +44,7 @@ CONFIG_KEXEC_FILE=y CONFIG_KEXEC_SIG=y CONFIG_CRASH_DUMP=y CONFIG_LIVEPATCH=y -CONFIG_MARCH_ZEC12=y -CONFIG_TUNE_ZEC12=y +CONFIG_MARCH_Z13=y CONFIG_NR_CPUS=512 CONFIG_NUMA=y CONFIG_HZ_100=y @@ -76,7 +75,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_MODULE_SIG_SHA256=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y @@ -93,6 +91,7 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_IOSCHED_BFQ=y CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y CONFIG_ZSMALLOC_STAT=y CONFIG_SLUB_STATS=y # CONFIG_COMPAT_BRK is not set @@ -118,7 +117,6 @@ CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_XFRM_USER=m CONFIG_NET_KEY=m -CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -598,6 +596,7 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -619,6 +618,9 @@ CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_DEBUG=y CONFIG_BTRFS_ASSERT=y CONFIG_NILFS2_FS=m +CONFIG_BCACHEFS_FS=y +CONFIG_BCACHEFS_QUOTA=y +CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_FS_DAX=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FS_ENCRYPTION=y @@ -691,7 +693,6 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=m CONFIG_KEY_NOTIFICATIONS=y CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 1b8150e50f6a..38d84bcded30 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -42,8 +42,7 @@ CONFIG_KEXEC_FILE=y CONFIG_KEXEC_SIG=y CONFIG_CRASH_DUMP=y CONFIG_LIVEPATCH=y -CONFIG_MARCH_ZEC12=y -CONFIG_TUNE_ZEC12=y +CONFIG_MARCH_Z13=y CONFIG_NR_CPUS=512 CONFIG_NUMA=y CONFIG_HZ_100=y @@ -71,7 +70,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_MODULE_SIG_SHA256=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y @@ -88,6 +86,7 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_IOSCHED_BFQ=y CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y CONFIG_ZSMALLOC_STAT=y # CONFIG_COMPAT_BRK is not set CONFIG_MEMORY_HOTPLUG=y @@ -109,7 +108,6 @@ CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_XFRM_USER=m CONFIG_NET_KEY=m -CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -587,6 +585,7 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -605,6 +604,9 @@ CONFIG_OCFS2_FS=m CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m +CONFIG_BCACHEFS_FS=m +CONFIG_BCACHEFS_QUOTA=y +CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_FS_DAX=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FS_ENCRYPTION=y @@ -677,7 +679,6 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=m CONFIG_KEY_NOTIFICATIONS=y CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_LOCKDOWN_LSM=y diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index b831083b4edd..47028450eee1 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -9,8 +9,7 @@ CONFIG_BPF_SYSCALL=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_CRASH_DUMP=y -CONFIG_MARCH_ZEC12=y -CONFIG_TUNE_ZEC12=y +CONFIG_MARCH_Z13=y # CONFIG_COMPAT is not set CONFIG_NR_CPUS=2 CONFIG_HZ_100=y -- cgit v1.2.3 From b8fa3e90965eeb2f83aa637ba0d0d6fd2a524004 Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Wed, 1 Nov 2023 12:57:51 +0100 Subject: s390/cio: make sch->lock spinlock pointer a member The lock member of struct subchannel used to be a spinlock, but became a pointer to a spinlock with commit 2ec2298412e1 ("[S390] subchannel lock conversion."). This might have been justified back then, but with the current state of affairs, there is no reason to manage a separate spinlock object. Let's simplify things and pull the spinlock back into struct subchannel. Signed-off-by: Halil Pasic Reviewed-by: Vineeth Vijayan Link: https://lore.kernel.org/r/20231101115751.2308307-1-pasic@linux.ibm.com Signed-off-by: Vasily Gorbik Signed-off-by: Alexander Gordeev --- drivers/s390/cio/chsc.c | 18 +++++------ drivers/s390/cio/chsc_sch.c | 6 ++-- drivers/s390/cio/cio.c | 6 ++-- drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/css.c | 36 +++++++--------------- drivers/s390/cio/device.c | 66 ++++++++++++++++++++--------------------- drivers/s390/cio/device_pgid.c | 12 ++++---- drivers/s390/cio/eadm_sch.c | 36 +++++++++++----------- drivers/s390/cio/vfio_ccw_drv.c | 8 ++--- drivers/s390/cio/vfio_ccw_fsm.c | 24 +++++++-------- 10 files changed, 99 insertions(+), 115 deletions(-) diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index f8b04ce61556..64ed55c3aed6 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -219,16 +219,16 @@ EXPORT_SYMBOL_GPL(chsc_sadc); static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) { - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); if (sch->driver && sch->driver->chp_event) if (sch->driver->chp_event(sch, data, CHP_OFFLINE) != 0) goto out_unreg; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; out_unreg: sch->lpm = 0; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); css_schedule_eval(sch->schid); return 0; } @@ -258,10 +258,10 @@ void chsc_chp_offline(struct chp_id chpid) static int __s390_process_res_acc(struct subchannel *sch, void *data) { - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); if (sch->driver && sch->driver->chp_event) sch->driver->chp_event(sch, data, CHP_ONLINE); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; } @@ -292,10 +292,10 @@ static void s390_process_res_acc(struct chp_link *link) static int process_fces_event(struct subchannel *sch, void *data) { - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); if (sch->driver && sch->driver->chp_event) sch->driver->chp_event(sch, data, CHP_FCES_EVENT); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; } @@ -769,11 +769,11 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, memset(&link, 0, sizeof(struct chp_link)); link.chpid = chpid; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); if (sch->driver && sch->driver->chp_event) sch->driver->chp_event(sch, &link, on ? CHP_VARY_ON : CHP_VARY_OFF); - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); } static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 180ab899289c..902237d0baef 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -211,10 +211,10 @@ static int chsc_async(struct chsc_async_area *chsc_area, chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; while ((sch = chsc_get_next_subchannel(sch))) { - spin_lock(sch->lock); + spin_lock(&sch->lock); private = dev_get_drvdata(&sch->dev); if (private->request) { - spin_unlock(sch->lock); + spin_unlock(&sch->lock); ret = -EBUSY; continue; } @@ -239,7 +239,7 @@ static int chsc_async(struct chsc_async_area *chsc_area, default: ret = -ENODEV; } - spin_unlock(sch->lock); + spin_unlock(&sch->lock); CHSC_MSG(2, "chsc on 0.%x.%04x returned cc=%d\n", sch->schid.ssid, sch->schid.sch_no, cc); if (ret == -EINPROGRESS) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 6127add746d1..a5736b7357b2 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -546,7 +546,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) return IRQ_HANDLED; } sch = phys_to_virt(tpi_info->intparm); - spin_lock(sch->lock); + spin_lock(&sch->lock); /* Store interrupt response block to lowcore. */ if (tsch(tpi_info->schid, irb) == 0) { /* Keep subchannel information word up to date. */ @@ -558,7 +558,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) inc_irq_stat(IRQIO_CIO); } else inc_irq_stat(IRQIO_CIO); - spin_unlock(sch->lock); + spin_unlock(&sch->lock); return IRQ_HANDLED; } @@ -663,7 +663,7 @@ struct subchannel *cio_probe_console(void) if (IS_ERR(sch)) return sch; - lockdep_set_class(sch->lock, &console_sch_key); + lockdep_set_class(&sch->lock, &console_sch_key); isc_register(CONSOLE_ISC); sch->config.isc = CONSOLE_ISC; sch->config.intparm = (u32)virt_to_phys(sch); diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index fa8df50bb49e..a9057a5b670a 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -83,7 +83,7 @@ enum sch_todo { /* subchannel data structure used by I/O subroutines */ struct subchannel { struct subchannel_id schid; - spinlock_t *lock; /* subchannel lock */ + spinlock_t lock; /* subchannel lock */ struct mutex reg_mutex; enum { SUBCHANNEL_TYPE_IO = 0, diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 3ff46fc694f8..28a88ed2c3aa 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -148,16 +148,10 @@ out: static void css_sch_todo(struct work_struct *work); -static int css_sch_create_locks(struct subchannel *sch) +static void css_sch_create_locks(struct subchannel *sch) { - sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL); - if (!sch->lock) - return -ENOMEM; - - spin_lock_init(sch->lock); + spin_lock_init(&sch->lock); mutex_init(&sch->reg_mutex); - - return 0; } static void css_subchannel_release(struct device *dev) @@ -167,7 +161,6 @@ static void css_subchannel_release(struct device *dev) sch->config.intparm = 0; cio_commit_config(sch); kfree(sch->driver_override); - kfree(sch->lock); kfree(sch); } @@ -219,9 +212,7 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, sch->schib = *schib; sch->st = schib->pmcw.st; - ret = css_sch_create_locks(sch); - if (ret) - goto err; + css_sch_create_locks(sch); INIT_WORK(&sch->todo_work, css_sch_todo); sch->dev.release = &css_subchannel_release; @@ -233,19 +224,17 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, */ ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31)); if (ret) - goto err_lock; + goto err; /* * But we don't have such restrictions imposed on the stuff that * is handled by the streaming API. */ ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64)); if (ret) - goto err_lock; + goto err; return sch; -err_lock: - kfree(sch->lock); err: kfree(sch); return ERR_PTR(ret); @@ -604,12 +593,12 @@ static void css_sch_todo(struct work_struct *work) sch = container_of(work, struct subchannel, todo_work); /* Find out todo. */ - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); todo = sch->todo; CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, sch->schid.sch_no, todo); sch->todo = SCH_TODO_NOTHING; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); /* Perform todo. */ switch (todo) { case SCH_TODO_NOTHING: @@ -617,9 +606,9 @@ static void css_sch_todo(struct work_struct *work) case SCH_TODO_EVAL: ret = css_evaluate_known_subchannel(sch, 1); if (ret == -EAGAIN) { - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); css_sched_sch_todo(sch, todo); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); } break; case SCH_TODO_UNREG: @@ -1028,12 +1017,7 @@ static int __init setup_css(int nr) css->pseudo_subchannel->dev.parent = &css->device; css->pseudo_subchannel->dev.release = css_subchannel_release; mutex_init(&css->pseudo_subchannel->reg_mutex); - ret = css_sch_create_locks(css->pseudo_subchannel); - if (ret) { - kfree(css->pseudo_subchannel); - device_unregister(&css->device); - goto out_err; - } + css_sch_create_locks(css->pseudo_subchannel); dev_set_name(&css->pseudo_subchannel->dev, "defunct"); ret = device_register(&css->pseudo_subchannel->dev); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 4ca5adce9107..0cfb179e1bcb 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -748,7 +748,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch, mutex_init(&cdev->reg_mutex); atomic_set(&priv->onoff, 0); - cdev->ccwlock = sch->lock; + cdev->ccwlock = &sch->lock; cdev->dev.parent = &sch->dev; cdev->dev.release = ccw_device_release; cdev->dev.bus = &ccw_bus_type; @@ -764,9 +764,9 @@ static int io_subchannel_initialize_dev(struct subchannel *sch, goto out_put; } priv->flags.initialized = 1; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); sch_set_cdev(sch, cdev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; out_put: @@ -851,9 +851,9 @@ static void io_subchannel_register(struct ccw_device *cdev) CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno, ret); - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); sch_set_cdev(sch, NULL); - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); mutex_unlock(&cdev->reg_mutex); /* Release initial device reference. */ put_device(&cdev->dev); @@ -904,9 +904,9 @@ static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) atomic_inc(&ccw_device_init_count); /* Start async. device sensing. */ - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); ccw_device_recognition(cdev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); } static int ccw_device_move_to_sch(struct ccw_device *cdev, @@ -921,12 +921,12 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev, return -ENODEV; if (!sch_is_pseudo_sch(old_sch)) { - spin_lock_irq(old_sch->lock); + spin_lock_irq(&old_sch->lock); old_enabled = old_sch->schib.pmcw.ena; rc = 0; if (old_enabled) rc = cio_disable_subchannel(old_sch); - spin_unlock_irq(old_sch->lock); + spin_unlock_irq(&old_sch->lock); if (rc == -EBUSY) { /* Release child reference for new parent. */ put_device(&sch->dev); @@ -944,9 +944,9 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev, sch->schib.pmcw.dev, rc); if (old_enabled) { /* Try to re-enable the old subchannel. */ - spin_lock_irq(old_sch->lock); + spin_lock_irq(&old_sch->lock); cio_enable_subchannel(old_sch, (u32)virt_to_phys(old_sch)); - spin_unlock_irq(old_sch->lock); + spin_unlock_irq(&old_sch->lock); } /* Release child reference for new parent. */ put_device(&sch->dev); @@ -954,19 +954,19 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev, } /* Clean up old subchannel. */ if (!sch_is_pseudo_sch(old_sch)) { - spin_lock_irq(old_sch->lock); + spin_lock_irq(&old_sch->lock); sch_set_cdev(old_sch, NULL); - spin_unlock_irq(old_sch->lock); + spin_unlock_irq(&old_sch->lock); css_schedule_eval(old_sch->schid); } /* Release child reference for old parent. */ put_device(&old_sch->dev); /* Initialize new subchannel. */ - spin_lock_irq(sch->lock); - cdev->ccwlock = sch->lock; + spin_lock_irq(&sch->lock); + cdev->ccwlock = &sch->lock; if (!sch_is_pseudo_sch(sch)) sch_set_cdev(sch, cdev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); if (!sch_is_pseudo_sch(sch)) css_update_ssd_info(sch); return 0; @@ -1077,9 +1077,9 @@ static int io_subchannel_probe(struct subchannel *sch) return 0; out_schedule: - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); css_sched_sch_todo(sch, SCH_TODO_UNREG); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; } @@ -1093,10 +1093,10 @@ static void io_subchannel_remove(struct subchannel *sch) goto out_free; ccw_device_unregister(cdev); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); sch_set_cdev(sch, NULL); set_io_private(sch, NULL); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); out_free: dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area), io_priv->dma_area, io_priv->dma_area_dma); @@ -1203,7 +1203,7 @@ static void io_subchannel_quiesce(struct subchannel *sch) struct ccw_device *cdev; int ret; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); cdev = sch_get_cdev(sch); if (cio_is_console(sch->schid)) goto out_unlock; @@ -1220,15 +1220,15 @@ static void io_subchannel_quiesce(struct subchannel *sch) ret = ccw_device_cancel_halt_clear(cdev); if (ret == -EBUSY) { ccw_device_set_timeout(cdev, HZ/10); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); wait_event(cdev->private->wait_q, cdev->private->state != DEV_STATE_QUIESCE); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); } ret = cio_disable_subchannel(sch); } out_unlock: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); } static void io_subchannel_shutdown(struct subchannel *sch) @@ -1439,7 +1439,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) enum io_sch_action action; int rc = -EAGAIN; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); if (!device_is_registered(&sch->dev)) goto out_unlock; if (work_pending(&sch->todo_work)) @@ -1492,7 +1492,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) default: break; } - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); /* All other actions require process context. */ if (!process) goto out; @@ -1507,9 +1507,9 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) break; case IO_SCH_UNREG_CDEV: case IO_SCH_UNREG_ATTACH: - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); sch_set_cdev(sch, NULL); - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); /* Unregister ccw device. */ ccw_device_unregister(cdev); break; @@ -1538,9 +1538,9 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) put_device(&cdev->dev); goto out; } - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); ccw_device_trigger_reprobe(cdev); - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); /* Release reference from get_ccwdev_by_dev_id() */ put_device(&cdev->dev); break; @@ -1550,7 +1550,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) return 0; out_unlock: - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); out: return rc; } @@ -1846,9 +1846,9 @@ static void ccw_device_todo(struct work_struct *work) css_schedule_eval(sch->schid); fallthrough; case CDEV_TODO_UNREG: - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); sch_set_cdev(sch, NULL); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); ccw_device_unregister(cdev); break; default: diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 3862961697eb..ad90045873e2 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -698,29 +698,29 @@ int ccw_device_stlck(struct ccw_device *cdev) return -ENOMEM; init_completion(&data.done); data.rc = -EIO; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); rc = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); if (rc) goto out_unlock; /* Perform operation. */ cdev->private->state = DEV_STATE_STEAL_LOCK; ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); /* Wait for operation to finish. */ if (wait_for_completion_interruptible(&data.done)) { /* Got a signal. */ - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); ccw_request_cancel(cdev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); wait_for_completion(&data.done); } rc = data.rc; /* Check results. */ - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); cio_disable_subchannel(sch); cdev->private->state = DEV_STATE_BOXED; out_unlock: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); kfree(buffer); return rc; diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c index 826364d2facd..1caedf931a5f 100644 --- a/drivers/s390/cio/eadm_sch.c +++ b/drivers/s390/cio/eadm_sch.c @@ -101,12 +101,12 @@ static void eadm_subchannel_timeout(struct timer_list *t) struct eadm_private *private = from_timer(private, t, timer); struct subchannel *sch = private->sch; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); EADM_LOG(1, "timeout"); EADM_LOG_HEX(1, &sch->schid, sizeof(sch->schid)); if (eadm_subchannel_clear(sch)) EADM_LOG(0, "clear failed"); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); } static void eadm_subchannel_set_timeout(struct subchannel *sch, int expires) @@ -163,16 +163,16 @@ static struct subchannel *eadm_get_idle_sch(void) spin_lock_irqsave(&list_lock, flags); list_for_each_entry(private, &eadm_list, head) { sch = private->sch; - spin_lock(sch->lock); + spin_lock(&sch->lock); if (private->state == EADM_IDLE) { private->state = EADM_BUSY; list_move_tail(&private->head, &eadm_list); - spin_unlock(sch->lock); + spin_unlock(&sch->lock); spin_unlock_irqrestore(&list_lock, flags); return sch; } - spin_unlock(sch->lock); + spin_unlock(&sch->lock); } spin_unlock_irqrestore(&list_lock, flags); @@ -190,7 +190,7 @@ int eadm_start_aob(struct aob *aob) if (!sch) return -EBUSY; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); eadm_subchannel_set_timeout(sch, EADM_TIMEOUT); ret = eadm_subchannel_start(sch, aob); if (!ret) @@ -203,7 +203,7 @@ int eadm_start_aob(struct aob *aob) css_sched_sch_todo(sch, SCH_TODO_EVAL); out_unlock: - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return ret; } @@ -221,7 +221,7 @@ static int eadm_subchannel_probe(struct subchannel *sch) INIT_LIST_HEAD(&private->head); timer_setup(&private->timer, eadm_subchannel_timeout, 0); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); set_eadm_private(sch, private); private->state = EADM_IDLE; private->sch = sch; @@ -229,11 +229,11 @@ static int eadm_subchannel_probe(struct subchannel *sch) ret = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); if (ret) { set_eadm_private(sch, NULL); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); kfree(private); goto out; } - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); spin_lock_irq(&list_lock); list_add(&private->head, &eadm_list); @@ -248,7 +248,7 @@ static void eadm_quiesce(struct subchannel *sch) DECLARE_COMPLETION_ONSTACK(completion); int ret; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); if (private->state != EADM_BUSY) goto disable; @@ -256,11 +256,11 @@ static void eadm_quiesce(struct subchannel *sch) goto disable; private->completion = &completion; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); wait_for_completion_io(&completion); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); private->completion = NULL; disable: @@ -269,7 +269,7 @@ disable: ret = cio_disable_subchannel(sch); } while (ret == -EBUSY); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); } static void eadm_subchannel_remove(struct subchannel *sch) @@ -282,9 +282,9 @@ static void eadm_subchannel_remove(struct subchannel *sch) eadm_quiesce(sch); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); set_eadm_private(sch, NULL); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); kfree(private); } @@ -309,7 +309,7 @@ static int eadm_subchannel_sch_event(struct subchannel *sch, int process) struct eadm_private *private; unsigned long flags; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); if (!device_is_registered(&sch->dev)) goto out_unlock; @@ -325,7 +325,7 @@ static int eadm_subchannel_sch_event(struct subchannel *sch, int process) private->state = EADM_IDLE; out_unlock: - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return 0; } diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 43601816ea4e..a3e25bdd6a76 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -65,14 +65,14 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch) * cancel/halt/clear completion. */ private->completion = &completion; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); if (ret == -EBUSY) wait_for_completion_timeout(&completion, 3*HZ); private->completion = NULL; flush_workqueue(vfio_ccw_work_q); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); ret = cio_disable_subchannel(sch); } while (ret == -EBUSY); @@ -249,7 +249,7 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process) unsigned long flags; int rc = -EAGAIN; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); if (!device_is_registered(&sch->dev)) goto out_unlock; @@ -264,7 +264,7 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process) } out_unlock: - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return rc; } diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 757b73141246..09877b46181d 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -25,7 +25,7 @@ static int fsm_io_helper(struct vfio_ccw_private *private) unsigned long flags; int ret; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); orb = cp_get_orb(&private->cp, sch); if (!orb) { @@ -72,7 +72,7 @@ static int fsm_io_helper(struct vfio_ccw_private *private) ret = ccode; } out: - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return ret; } @@ -83,7 +83,7 @@ static int fsm_do_halt(struct vfio_ccw_private *private) int ccode; int ret; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); VFIO_CCW_TRACE_EVENT(2, "haltIO"); VFIO_CCW_TRACE_EVENT(2, dev_name(&sch->dev)); @@ -111,7 +111,7 @@ static int fsm_do_halt(struct vfio_ccw_private *private) default: ret = ccode; } - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return ret; } @@ -122,7 +122,7 @@ static int fsm_do_clear(struct vfio_ccw_private *private) int ccode; int ret; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); VFIO_CCW_TRACE_EVENT(2, "clearIO"); VFIO_CCW_TRACE_EVENT(2, dev_name(&sch->dev)); @@ -147,7 +147,7 @@ static int fsm_do_clear(struct vfio_ccw_private *private) default: ret = ccode; } - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return ret; } @@ -376,18 +376,18 @@ static void fsm_open(struct vfio_ccw_private *private, struct subchannel *sch = to_subchannel(private->vdev.dev->parent); int ret; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); sch->isc = VFIO_CCW_ISC; ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); if (ret) goto err_unlock; private->state = VFIO_CCW_STATE_IDLE; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return; err_unlock: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); } @@ -397,7 +397,7 @@ static void fsm_close(struct vfio_ccw_private *private, struct subchannel *sch = to_subchannel(private->vdev.dev->parent); int ret; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); if (!sch->schib.pmcw.ena) goto err_unlock; @@ -409,12 +409,12 @@ static void fsm_close(struct vfio_ccw_private *private, goto err_unlock; private->state = VFIO_CCW_STATE_STANDBY; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); cp_free(&private->cp); return; err_unlock: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); } -- cgit v1.2.3 From b2b97a62f055dd638f7f02087331a8380d8f139a Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Mon, 18 Dec 2023 10:58:58 +0100 Subject: Revert "s390: update defconfigs" This reverts commit 7fe228e1866f3a270a1f963c9f2ae3ba1eae7411. CONFIG_IOMMU_DEFAULT_DMA_STRICT option needs to be disabled. Signed-off-by: Alexander Gordeev --- arch/s390/configs/debug_defconfig | 11 +++++------ arch/s390/configs/defconfig | 11 +++++------ arch/s390/configs/zfcpdump_defconfig | 3 ++- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index e37e4119f7bd..438cd92e6080 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -44,7 +44,8 @@ CONFIG_KEXEC_FILE=y CONFIG_KEXEC_SIG=y CONFIG_CRASH_DUMP=y CONFIG_LIVEPATCH=y -CONFIG_MARCH_Z13=y +CONFIG_MARCH_ZEC12=y +CONFIG_TUNE_ZEC12=y CONFIG_NR_CPUS=512 CONFIG_NUMA=y CONFIG_HZ_100=y @@ -75,6 +76,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_SIG_SHA256=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y @@ -91,7 +93,6 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_IOSCHED_BFQ=y CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y -CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y CONFIG_ZSMALLOC_STAT=y CONFIG_SLUB_STATS=y # CONFIG_COMPAT_BRK is not set @@ -117,6 +118,7 @@ CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_XFRM_USER=m CONFIG_NET_KEY=m +CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -596,7 +598,6 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m -CONFIG_IOMMU_DEFAULT_DMA_STRICT=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -618,9 +619,6 @@ CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_DEBUG=y CONFIG_BTRFS_ASSERT=y CONFIG_NILFS2_FS=m -CONFIG_BCACHEFS_FS=y -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_FS_DAX=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FS_ENCRYPTION=y @@ -693,6 +691,7 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=m CONFIG_KEY_NOTIFICATIONS=y CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 38d84bcded30..1b8150e50f6a 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -42,7 +42,8 @@ CONFIG_KEXEC_FILE=y CONFIG_KEXEC_SIG=y CONFIG_CRASH_DUMP=y CONFIG_LIVEPATCH=y -CONFIG_MARCH_Z13=y +CONFIG_MARCH_ZEC12=y +CONFIG_TUNE_ZEC12=y CONFIG_NR_CPUS=512 CONFIG_NUMA=y CONFIG_HZ_100=y @@ -70,6 +71,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_SIG_SHA256=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_WBT=y CONFIG_BLK_CGROUP_IOLATENCY=y @@ -86,7 +88,6 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_IOSCHED_BFQ=y CONFIG_BINFMT_MISC=m CONFIG_ZSWAP=y -CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y CONFIG_ZSMALLOC_STAT=y # CONFIG_COMPAT_BRK is not set CONFIG_MEMORY_HOTPLUG=y @@ -108,6 +109,7 @@ CONFIG_UNIX=y CONFIG_UNIX_DIAG=m CONFIG_XFRM_USER=m CONFIG_NET_KEY=m +CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -585,7 +587,6 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m -CONFIG_IOMMU_DEFAULT_DMA_STRICT=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -604,9 +605,6 @@ CONFIG_OCFS2_FS=m CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m -CONFIG_BCACHEFS_FS=m -CONFIG_BCACHEFS_QUOTA=y -CONFIG_BCACHEFS_POSIX_ACL=y CONFIG_FS_DAX=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FS_ENCRYPTION=y @@ -679,6 +677,7 @@ CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=m CONFIG_KEY_NOTIFICATIONS=y CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_LOCKDOWN_LSM=y diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index 47028450eee1..b831083b4edd 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -9,7 +9,8 @@ CONFIG_BPF_SYSCALL=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_CRASH_DUMP=y -CONFIG_MARCH_Z13=y +CONFIG_MARCH_ZEC12=y +CONFIG_TUNE_ZEC12=y # CONFIG_COMPAT is not set CONFIG_NR_CPUS=2 CONFIG_HZ_100=y -- cgit v1.2.3