From: Jan Höppner hoeppner@linux.ibm.com
commit 709192d531e5b0a91f20aa14abfe2fc27ddd47af upstream.
A discard request that writes zeros using the global kernel internal ZERO_PAGE will fail for machines with more than 2GB of memory due to the location of the ZERO_PAGE.
Fix this by using a driver owned global zero page allocated with GFP_DMA flag set.
Fixes: 28b841b3a7cb ("s390/dasd: Add discard support for FBA devices") Signed-off-by: Jan Höppner hoeppner@linux.ibm.com Reviewed-by: Stefan Haberland sth@linux.ibm.com Cc: stable@vger.kernel.org # 4.14+ Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/s390/block/dasd_fba.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -39,6 +39,7 @@ MODULE_LICENSE("GPL");
static struct dasd_discipline dasd_fba_discipline; +static void *dasd_fba_zero_page;
struct dasd_fba_private { struct dasd_fba_characteristics rdc_data; @@ -269,7 +270,7 @@ static void ccw_write_zero(struct ccw1 * ccw->cmd_code = DASD_FBA_CCW_WRITE; ccw->flags |= CCW_FLAG_SLI; ccw->count = count; - ccw->cda = (__u32) (addr_t) page_to_phys(ZERO_PAGE(0)); + ccw->cda = (__u32) (addr_t) dasd_fba_zero_page; }
/* @@ -808,6 +809,11 @@ dasd_fba_init(void) int ret;
ASCEBC(dasd_fba_discipline.ebcname, 4); + + dasd_fba_zero_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!dasd_fba_zero_page) + return -ENOMEM; + ret = ccw_driver_register(&dasd_fba_driver); if (!ret) wait_for_device_probe(); @@ -819,6 +825,7 @@ static void __exit dasd_fba_cleanup(void) { ccw_driver_unregister(&dasd_fba_driver); + free_page((unsigned long)dasd_fba_zero_page); }
module_init(dasd_fba_init);