arch/s390/mm/pgalloc.c

Source file repositories/reference/linux-study-clean/arch/s390/mm/pgalloc.c

File Facts

System
Linux kernel
Corpus path
arch/s390/mm/pgalloc.c
Extension
.c
Size
11580 bytes
Lines
458
Domain
Architecture Layer
Bucket
arch/s390
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

if (*ste & _SEGMENT_ENTRY_INVALID) {
			if (!alloc)
				continue;
			table = base_pgt_alloc();
			if (!table)
				return -ENOMEM;
			*ste = __pa(table) | _SEGMENT_ENTRY;
		}
		table = __va(*ste & _SEGMENT_ENTRY_ORIGIN);
		rc = base_page_walk(table, addr, next, alloc);
		if (rc)
			return rc;
		if (!alloc)
			base_pgt_free(table);
		cond_resched();
	} while (ste++, addr = next, addr < end);
	return 0;
}

static int base_region3_walk(unsigned long *origin, unsigned long addr,
			     unsigned long end, int alloc)
{
	unsigned long *rtte, next, *table;
	int rc;

	rtte = origin;
	rtte += (addr & _REGION3_INDEX) >> _REGION3_SHIFT;
	do {
		next = base_region3_addr_end(addr, end);
		if (*rtte & _REGION_ENTRY_INVALID) {
			if (!alloc)
				continue;
			table = base_crst_alloc(_SEGMENT_ENTRY_EMPTY);
			if (!table)
				return -ENOMEM;
			*rtte = __pa(table) | _REGION3_ENTRY;
		}
		table = __va(*rtte & _REGION_ENTRY_ORIGIN);
		rc = base_segment_walk(table, addr, next, alloc);
		if (rc)
			return rc;
		if (!alloc)
			base_crst_free(table);
	} while (rtte++, addr = next, addr < end);
	return 0;
}

static int base_region2_walk(unsigned long *origin, unsigned long addr,
			     unsigned long end, int alloc)
{
	unsigned long *rste, next, *table;
	int rc;

	rste = origin;
	rste += (addr & _REGION2_INDEX) >> _REGION2_SHIFT;
	do {
		next = base_region2_addr_end(addr, end);
		if (*rste & _REGION_ENTRY_INVALID) {
			if (!alloc)
				continue;
			table = base_crst_alloc(_REGION3_ENTRY_EMPTY);
			if (!table)
				return -ENOMEM;
			*rste = __pa(table) | _REGION2_ENTRY;
		}
		table = __va(*rste & _REGION_ENTRY_ORIGIN);
		rc = base_region3_walk(table, addr, next, alloc);
		if (rc)
			return rc;
		if (!alloc)
			base_crst_free(table);
	} while (rste++, addr = next, addr < end);
	return 0;
}

static int base_region1_walk(unsigned long *origin, unsigned long addr,
			     unsigned long end, int alloc)
{
	unsigned long *rfte, next, *table;
	int rc;

	rfte = origin;
	rfte += (addr & _REGION1_INDEX) >> _REGION1_SHIFT;
	do {
		next = base_region1_addr_end(addr, end);
		if (*rfte & _REGION_ENTRY_INVALID) {
			if (!alloc)
				continue;
			table = base_crst_alloc(_REGION2_ENTRY_EMPTY);
			if (!table)

Annotation

Implementation Notes