From: Rosen Penev Date: Fri, 27 Mar 2026 02:48:28 +0000 (-0700) Subject: EDAC/mc: Use kzalloc_flex() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62ba6d66b22356a6a78fd015c37fd108710dfc32;p=thirdparty%2Fkernel%2Flinux.git EDAC/mc: Use kzalloc_flex() Convert struct mem_ctl_info to use flex array and use the new flex array helpers to enable runtime bounds checking, including annotating the array length member with __counted_by() for extra runtime analysis when requested. Move memcpy() after the counter assignment so that it is initialized before the first reference to the flex array, as the new attribute requires. [ bp: Heavily massage commit message. ] Signed-off-by: Rosen Penev Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Yazen Ghannam Reviewed-by: Qiuxu Zhuo Link: https://patch.msgid.link/20260327024828.7377-1-rosenp@gmail.com --- diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 29e9828422bb0..07d3f73bcd237 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -203,7 +203,6 @@ static void mci_release(struct device *dev) kfree(mci->csrows); } kfree(mci->pvt_info); - kfree(mci->layers); kfree(mci); } @@ -361,13 +360,12 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, per_rank = true; } - mci = kzalloc_obj(struct mem_ctl_info); + mci = kzalloc_flex(*mci, layers, n_layers); if (!mci) return NULL; - mci->layers = kzalloc_objs(struct edac_mc_layer, n_layers); - if (!mci->layers) - goto error; + mci->n_layers = n_layers; + memcpy(mci->layers, layers, sizeof(*layer) * n_layers); mci->pvt_info = kzalloc(sz_pvt, GFP_KERNEL); if (!mci->pvt_info) @@ -379,8 +377,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, /* setup index and various internal pointers */ mci->mc_idx = mc_num; mci->tot_dimms = tot_dimms; - mci->n_layers = n_layers; - memcpy(mci->layers, layers, sizeof(*layer) * n_layers); mci->nr_csrows = tot_csrows; mci->num_cschannel = tot_channels; mci->csbased = per_rank; diff --git a/include/linux/edac.h b/include/linux/edac.h index fa32f2aca22fd..deba46b3ee25d 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -541,17 +541,6 @@ struct mem_ctl_info { struct csrow_info **csrows; unsigned int nr_csrows, num_cschannel; - /* - * Memory Controller hierarchy - * - * There are basically two types of memory controller: the ones that - * sees memory sticks ("dimms"), and the ones that sees memory ranks. - * All old memory controllers enumerate memories per rank, but most - * of the recent drivers enumerate memories per DIMM, instead. - * When the memory controller is per rank, csbased is true. - */ - unsigned int n_layers; - struct edac_mc_layer *layers; bool csbased; /* @@ -609,6 +598,18 @@ struct mem_ctl_info { u8 fake_inject_layer[EDAC_MAX_LAYERS]; bool fake_inject_ue; u16 fake_inject_count; + + /* + * Memory Controller hierarchy + * + * There are basically two types of memory controller: the ones that + * sees memory sticks ("dimms"), and the ones that sees memory ranks. + * All old memory controllers enumerate memories per rank, but most + * of the recent drivers enumerate memories per DIMM, instead. + * When the memory controller is per rank, csbased is true. + */ + unsigned int n_layers; + struct edac_mc_layer layers[] __counted_by(n_layers); }; #define mci_for_each_dimm(mci, dimm) \