Thread (25 messages) flat view 25 messages, 11 authors, 2020-07-26

Re: [PATCH v2 1/3] module: Rename module_alloc() to text_alloc() and move to kernel proper

From: Mark Rutland <mark.rutland@arm.com>
Date: 2020-07-14 19:19:36
Also in: linux-riscv

On Tue, Jul 14, 2020 at 03:01:09PM +0200, Peter Zijlstra wrote:
On Tue, Jul 14, 2020 at 03:19:24PM +0300, Ard Biesheuvel wrote:
quoted
So perhaps the answer is to have text_alloc() not with a 'where'
argument but with a 'why' argument. Or more simply, just have separate
alloc/free APIs for each case, with generic versions that can be
overridden by the architecture.
Well, there only seem to be 2 cases here, either the pointer needs to
fit in some immediate displacement, or not.
On some arches you have a few choices for immediates depending on
compiler options, e.g. on arm64:

* +/- 128M with B
* +/-4G with ADRP+ADD+BR
* +/- 48/64 bits with a series of MOVK* + BR

... and you might build core kernel one way and modules another, and
either could depend on configuration.
On x86 we seem have the advantage of a fairly large immediate
displacement as compared to many other architectures (due to our
variable sized instructions). And thus have been fairly liberal with our
usage of it (also our indirect jmps/calls suck, double so with
RETCH-POLINE).

Still, the indirect jump, as mentioned by Russel should work for
arbitrarily placed code for us too.


So I'm thinking that something like:

enum ptr_type {
	immediate_displacement,
	absolute,
};

void *text_alloc(unsigned long size, enum ptr_type type)
{
	unsigned long vstart = VMALLOC_START;
	unsigned long vend   = VMALLOC_END;

	if (type == immediate_displacement) {
		vstart = MODULES_VADDR;
		vend   = MODULES_END;
	}

	return __vmalloc_node_range(size, TEXT_ALIGN, vstart, vend,
				    GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
				    NUMA_NO_NODE, _RET_IP_);
}

void text_free(void *ptr)
{
	vfree(ptr);
}
I think it'd be easier to read with separate functions, e.g.

  text_alloc_imm_offset(unsigned long size);
  text_alloc_absolute(unsigned long size);
Should work for all cases. Yes, we might then want something like a per
arch:

	{BPF,FTRACE,KPROBE}_TEXT_TYPE
... at that point why not:

  text_alloc_ftrace();
  text_alloc_module();
  text_alloc_bpf();
  text_alloc_kprobe();

... etc which an arch can alias however it wants? e.g. x86 can have
those all go to a common text_alloc_generic(), and that could even be a
generic option for arches that don't care to distinguish these cases.

Then if there are new places that want to allocate text we have to
consider their requirements when adding them, too.

Thanks,
Mark.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help