Skip to content

Commit 9ebfa8d

Browse files
coibyakpm00
authored andcommitted
crash_dump: reuse saved dm crypt keys for CPU/memory hot-plugging
When there are CPU and memory hot un/plugs, the dm crypt keys may need to be reloaded again depending on the solution for crash hotplug support. Currently, there are two solutions. One is to utilizes udev to instruct user space to reload the kdump kernel image and initrd, elfcorehdr and etc again. The other is to only update the elfcorehdr segment introduced in commit 2472627 ("crash: add generic infrastructure for crash hotplug support"). For the 1st solution, the dm crypt keys need to be reloaded again. The user space can write true to /sys/kernel/config/crash_dm_crypt_key/reuse so the stored keys can be re-used. For the 2nd solution, the dm crypt keys don't need to be reloaded. Currently, only x86 supports the 2nd solution. If the 2nd solution gets extended to all arches, this patch can be dropped. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Coiby Xu <[email protected]> Acked-by: Baoquan He <[email protected]> Cc: "Daniel P. Berrange" <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Dave Young <[email protected]> Cc: Jan Pazdziora <[email protected]> Cc: Liu Pingfan <[email protected]> Cc: Milan Broz <[email protected]> Cc: Ondrej Kozina <[email protected]> Cc: Vitaly Kuznetsov <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 479e585 commit 9ebfa8d

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

Documentation/admin-guide/kdump/kdump.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,10 @@ encrypted disk volume. User space can interact with
570570
cat /sys/kernel/config/crash_dm_crypt_keys/count
571571
2
572572

573+
# To support CPU/memory hot-plugging, re-use keys already saved to reserved
574+
# memory
575+
echo true > /sys/kernel/config/crash_dm_crypt_key/reuse
576+
573577
2. Load the dump-capture kernel
574578

575579
3. After the dump-capture kerne get booted, restore the keys to user keyring

kernel/crash_dump_dm_crypt.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ static size_t get_keys_header_size(size_t total_keys)
2828
return struct_size(keys_header, keys, total_keys);
2929
}
3030

31+
static void get_keys_from_kdump_reserved_memory(void)
32+
{
33+
struct keys_header *keys_header_loaded;
34+
35+
arch_kexec_unprotect_crashkres();
36+
37+
keys_header_loaded = kmap_local_page(pfn_to_page(
38+
kexec_crash_image->dm_crypt_keys_addr >> PAGE_SHIFT));
39+
40+
memcpy(keys_header, keys_header_loaded, get_keys_header_size(key_count));
41+
kunmap_local(keys_header_loaded);
42+
arch_kexec_protect_crashkres();
43+
}
44+
3145
static int read_key_from_user_keying(struct dm_crypt_key *dm_key)
3246
{
3347
const struct user_key_payload *ukp;
@@ -150,8 +164,36 @@ static ssize_t config_keys_count_show(struct config_item *item, char *page)
150164

151165
CONFIGFS_ATTR_RO(config_keys_, count);
152166

167+
static bool is_dm_key_reused;
168+
169+
static ssize_t config_keys_reuse_show(struct config_item *item, char *page)
170+
{
171+
return sprintf(page, "%d\n", is_dm_key_reused);
172+
}
173+
174+
static ssize_t config_keys_reuse_store(struct config_item *item,
175+
const char *page, size_t count)
176+
{
177+
if (!kexec_crash_image || !kexec_crash_image->dm_crypt_keys_addr) {
178+
kexec_dprintk(
179+
"dm-crypt keys haven't be saved to crash-reserved memory\n");
180+
return -EINVAL;
181+
}
182+
183+
if (kstrtobool(page, &is_dm_key_reused))
184+
return -EINVAL;
185+
186+
if (is_dm_key_reused)
187+
get_keys_from_kdump_reserved_memory();
188+
189+
return count;
190+
}
191+
192+
CONFIGFS_ATTR(config_keys_, reuse);
193+
153194
static struct configfs_attribute *config_keys_attrs[] = {
154195
&config_keys_attr_count,
196+
&config_keys_attr_reuse,
155197
NULL,
156198
};
157199

@@ -238,10 +280,12 @@ int crash_load_dm_crypt_keys(struct kimage *image)
238280
return -ENOENT;
239281
}
240282

241-
image->dm_crypt_keys_addr = 0;
242-
r = build_keys_header();
243-
if (r)
244-
return r;
283+
if (!is_dm_key_reused) {
284+
image->dm_crypt_keys_addr = 0;
285+
r = build_keys_header();
286+
if (r)
287+
return r;
288+
}
245289

246290
kbuf.buffer = keys_header;
247291
kbuf.bufsz = get_keys_header_size(key_count);

0 commit comments

Comments
 (0)