From: Dave Hansen dave.hansen@linux.intel.com
stable inclusion from linux-4.19.198 commit 8ceeafb911cc056bb8d4b804b04b54a214a0a684
--------------------------------
[ Upstream commit f36ef407628835a7d7fb3d235b1f1aac7022d9a3 ]
Patch series "selftests/vm/pkeys: Bug fixes and a new test".
There has been a lot of activity on the x86 front around the XSAVE architecture which is used to context-switch processor state (among other things). In addition, AMD has recently joined the protection keys club by adding processor support for PKU.
The AMD implementation helped uncover a kernel bug around the PKRU "init state", which actually applied to Intel's implementation but was just harder to hit. This series adds a test which is expected to help find this class of bug both on AMD and Intel. All the work around pkeys on x86 also uncovered a few bugs in the selftest.
This patch (of 4):
The "random" pkey allocation code currently does the good old:
srand((unsigned int)time(NULL));
*But*, it unfortunately does this on every random pkey allocation.
There may be thousands of these a second. time() has a one second resolution. So, each time alloc_random_pkey() is called, the PRNG is *RESET* to time(). This is nasty. Normally, if you do:
srand(<ANYTHING>); foo = rand(); bar = rand();
You'll be quite guaranteed that 'foo' and 'bar' are different. But, if you do:
srand(1); foo = rand(); srand(1); bar = rand();
You are quite guaranteed that 'foo' and 'bar' are the *SAME*. The recent "fix" effectively forced the test case to use the same "random" pkey for the whole test, unless the test run crossed a second boundary.
Only run srand() once at program startup.
This explains some very odd and persistent test failures I've been seeing.
Link: https://lkml.kernel.org/r/20210611164153.91B76FB8@viggo.jf.intel.com Link: https://lkml.kernel.org/r/20210611164155.192D00FF@viggo.jf.intel.com Fixes: 6e373263ce07 ("selftests/vm/pkeys: fix alloc_random_pkey() to make it really random") Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Cc: Ram Pai linuxram@us.ibm.com Cc: Sandipan Das sandipan@linux.ibm.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: Michael Ellerman mpe@ellerman.id.au Cc: Michal Hocko mhocko@kernel.org Cc: Michal Suchanek msuchanek@suse.de Cc: Shuah Khan shuah@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- tools/testing/selftests/x86/protection_keys.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c index b8778960da106..27661302a6985 100644 --- a/tools/testing/selftests/x86/protection_keys.c +++ b/tools/testing/selftests/x86/protection_keys.c @@ -613,7 +613,6 @@ int alloc_random_pkey(void) int nr_alloced = 0; int random_index; memset(alloced_pkeys, 0, sizeof(alloced_pkeys)); - srand((unsigned int)time(NULL));
/* allocate every possible key and make a note of which ones we got */ max_nr_pkey_allocs = NR_PKEYS; @@ -1479,6 +1478,8 @@ int main(void) { int nr_iterations = 22;
+ srand((unsigned int)time(NULL)); + setup_handlers();
printf("has pku: %d\n", cpu_has_pku());