Commit fa17437c authored by Ram Pai's avatar Ram Pai Committed by Linus Torvalds
Browse files

selftests/vm/pkeys: test correct behaviour of pkey-0



Ensure that pkey-0 is allocated on start and that it can be attached
dynamically in various modes, without failures.

Signed-off-by: default avatarRam Pai <linuxram@us.ibm.com>
Signed-off-by: default avatarSandipan Das <sandipan@linux.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Acked-by: default avatarDave Hansen <dave.hansen@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: "Desnes A. Nunes do Rosario" <desnesn@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Suchanek <msuchanek@suse.de>
Cc: Shuah Khan <shuah@kernel.org>
Link: http://lkml.kernel.org/r/9b7c54a9b4261894fe0c7e884c70b87214ff8fbb.1585646528.git.sandipan@linux.ibm.com


Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6e2c2d0f
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -964,6 +964,58 @@ __attribute__((noinline)) int read_ptr(int *ptr)
	return *ptr;
}

void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
{
	int i, err;
	int max_nr_pkey_allocs;
	int alloced_pkeys[NR_PKEYS];
	int nr_alloced = 0;
	long size;

	pkey_assert(pkey_last_malloc_record);
	size = pkey_last_malloc_record->size;
	/*
	 * This is a bit of a hack.  But mprotect() requires
	 * huge-page-aligned sizes when operating on hugetlbfs.
	 * So, make sure that we use something that's a multiple
	 * of a huge page when we can.
	 */
	if (size >= HPAGE_SIZE)
		size = HPAGE_SIZE;

	/* allocate every possible key and make sure key-0 never got allocated */
	max_nr_pkey_allocs = NR_PKEYS;
	for (i = 0; i < max_nr_pkey_allocs; i++) {
		int new_pkey = alloc_pkey();
		pkey_assert(new_pkey != 0);

		if (new_pkey < 0)
			break;
		alloced_pkeys[nr_alloced++] = new_pkey;
	}
	/* free all the allocated keys */
	for (i = 0; i < nr_alloced; i++) {
		int free_ret;

		if (!alloced_pkeys[i])
			continue;
		free_ret = sys_pkey_free(alloced_pkeys[i]);
		pkey_assert(!free_ret);
	}

	/* attach key-0 in various modes */
	err = sys_mprotect_pkey(ptr, size, PROT_READ, 0);
	pkey_assert(!err);
	err = sys_mprotect_pkey(ptr, size, PROT_WRITE, 0);
	pkey_assert(!err);
	err = sys_mprotect_pkey(ptr, size, PROT_EXEC, 0);
	pkey_assert(!err);
	err = sys_mprotect_pkey(ptr, size, PROT_READ|PROT_WRITE, 0);
	pkey_assert(!err);
	err = sys_mprotect_pkey(ptr, size, PROT_READ|PROT_WRITE|PROT_EXEC, 0);
	pkey_assert(!err);
}

void test_read_of_write_disabled_region(int *ptr, u16 pkey)
{
	int ptr_contents;
@@ -1448,6 +1500,7 @@ void (*pkey_tests[])(int *ptr, u16 pkey) = {
	test_pkey_syscalls_on_non_allocated_pkey,
	test_pkey_syscalls_bad_args,
	test_pkey_alloc_exhaust,
	test_pkey_alloc_free_attach_pkey0,
};

void run_tests_once(void)