@@ -149,8 +149,8 @@ static int to_interleave_ways(u32 ctrl)
149149 }
150150}
151151
152- static void init_hdm_decoder (struct cxl_decoder * cxld , int * target_map ,
153- void __iomem * hdm , int which )
152+ static int init_hdm_decoder (struct cxl_port * port , struct cxl_decoder * cxld ,
153+ int * target_map , void __iomem * hdm , int which )
154154{
155155 u64 size , base ;
156156 u32 ctrl ;
@@ -166,6 +166,11 @@ static void init_hdm_decoder(struct cxl_decoder *cxld, int *target_map,
166166
167167 if (!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED ))
168168 size = 0 ;
169+ if (base == U64_MAX || size == U64_MAX ) {
170+ dev_warn (& port -> dev , "decoder%d.%d: Invalid resource range\n" ,
171+ port -> id , cxld -> id );
172+ return - ENXIO ;
173+ }
169174
170175 cxld -> decoder_range = (struct range ) {
171176 .start = base ,
@@ -179,6 +184,12 @@ static void init_hdm_decoder(struct cxl_decoder *cxld, int *target_map,
179184 cxld -> flags |= CXL_DECODER_F_LOCK ;
180185 }
181186 cxld -> interleave_ways = to_interleave_ways (ctrl );
187+ if (!cxld -> interleave_ways ) {
188+ dev_warn (& port -> dev ,
189+ "decoder%d.%d: Invalid interleave ways (ctrl: %#x)\n" ,
190+ port -> id , cxld -> id , ctrl );
191+ return - ENXIO ;
192+ }
182193 cxld -> interleave_granularity = to_interleave_granularity (ctrl );
183194
184195 if (FIELD_GET (CXL_HDM_DECODER0_CTRL_TYPE , ctrl ))
@@ -187,12 +198,14 @@ static void init_hdm_decoder(struct cxl_decoder *cxld, int *target_map,
187198 cxld -> target_type = CXL_DECODER_ACCELERATOR ;
188199
189200 if (is_cxl_endpoint (to_cxl_port (cxld -> dev .parent )))
190- return ;
201+ return 0 ;
191202
192203 target_list .value =
193204 ioread64_hi_lo (hdm + CXL_HDM_DECODER0_TL_LOW (which ));
194205 for (i = 0 ; i < cxld -> interleave_ways ; i ++ )
195206 target_map [i ] = target_list .target_id [i ];
207+
208+ return 0 ;
196209}
197210
198211/**
@@ -203,7 +216,7 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
203216{
204217 void __iomem * hdm = cxlhdm -> regs .hdm_decoder ;
205218 struct cxl_port * port = cxlhdm -> port ;
206- int i , committed ;
219+ int i , committed , failed ;
207220 u32 ctrl ;
208221
209222 /*
@@ -223,7 +236,7 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
223236 if (committed != cxlhdm -> decoder_count )
224237 msleep (20 );
225238
226- for (i = 0 ; i < cxlhdm -> decoder_count ; i ++ ) {
239+ for (i = 0 , failed = 0 ; i < cxlhdm -> decoder_count ; i ++ ) {
227240 int target_map [CXL_DECODER_MAX_INTERLEAVE ] = { 0 };
228241 int rc , target_count = cxlhdm -> target_count ;
229242 struct cxl_decoder * cxld ;
@@ -238,7 +251,13 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
238251 return PTR_ERR (cxld );
239252 }
240253
241- init_hdm_decoder (cxld , target_map , cxlhdm -> regs .hdm_decoder , i );
254+ rc = init_hdm_decoder (port , cxld , target_map ,
255+ cxlhdm -> regs .hdm_decoder , i );
256+ if (rc ) {
257+ put_device (& cxld -> dev );
258+ failed ++ ;
259+ continue ;
260+ }
242261 rc = add_hdm_decoder (port , cxld , target_map );
243262 if (rc ) {
244263 dev_warn (& port -> dev ,
@@ -247,6 +266,11 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
247266 }
248267 }
249268
269+ if (failed == cxlhdm -> decoder_count ) {
270+ dev_err (& port -> dev , "No valid decoders found\n" );
271+ return - ENXIO ;
272+ }
273+
250274 return 0 ;
251275}
252276EXPORT_SYMBOL_NS_GPL (devm_cxl_enumerate_decoders , CXL );
0 commit comments