diff options
author | Quanquan Cao <caoqq@fujitsu.com> | 2024-01-24 12:15:26 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-02-01 03:17:12 +0300 |
commit | ec745eeff4d2824e983f6f00bbff2a8a8003972b (patch) | |
tree | ed81d8b7b130cb6dd6b176f7a31a5090a8fe13cc /drivers/cxl | |
parent | 1111abee590ddc3f86e5fb119a9def756c217bb1 (diff) | |
download | linux-ec745eeff4d2824e983f6f00bbff2a8a8003972b.tar.xz |
cxl/region:Fix overflow issue in alloc_hpa()
commit d76779dd3681c01a4c6c3cae4d0627c9083e0ee6 upstream.
Creating a region with 16 memory devices caused a problem. The div_u64_rem
function, used for dividing an unsigned 64-bit number by a 32-bit one,
faced an issue when SZ_256M * p->interleave_ways. The result surpassed
the maximum limit of the 32-bit divisor (4G), leading to an overflow
and a remainder of 0.
note: At this point, p->interleave_ways is 16, meaning 16 * 256M = 4G
To fix this issue, I replaced the div_u64_rem function with div64_u64_rem
and adjusted the type of the remainder.
Signed-off-by: Quanquan Cao <caoqq@fujitsu.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Fixes: 23a22cd1c98b ("cxl/region: Allocate HPA capacity to regions")
Cc: <stable@vger.kernel.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/cxl')
-rw-r--r-- | drivers/cxl/core/region.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 2f7187dbfa2d..5b7d848a6f01 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -450,7 +450,7 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size) struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_region_params *p = &cxlr->params; struct resource *res; - u32 remainder = 0; + u64 remainder = 0; lockdep_assert_held_write(&cxl_region_rwsem); @@ -470,7 +470,7 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size) (cxlr->mode == CXL_DECODER_PMEM && uuid_is_null(&p->uuid))) return -ENXIO; - div_u64_rem(size, SZ_256M * p->interleave_ways, &remainder); + div64_u64_rem(size, (u64)SZ_256M * p->interleave_ways, &remainder); if (remainder) return -EINVAL; |