arch/powerpc/kexec/file_load_64.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kexec/file_load_64.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kexec/file_load_64.c
Extension
.c
Size
23130 bytes
Lines
857
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct umem_info {
	__be64 *buf;		/* data buffer for usable-memory property */
	u32 size;		/* size allocated for the data buffer */
	u32 max_entries;	/* maximum no. of entries */
	u32 idx;		/* index of current entry */

	/* usable memory ranges to look up */
	unsigned int nr_ranges;
	const struct range *ranges;
};

const struct kexec_file_ops * const kexec_file_loaders[] = {
	&kexec_elf64_ops,
	NULL
};

int arch_check_excluded_range(struct kimage *image, unsigned long start,
			      unsigned long end)
{
	struct crash_mem *emem;
	int i;

	emem = image->arch.exclude_ranges;
	for (i = 0; i < emem->nr_ranges; i++)
		if (start < emem->ranges[i].end && end > emem->ranges[i].start)
			return 1;

	return 0;
}

#ifdef CONFIG_CRASH_DUMP
/**
 * check_realloc_usable_mem - Reallocate buffer if it can't accommodate entries
 * @um_info:                  Usable memory buffer and ranges info.
 * @cnt:                      No. of entries to accommodate.
 *
 * Frees up the old buffer if memory reallocation fails.
 *
 * Returns buffer on success, NULL on error.
 */
static __be64 *check_realloc_usable_mem(struct umem_info *um_info, int cnt)
{
	u32 new_size;
	__be64 *tbuf;

	if ((um_info->idx + cnt) <= um_info->max_entries)
		return um_info->buf;

	new_size = um_info->size + MEM_RANGE_CHUNK_SZ;
	tbuf = krealloc(um_info->buf, new_size, GFP_KERNEL);
	if (tbuf) {
		um_info->buf = tbuf;
		um_info->size = new_size;
		um_info->max_entries = (um_info->size / sizeof(u64));
	}

	return tbuf;
}

/**
 * add_usable_mem - Add the usable memory ranges within the given memory range
 *                  to the buffer
 * @um_info:        Usable memory buffer and ranges info.
 * @base:           Base address of memory range to look for.
 * @end:            End address of memory range to look for.
 *
 * Returns 0 on success, negative errno on error.
 */
static int add_usable_mem(struct umem_info *um_info, u64 base, u64 end)
{
	u64 loc_base, loc_end;
	bool add;
	int i;

	for (i = 0; i < um_info->nr_ranges; i++) {
		add = false;
		loc_base = um_info->ranges[i].start;
		loc_end = um_info->ranges[i].end;
		if (loc_base >= base && loc_end <= end)
			add = true;
		else if (base < loc_end && end > loc_base) {
			if (loc_base < base)
				loc_base = base;
			if (loc_end > end)
				loc_end = end;
			add = true;
		}

		if (add) {
			if (!check_realloc_usable_mem(um_info, 2))

Annotation

Implementation Notes