diff options
author | Peter Oberparleiter <oberpar@linux.ibm.com> | 2024-03-26 17:03:20 +0100 |
---|---|---|
committer | Alexander Gordeev <agordeev@linux.ibm.com> | 2024-04-12 16:11:28 +0200 |
commit | a817d98dc2e8f9c252bd3e31d86dfe61ec76d23f (patch) | |
tree | c0494788b111044730d00ae8d4210b6e8e0ae216 /drivers/s390 | |
parent | d35c34bb32f2cc4ec0b52e91ad7a8fcab55d7856 (diff) |
s390/cio: rework channel-utilization-block handling
Convert channel-utilization-block (CUB) address variables from separate
named fields to arrays of addresses. Also simplify error handling and
introduce named constants. This is done in preparation of introducing
additional CUBs.
Note: With this change the __packed annotation of secm_area is required
to prevent an alignment hole that would otherwise occur due to the
switch from u32 to dma64_t.
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/chp.c | 8 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.c | 56 | ||||
-rw-r--r-- | drivers/s390/cio/css.h | 10 |
3 files changed, 49 insertions, 25 deletions
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 675d7ed82356..0edb6dd0f105 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -161,12 +161,12 @@ static void chp_measurement_copy_block(struct cmg_entry *buf, struct cmg_entry *entry, reference_buf; int idx; - if (chpid.id < 128) { - area = css->cub_addr1; + if (chpid.id < CSS_CUES_PER_PAGE) { + area = css->cub[0]; idx = chpid.id; } else { - area = css->cub_addr2; - idx = chpid.id - 128; + area = css->cub[1]; + idx = chpid.id - CSS_CUES_PER_PAGE; } entry = area + (idx * sizeof(struct cmg_entry)); do { diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 89e51f197cdd..3344fa996ec4 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -874,19 +874,16 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) u32 : 30; u32 key : 4; u32 : 28; - u32 zeroes1; - dma32_t cub_addr1; - u32 zeroes2; - dma32_t cub_addr2; + dma64_t cub[CSS_NUM_CUB_PAGES]; u32 reserved[13]; struct chsc_header response; u32 status : 8; u32 : 4; u32 fmt : 4; u32 : 16; - } *secm_area; + } __packed *secm_area; unsigned long flags; - int ret, ccode; + int ret, ccode, i; spin_lock_irqsave(&chsc_page_lock, flags); memset(chsc_page, 0, PAGE_SIZE); @@ -895,8 +892,9 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) secm_area->request.code = 0x0016; secm_area->key = PAGE_DEFAULT_KEY >> 4; - secm_area->cub_addr1 = virt_to_dma32(css->cub_addr1); - secm_area->cub_addr2 = virt_to_dma32(css->cub_addr2); + + for (i = 0; i < CSS_NUM_CUB_PAGES; i++) + secm_area->cub[i] = (__force dma64_t)virt_to_dma32(css->cub[i]); secm_area->operation_code = enable ? 0 : 1; @@ -922,19 +920,38 @@ out: return ret; } +static int cub_alloc(struct channel_subsystem *css) +{ + int i; + + for (i = 0; i < CSS_NUM_CUB_PAGES; i++) { + css->cub[i] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!css->cub[i]) + return -ENOMEM; + } + + return 0; +} + +static void cub_free(struct channel_subsystem *css) +{ + int i; + + for (i = 0; i < CSS_NUM_CUB_PAGES; i++) { + free_page((unsigned long)css->cub[i]); + css->cub[i] = NULL; + } +} + int chsc_secm(struct channel_subsystem *css, int enable) { int ret; if (enable && !css->cm_enabled) { - css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!css->cub_addr1 || !css->cub_addr2) { - free_page((unsigned long)css->cub_addr1); - free_page((unsigned long)css->cub_addr2); - return -ENOMEM; - } + ret = cub_alloc(css); + if (ret) + goto out; } ret = __chsc_do_secm(css, enable); if (!ret) { @@ -948,10 +965,11 @@ chsc_secm(struct channel_subsystem *css, int enable) } else chsc_remove_cmg_attr(css); } - if (!css->cm_enabled) { - free_page((unsigned long)css->cub_addr1); - free_page((unsigned long)css->cub_addr2); - } + +out: + if (!css->cm_enabled) + cub_free(css); + return ret; } diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index ea5550554297..aca11dacb224 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -35,6 +35,13 @@ #define SNID_STATE3_SINGLE_PATH 0 /* + * Miscellaneous constants + */ + +#define CSS_NUM_CUB_PAGES 2 +#define CSS_CUES_PER_PAGE 128 + +/* * Conditions used to specify which subchannels need evaluation */ enum css_eval_cond { @@ -122,8 +129,7 @@ struct channel_subsystem { struct mutex mutex; /* channel measurement related */ int cm_enabled; - void *cub_addr1; - void *cub_addr2; + void *cub[CSS_NUM_CUB_PAGES]; /* for orphaned ccw devices */ struct subchannel *pseudo_subchannel; }; |