1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2021 Google LLC
5 * sysfs support for blk-crypto. This file contains the code which exports the
6 * crypto capabilities of devices via /sys/block/$disk/queue/crypto/.
9 #include <linux/blk-crypto-profile.h>
11 #include "blk-crypto-internal.h"
13 struct blk_crypto_kobj
{
15 struct blk_crypto_profile
*profile
;
18 struct blk_crypto_attr
{
19 struct attribute attr
;
20 ssize_t (*show
)(struct blk_crypto_profile
*profile
,
21 struct blk_crypto_attr
*attr
, char *page
);
24 static struct blk_crypto_profile
*kobj_to_crypto_profile(struct kobject
*kobj
)
26 return container_of(kobj
, struct blk_crypto_kobj
, kobj
)->profile
;
29 static struct blk_crypto_attr
*attr_to_crypto_attr(struct attribute
*attr
)
31 return container_of(attr
, struct blk_crypto_attr
, attr
);
34 static ssize_t
max_dun_bits_show(struct blk_crypto_profile
*profile
,
35 struct blk_crypto_attr
*attr
, char *page
)
37 return sysfs_emit(page
, "%u\n", 8 * profile
->max_dun_bytes_supported
);
40 static ssize_t
num_keyslots_show(struct blk_crypto_profile
*profile
,
41 struct blk_crypto_attr
*attr
, char *page
)
43 return sysfs_emit(page
, "%u\n", profile
->num_slots
);
46 #define BLK_CRYPTO_RO_ATTR(_name) \
47 static struct blk_crypto_attr _name##_attr = __ATTR_RO(_name)
49 BLK_CRYPTO_RO_ATTR(max_dun_bits
);
50 BLK_CRYPTO_RO_ATTR(num_keyslots
);
52 static struct attribute
*blk_crypto_attrs
[] = {
53 &max_dun_bits_attr
.attr
,
54 &num_keyslots_attr
.attr
,
58 static const struct attribute_group blk_crypto_attr_group
= {
59 .attrs
= blk_crypto_attrs
,
63 * The encryption mode attributes. To avoid hard-coding the list of encryption
64 * modes, these are initialized at boot time by blk_crypto_sysfs_init().
66 static struct blk_crypto_attr __blk_crypto_mode_attrs
[BLK_ENCRYPTION_MODE_MAX
];
67 static struct attribute
*blk_crypto_mode_attrs
[BLK_ENCRYPTION_MODE_MAX
+ 1];
69 static umode_t
blk_crypto_mode_is_visible(struct kobject
*kobj
,
70 struct attribute
*attr
, int n
)
72 struct blk_crypto_profile
*profile
= kobj_to_crypto_profile(kobj
);
73 struct blk_crypto_attr
*a
= attr_to_crypto_attr(attr
);
74 int mode_num
= a
- __blk_crypto_mode_attrs
;
76 if (profile
->modes_supported
[mode_num
])
81 static ssize_t
blk_crypto_mode_show(struct blk_crypto_profile
*profile
,
82 struct blk_crypto_attr
*attr
, char *page
)
84 int mode_num
= attr
- __blk_crypto_mode_attrs
;
86 return sysfs_emit(page
, "0x%x\n", profile
->modes_supported
[mode_num
]);
89 static const struct attribute_group blk_crypto_modes_attr_group
= {
91 .attrs
= blk_crypto_mode_attrs
,
92 .is_visible
= blk_crypto_mode_is_visible
,
95 static const struct attribute_group
*blk_crypto_attr_groups
[] = {
96 &blk_crypto_attr_group
,
97 &blk_crypto_modes_attr_group
,
101 static ssize_t
blk_crypto_attr_show(struct kobject
*kobj
,
102 struct attribute
*attr
, char *page
)
104 struct blk_crypto_profile
*profile
= kobj_to_crypto_profile(kobj
);
105 struct blk_crypto_attr
*a
= attr_to_crypto_attr(attr
);
107 return a
->show(profile
, a
, page
);
110 static const struct sysfs_ops blk_crypto_attr_ops
= {
111 .show
= blk_crypto_attr_show
,
114 static void blk_crypto_release(struct kobject
*kobj
)
116 kfree(container_of(kobj
, struct blk_crypto_kobj
, kobj
));
119 static const struct kobj_type blk_crypto_ktype
= {
120 .default_groups
= blk_crypto_attr_groups
,
121 .sysfs_ops
= &blk_crypto_attr_ops
,
122 .release
= blk_crypto_release
,
126 * If the request_queue has a blk_crypto_profile, create the "crypto"
127 * subdirectory in sysfs (/sys/block/$disk/queue/crypto/).
129 int blk_crypto_sysfs_register(struct gendisk
*disk
)
131 struct request_queue
*q
= disk
->queue
;
132 struct blk_crypto_kobj
*obj
;
135 if (!q
->crypto_profile
)
138 obj
= kzalloc(sizeof(*obj
), GFP_KERNEL
);
141 obj
->profile
= q
->crypto_profile
;
143 err
= kobject_init_and_add(&obj
->kobj
, &blk_crypto_ktype
,
144 &disk
->queue_kobj
, "crypto");
146 kobject_put(&obj
->kobj
);
149 q
->crypto_kobject
= &obj
->kobj
;
153 void blk_crypto_sysfs_unregister(struct gendisk
*disk
)
155 kobject_put(disk
->queue
->crypto_kobject
);
158 static int __init
blk_crypto_sysfs_init(void)
162 BUILD_BUG_ON(BLK_ENCRYPTION_MODE_INVALID
!= 0);
163 for (i
= 1; i
< BLK_ENCRYPTION_MODE_MAX
; i
++) {
164 struct blk_crypto_attr
*attr
= &__blk_crypto_mode_attrs
[i
];
166 attr
->attr
.name
= blk_crypto_modes
[i
].name
;
167 attr
->attr
.mode
= 0444;
168 attr
->show
= blk_crypto_mode_show
;
169 blk_crypto_mode_attrs
[i
- 1] = &attr
->attr
;
173 subsys_initcall(blk_crypto_sysfs_init
);