@@ -73,6 +73,18 @@ const guid_t *to_nfit_uuid(enum nfit_uuids id)
73
73
}
74
74
EXPORT_SYMBOL (to_nfit_uuid );
75
75
76
+ static const guid_t * to_nfit_bus_uuid (int family )
77
+ {
78
+ if (WARN_ONCE (family == NVDIMM_BUS_FAMILY_NFIT ,
79
+ "only secondary bus families can be translated\n" ))
80
+ return NULL ;
81
+ /*
82
+ * The index of bus UUIDs starts immediately following the last
83
+ * NVDIMM/leaf family.
84
+ */
85
+ return to_nfit_uuid (family + NVDIMM_FAMILY_MAX );
86
+ }
87
+
76
88
static struct acpi_device * to_acpi_dev (struct acpi_nfit_desc * acpi_desc )
77
89
{
78
90
struct nvdimm_bus_descriptor * nd_desc = & acpi_desc -> nd_desc ;
@@ -362,24 +374,8 @@ static u8 nfit_dsm_revid(unsigned family, unsigned func)
362
374
{
363
375
static const u8 revid_table [NVDIMM_FAMILY_MAX + 1 ][NVDIMM_CMD_MAX + 1 ] = {
364
376
[NVDIMM_FAMILY_INTEL ] = {
365
- [NVDIMM_INTEL_GET_MODES ] = 2 ,
366
- [NVDIMM_INTEL_GET_FWINFO ] = 2 ,
367
- [NVDIMM_INTEL_START_FWUPDATE ] = 2 ,
368
- [NVDIMM_INTEL_SEND_FWUPDATE ] = 2 ,
369
- [NVDIMM_INTEL_FINISH_FWUPDATE ] = 2 ,
370
- [NVDIMM_INTEL_QUERY_FWUPDATE ] = 2 ,
371
- [NVDIMM_INTEL_SET_THRESHOLD ] = 2 ,
372
- [NVDIMM_INTEL_INJECT_ERROR ] = 2 ,
373
- [NVDIMM_INTEL_GET_SECURITY_STATE ] = 2 ,
374
- [NVDIMM_INTEL_SET_PASSPHRASE ] = 2 ,
375
- [NVDIMM_INTEL_DISABLE_PASSPHRASE ] = 2 ,
376
- [NVDIMM_INTEL_UNLOCK_UNIT ] = 2 ,
377
- [NVDIMM_INTEL_FREEZE_LOCK ] = 2 ,
378
- [NVDIMM_INTEL_SECURE_ERASE ] = 2 ,
379
- [NVDIMM_INTEL_OVERWRITE ] = 2 ,
380
- [NVDIMM_INTEL_QUERY_OVERWRITE ] = 2 ,
381
- [NVDIMM_INTEL_SET_MASTER_PASSPHRASE ] = 2 ,
382
- [NVDIMM_INTEL_MASTER_SECURE_ERASE ] = 2 ,
377
+ [NVDIMM_INTEL_GET_MODES ...
378
+ NVDIMM_INTEL_FW_ACTIVATE_ARM ] = 2 ,
383
379
},
384
380
};
385
381
u8 id ;
@@ -406,7 +402,7 @@ static bool payload_dumpable(struct nvdimm *nvdimm, unsigned int func)
406
402
}
407
403
408
404
static int cmd_to_func (struct nfit_mem * nfit_mem , unsigned int cmd ,
409
- struct nd_cmd_pkg * call_pkg )
405
+ struct nd_cmd_pkg * call_pkg , int * family )
410
406
{
411
407
if (call_pkg ) {
412
408
int i ;
@@ -417,6 +413,7 @@ static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
417
413
for (i = 0 ; i < ARRAY_SIZE (call_pkg -> nd_reserved2 ); i ++ )
418
414
if (call_pkg -> nd_reserved2 [i ])
419
415
return - EINVAL ;
416
+ * family = call_pkg -> nd_family ;
420
417
return call_pkg -> nd_command ;
421
418
}
422
419
@@ -450,13 +447,14 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
450
447
acpi_handle handle ;
451
448
const guid_t * guid ;
452
449
int func , rc , i ;
450
+ int family = 0 ;
453
451
454
452
if (cmd_rc )
455
453
* cmd_rc = - EINVAL ;
456
454
457
455
if (cmd == ND_CMD_CALL )
458
456
call_pkg = buf ;
459
- func = cmd_to_func (nfit_mem , cmd , call_pkg );
457
+ func = cmd_to_func (nfit_mem , cmd , call_pkg , & family );
460
458
if (func < 0 )
461
459
return func ;
462
460
@@ -478,9 +476,17 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
478
476
479
477
cmd_name = nvdimm_bus_cmd_name (cmd );
480
478
cmd_mask = nd_desc -> cmd_mask ;
481
- dsm_mask = acpi_desc -> bus_dsm_mask ;
479
+ if (cmd == ND_CMD_CALL && call_pkg -> nd_family ) {
480
+ family = call_pkg -> nd_family ;
481
+ if (!test_bit (family , & nd_desc -> bus_family_mask ))
482
+ return - EINVAL ;
483
+ dsm_mask = acpi_desc -> family_dsm_mask [family ];
484
+ guid = to_nfit_bus_uuid (family );
485
+ } else {
486
+ dsm_mask = acpi_desc -> bus_dsm_mask ;
487
+ guid = to_nfit_uuid (NFIT_DEV_BUS );
488
+ }
482
489
desc = nd_cmd_bus_desc (cmd );
483
- guid = to_nfit_uuid (NFIT_DEV_BUS );
484
490
handle = adev -> handle ;
485
491
dimm_name = "bus" ;
486
492
}
@@ -516,8 +522,8 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
516
522
in_buf .buffer .length = call_pkg -> nd_size_in ;
517
523
}
518
524
519
- dev_dbg (dev , "%s cmd: %d: func: %d input length: %d\n" ,
520
- dimm_name , cmd , func , in_buf .buffer .length );
525
+ dev_dbg (dev , "%s cmd: %d: family: %d func: %d input length: %d\n" ,
526
+ dimm_name , cmd , family , func , in_buf .buffer .length );
521
527
if (payload_dumpable (nvdimm , func ))
522
528
print_hex_dump_debug ("nvdimm in " , DUMP_PREFIX_OFFSET , 4 , 4 ,
523
529
in_buf .buffer .pointer ,
@@ -2153,14 +2159,21 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
2153
2159
{
2154
2160
struct nvdimm_bus_descriptor * nd_desc = & acpi_desc -> nd_desc ;
2155
2161
const guid_t * guid = to_nfit_uuid (NFIT_DEV_BUS );
2162
+ unsigned long dsm_mask , * mask ;
2156
2163
struct acpi_device * adev ;
2157
- unsigned long dsm_mask ;
2158
2164
int i ;
2159
2165
2160
- nd_desc -> cmd_mask = acpi_desc -> bus_cmd_force_en ;
2161
2166
set_bit (ND_CMD_CALL , & nd_desc -> cmd_mask );
2162
2167
set_bit (NVDIMM_BUS_FAMILY_NFIT , & nd_desc -> bus_family_mask );
2163
2168
2169
+ /* enable nfit_test to inject bus command emulation */
2170
+ if (acpi_desc -> bus_cmd_force_en ) {
2171
+ nd_desc -> cmd_mask = acpi_desc -> bus_cmd_force_en ;
2172
+ mask = & nd_desc -> bus_family_mask ;
2173
+ if (acpi_desc -> family_dsm_mask [NVDIMM_BUS_FAMILY_INTEL ])
2174
+ set_bit (NVDIMM_BUS_FAMILY_INTEL , mask );
2175
+ }
2176
+
2164
2177
adev = to_acpi_dev (acpi_desc );
2165
2178
if (!adev )
2166
2179
return ;
@@ -2181,6 +2194,14 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
2181
2194
for_each_set_bit (i , & dsm_mask , BITS_PER_LONG )
2182
2195
if (acpi_check_dsm (adev -> handle , guid , 1 , 1ULL << i ))
2183
2196
set_bit (i , & acpi_desc -> bus_dsm_mask );
2197
+
2198
+ /* Enumerate allowed NVDIMM_BUS_FAMILY_INTEL commands */
2199
+ dsm_mask = NVDIMM_BUS_INTEL_FW_ACTIVATE_CMDMASK ;
2200
+ guid = to_nfit_bus_uuid (NVDIMM_BUS_FAMILY_INTEL );
2201
+ mask = & acpi_desc -> family_dsm_mask [NVDIMM_BUS_FAMILY_INTEL ];
2202
+ for_each_set_bit (i , & dsm_mask , BITS_PER_LONG )
2203
+ if (acpi_check_dsm (adev -> handle , guid , 1 , 1ULL << i ))
2204
+ set_bit (i , mask );
2184
2205
}
2185
2206
2186
2207
static ssize_t range_index_show (struct device * dev ,
@@ -3492,7 +3513,10 @@ static int __acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
3492
3513
return 0 ;
3493
3514
}
3494
3515
3495
- /* prevent security commands from being issued via ioctl */
3516
+ /*
3517
+ * Prevent security and firmware activate commands from being issued via
3518
+ * ioctl.
3519
+ */
3496
3520
static int acpi_nfit_clear_to_send (struct nvdimm_bus_descriptor * nd_desc ,
3497
3521
struct nvdimm * nvdimm , unsigned int cmd , void * buf )
3498
3522
{
@@ -3503,10 +3527,15 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
3503
3527
call_pkg -> nd_family == NVDIMM_FAMILY_INTEL ) {
3504
3528
func = call_pkg -> nd_command ;
3505
3529
if (func > NVDIMM_CMD_MAX ||
3506
- (1 << func ) & NVDIMM_INTEL_SECURITY_CMDMASK )
3530
+ (1 << func ) & NVDIMM_INTEL_DENY_CMDMASK )
3507
3531
return - EOPNOTSUPP ;
3508
3532
}
3509
3533
3534
+ /* block all non-nfit bus commands */
3535
+ if (!nvdimm && cmd == ND_CMD_CALL &&
3536
+ call_pkg -> nd_family != NVDIMM_BUS_FAMILY_NFIT )
3537
+ return - EOPNOTSUPP ;
3538
+
3510
3539
return __acpi_nfit_clear_to_send (nd_desc , nvdimm , cmd );
3511
3540
}
3512
3541
@@ -3798,6 +3827,7 @@ static __init int nfit_init(void)
3798
3827
guid_parse (UUID_NFIT_DIMM_N_HPE2 , & nfit_uuid [NFIT_DEV_DIMM_N_HPE2 ]);
3799
3828
guid_parse (UUID_NFIT_DIMM_N_MSFT , & nfit_uuid [NFIT_DEV_DIMM_N_MSFT ]);
3800
3829
guid_parse (UUID_NFIT_DIMM_N_HYPERV , & nfit_uuid [NFIT_DEV_DIMM_N_HYPERV ]);
3830
+ guid_parse (UUID_INTEL_BUS , & nfit_uuid [NFIT_BUS_INTEL ]);
3801
3831
3802
3832
nfit_wq = create_singlethread_workqueue ("nfit" );
3803
3833
if (!nfit_wq )
0 commit comments