kernel/liveupdate/kexec_handover.c

Source file repositories/reference/linux-study-clean/kernel/liveupdate/kexec_handover.c

File Facts

System
Linux kernel
Corpus path
kernel/liveupdate/kexec_handover.c
Extension
.c
Size
46490 bytes
Lines
1785
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kho_out {
	void *fdt;
	struct mutex lock; /* protects KHO FDT */

	struct kho_radix_tree radix_tree;
	struct kho_debugfs dbg;
};

static struct kho_out kho_out = {
	.lock = __MUTEX_INITIALIZER(kho_out.lock),
	.radix_tree = {
		.lock = __MUTEX_INITIALIZER(kho_out.radix_tree.lock),
	},
};

/**
 * kho_radix_encode_key - Encodes a physical address and order into a radix key.
 * @phys: The physical address of the page.
 * @order: The order of the page.
 *
 * This function combines a page's physical address and its order into a
 * single unsigned long, which is used as a key for all radix tree
 * operations.
 *
 * Return: The encoded unsigned long radix key.
 */
static unsigned long kho_radix_encode_key(phys_addr_t phys, unsigned int order)
{
	/* Order bits part */
	unsigned long h = 1UL << (KHO_ORDER_0_LOG2 - order);
	/* Shifted physical address part */
	unsigned long l = phys >> (PAGE_SHIFT + order);

	return h | l;
}

/**
 * kho_radix_decode_key - Decodes a radix key back into a physical address and order.
 * @key: The unsigned long key to decode.
 * @order: An output parameter, a pointer to an unsigned int where the decoded
 *         page order will be stored.
 *
 * This function reverses the encoding performed by kho_radix_encode_key(),
 * extracting the original physical address and page order from a given key.
 *
 * Return: The decoded physical address.
 */
static phys_addr_t kho_radix_decode_key(unsigned long key, unsigned int *order)
{
	unsigned int order_bit = fls64(key);
	phys_addr_t phys;

	/* order_bit is numbered starting at 1 from fls64 */
	*order = KHO_ORDER_0_LOG2 - order_bit + 1;
	/* The order is discarded by the shift */
	phys = key << (PAGE_SHIFT + *order);

	return phys;
}

static unsigned long kho_radix_get_bitmap_index(unsigned long key)
{
	return key % (1 << KHO_BITMAP_SIZE_LOG2);
}

static unsigned long kho_radix_get_table_index(unsigned long key,
					       unsigned int level)
{
	int s;

	s = ((level - 1) * KHO_TABLE_SIZE_LOG2) + KHO_BITMAP_SIZE_LOG2;
	return (key >> s) % (1 << KHO_TABLE_SIZE_LOG2);
}

/**
 * kho_radix_add_page - Marks a page as preserved in the radix tree.
 * @tree: The KHO radix tree.
 * @pfn: The page frame number of the page to preserve.
 * @order: The order of the page.
 *
 * This function traverses the radix tree based on the key derived from @pfn
 * and @order. It sets the corresponding bit in the leaf bitmap to mark the
 * page for preservation. If intermediate nodes do not exist along the path,
 * they are allocated and added to the tree.
 *
 * Return: 0 on success, or a negative error code on failure.
 */
int kho_radix_add_page(struct kho_radix_tree *tree,
		       unsigned long pfn, unsigned int order)
{

Annotation

Implementation Notes