endef
 
 ifeq ($(CAN_BUILD_I386),1)
-$(BINARIES_32): CFLAGS += -m32
+$(BINARIES_32): CFLAGS += -m32 -mxsave
 $(BINARIES_32): LDLIBS += -lrt -ldl -lm
 $(BINARIES_32): $(OUTPUT)/%_32: %.c
        $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@
 endif
 
 ifeq ($(CAN_BUILD_X86_64),1)
-$(BINARIES_64): CFLAGS += -m64
+$(BINARIES_64): CFLAGS += -m64 -mxsave
 $(BINARIES_64): LDLIBS += -lrt -ldl
 $(BINARIES_64): $(OUTPUT)/%_64: %.c
        $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(notdir $^) $(LDLIBS) -o $@
 
        }
 }
 
+void arch_force_pkey_reg_init(void)
+{
+#if defined(__i386__) || defined(__x86_64__) /* arch */
+       u64 *buf;
+
+       /*
+        * All keys should be allocated and set to allow reads and
+        * writes, so the register should be all 0.  If not, just
+        * skip the test.
+        */
+       if (read_pkey_reg())
+               return;
+
+       /*
+        * Just allocate an absurd about of memory rather than
+        * doing the XSAVE size enumeration dance.
+        */
+       buf = mmap(NULL, 1*MB, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+
+       /* These __builtins require compiling with -mxsave */
+
+       /* XSAVE to build a valid buffer: */
+       __builtin_ia32_xsave(buf, XSTATE_PKEY);
+       /* Clear XSTATE_BV[PKRU]: */
+       buf[XSTATE_BV_OFFSET/sizeof(u64)] &= ~XSTATE_PKEY;
+       /* XRSTOR will likely get PKRU back to the init state: */
+       __builtin_ia32_xrstor(buf, XSTATE_PKEY);
+
+       munmap(buf, 1*MB);
+#endif
+}
+
+
+/*
+ * This is mostly useless on ppc for now.  But it will not
+ * hurt anything and should give some better coverage as
+ * a long-running test that continually checks the pkey
+ * register.
+ */
+void test_pkey_init_state(int *ptr, u16 pkey)
+{
+       int err;
+       int allocated_pkeys[NR_PKEYS] = {0};
+       int nr_allocated_pkeys = 0;
+       int i;
+
+       for (i = 0; i < NR_PKEYS; i++) {
+               int new_pkey = alloc_pkey();
+
+               if (new_pkey < 0)
+                       continue;
+               allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
+       }
+
+       dprintf3("%s()::%d\n", __func__, __LINE__);
+
+       arch_force_pkey_reg_init();
+
+       /*
+        * Loop for a bit, hoping to get exercise the kernel
+        * context switch code.
+        */
+       for (i = 0; i < 1000000; i++)
+               read_pkey_reg();
+
+       for (i = 0; i < nr_allocated_pkeys; i++) {
+               err = sys_pkey_free(allocated_pkeys[i]);
+               pkey_assert(!err);
+               read_pkey_reg(); /* for shadow checking */
+       }
+}
+
 /*
  * pkey 0 is special.  It is allocated by default, so you do not
  * have to call pkey_alloc() to use it first.  Make sure that it
        test_implicit_mprotect_exec_only_memory,
        test_mprotect_with_pkey_0,
        test_ptrace_of_child,
+       test_pkey_init_state,
        test_pkey_syscalls_on_non_allocated_pkey,
        test_pkey_syscalls_bad_args,
        test_pkey_alloc_exhaust,