@@ -316,28 +316,59 @@ static const struct cxl_root_ops acpi_root_ops = {
316
316
.qos_class = cxl_acpi_qos_class ,
317
317
};
318
318
319
+ static void del_cxl_resource (struct resource * res )
320
+ {
321
+ if (!res )
322
+ return ;
323
+ kfree (res -> name );
324
+ kfree (res );
325
+ }
326
+
327
+ static struct resource * alloc_cxl_resource (resource_size_t base ,
328
+ resource_size_t n , int id )
329
+ {
330
+ struct resource * res __free (kfree ) = kzalloc (sizeof (* res ), GFP_KERNEL );
331
+
332
+ if (!res )
333
+ return NULL ;
334
+
335
+ res -> start = base ;
336
+ res -> end = base + n - 1 ;
337
+ res -> flags = IORESOURCE_MEM ;
338
+ res -> name = kasprintf (GFP_KERNEL , "CXL Window %d" , id );
339
+ if (!res -> name )
340
+ return NULL ;
341
+
342
+ return no_free_ptr (res );
343
+ }
344
+
345
+ static int add_or_reset_cxl_resource (struct resource * parent , struct resource * res )
346
+ {
347
+ int rc = insert_resource (parent , res );
348
+
349
+ if (rc )
350
+ del_cxl_resource (res );
351
+ return rc ;
352
+ }
353
+
354
+ DEFINE_FREE (put_cxlrd , struct cxl_root_decoder * ,
355
+ if (!IS_ERR_OR_NULL (_T )) put_device (& _T -> cxlsd .cxld .dev ))
356
+ DEFINE_FREE (del_cxl_resource , struct resource * , if (_T ) del_cxl_resource (_T ))
319
357
static int __cxl_parse_cfmws (struct acpi_cedt_cfmws * cfmws ,
320
358
struct cxl_cfmws_context * ctx )
321
359
{
322
360
int target_map [CXL_DECODER_MAX_INTERLEAVE ];
323
361
struct cxl_port * root_port = ctx -> root_port ;
324
- struct resource * cxl_res = ctx -> cxl_res ;
325
362
struct cxl_cxims_context cxims_ctx ;
326
- struct cxl_root_decoder * cxlrd ;
327
363
struct device * dev = ctx -> dev ;
328
364
cxl_calc_hb_fn cxl_calc_hb ;
329
365
struct cxl_decoder * cxld ;
330
366
unsigned int ways , i , ig ;
331
- struct resource * res ;
332
367
int rc ;
333
368
334
369
rc = cxl_acpi_cfmws_verify (dev , cfmws );
335
- if (rc ) {
336
- dev_err (dev , "CFMWS range %#llx-%#llx not registered\n" ,
337
- cfmws -> base_hpa ,
338
- cfmws -> base_hpa + cfmws -> window_size - 1 );
370
+ if (rc )
339
371
return rc ;
340
- }
341
372
342
373
rc = eiw_to_ways (cfmws -> interleave_ways , & ways );
343
374
if (rc )
@@ -348,38 +379,32 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
348
379
for (i = 0 ; i < ways ; i ++ )
349
380
target_map [i ] = cfmws -> interleave_targets [i ];
350
381
351
- res = kzalloc (sizeof (* res ), GFP_KERNEL );
382
+ struct resource * res __free (del_cxl_resource ) = alloc_cxl_resource (
383
+ cfmws -> base_hpa , cfmws -> window_size , ctx -> id ++ );
352
384
if (!res )
353
385
return - ENOMEM ;
354
386
355
- res -> name = kasprintf (GFP_KERNEL , "CXL Window %d" , ctx -> id ++ );
356
- if (!res -> name )
357
- goto err_name ;
358
-
359
- res -> start = cfmws -> base_hpa ;
360
- res -> end = cfmws -> base_hpa + cfmws -> window_size - 1 ;
361
- res -> flags = IORESOURCE_MEM ;
362
-
363
387
/* add to the local resource tracking to establish a sort order */
364
- rc = insert_resource ( cxl_res , res );
388
+ rc = add_or_reset_cxl_resource ( ctx -> cxl_res , no_free_ptr ( res ) );
365
389
if (rc )
366
- goto err_insert ;
390
+ return rc ;
367
391
368
392
if (cfmws -> interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO )
369
393
cxl_calc_hb = cxl_hb_modulo ;
370
394
else
371
395
cxl_calc_hb = cxl_hb_xor ;
372
396
373
- cxlrd = cxl_root_decoder_alloc (root_port , ways , cxl_calc_hb );
397
+ struct cxl_root_decoder * cxlrd __free (put_cxlrd ) =
398
+ cxl_root_decoder_alloc (root_port , ways , cxl_calc_hb );
374
399
if (IS_ERR (cxlrd ))
375
400
return PTR_ERR (cxlrd );
376
401
377
402
cxld = & cxlrd -> cxlsd .cxld ;
378
403
cxld -> flags = cfmws_to_decoder_flags (cfmws -> restrictions );
379
404
cxld -> target_type = CXL_DECODER_HOSTONLYMEM ;
380
405
cxld -> hpa_range = (struct range ) {
381
- .start = res -> start ,
382
- .end = res -> end ,
406
+ .start = cfmws -> base_hpa ,
407
+ .end = cfmws -> base_hpa + cfmws -> window_size - 1 ,
383
408
};
384
409
cxld -> interleave_ways = ways ;
385
410
/*
@@ -399,30 +424,20 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
399
424
rc = acpi_table_parse_cedt (ACPI_CEDT_TYPE_CXIMS ,
400
425
cxl_parse_cxims , & cxims_ctx );
401
426
if (rc < 0 )
402
- goto err_xormap ;
427
+ return rc ;
403
428
if (!cxlrd -> platform_data ) {
404
429
dev_err (dev , "No CXIMS for HBIG %u\n" , ig );
405
- rc = - EINVAL ;
406
- goto err_xormap ;
430
+ return - EINVAL ;
407
431
}
408
432
}
409
433
}
410
434
411
435
cxlrd -> qos_class = cfmws -> qtg_id ;
412
436
413
437
rc = cxl_decoder_add (cxld , target_map );
414
- err_xormap :
415
438
if (rc )
416
- put_device (& cxld -> dev );
417
- else
418
- rc = cxl_decoder_autoremove (dev , cxld );
419
- return rc ;
420
-
421
- err_insert :
422
- kfree (res -> name );
423
- err_name :
424
- kfree (res );
425
- return - ENOMEM ;
439
+ return rc ;
440
+ return cxl_root_decoder_autoremove (dev , no_free_ptr (cxlrd ));
426
441
}
427
442
428
443
static int cxl_parse_cfmws (union acpi_subtable_headers * header , void * arg ,
@@ -683,12 +698,6 @@ static void cxl_acpi_lock_reset_class(void *dev)
683
698
device_lock_reset_class (dev );
684
699
}
685
700
686
- static void del_cxl_resource (struct resource * res )
687
- {
688
- kfree (res -> name );
689
- kfree (res );
690
- }
691
-
692
701
static void cxl_set_public_resource (struct resource * priv , struct resource * pub )
693
702
{
694
703
priv -> desc = (unsigned long ) pub ;
0 commit comments