<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 22, 2018 at 3:09 PM, Ram Pai <span dir="ltr"><<a href="mailto:linuxram@us.ibm.com" target="_blank">linuxram@us.ibm.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Mar 21, 2018 at 02:53:00PM +0800, Li Wang wrote:<br>
<span class="gmail-">>    On Wed, Mar 21, 2018 at 5:58 AM, Ram Pai <[1]<a href="mailto:linuxram@us.ibm.com">linuxram@us.ibm.com</a>> wrote:<br>
><br>
>      On Fri, Mar 09, 2018 at 11:43:00AM +0800, Li Wang wrote:<br>
>      >    On Fri, Mar 9, 2018 at 12:45 AM, Ram Pai<br>
</span><span class="gmail-">>      <[1][2]<a href="mailto:linuxram@us.ibm.com">linuxram@us.ibm.com</a>> wrote:<br>
>      ><br>
>      >      On Thu, Mar 08, 2018 at 11:19:12PM +1100, Michael Ellerman wrote:<br>
</span>>      >      > Li Wang <[2][3]<a href="mailto:liwang@redhat.com">liwang@redhat.com</a>> writes:<br>
>      >      > > Hi,<br>
<span class="gmail-">>      >      > ><br>
>      >      am wondering if the slightly different cpu behavior is dependent<br>
</span>..snip..<br>
<span class="gmail-">>      on the<br>
>      >      version of the firmware/microcode?<br>
>      ><br>
>      >    ​I also run this reproducer on series ppc kvm machines, but none of<br>
>      them<br>
>      >    get the FAIL.<br>
>      >    If you need some more HW info, pls let me know.​<br>
><br>
>      Hi Li,<br>
><br>
>         Can you try the following patch and see if it solves your problem.<br>
><br>
>    ​It only works on power7 lpar machine.<br>
><br>
>    But for p8 lpar, it still get failure as that before, the thing I wondered<br>
>    is<br>
>    that why not disable the pkey_execute_disable_supported on p8 machine?<br>
<br>
</span>It turns out to be a testcase bug.  On Big endian powerpc ABI, function<br>
ptrs are basically pointers to function descriptors.  The testcase<br>
copies functions which results in function descriptors getting copied.<br>
You have to apply the following patch to your test case for it to<br>
operate as intended.  Thanks to Michael Ellermen for helping me out.<br>
Otherwise I would be scratching my head for ever.<br></blockquote><div><br><div style="font-family:monospace,monospace" class="gmail_default">​Thanks for the explanation, I learned something new about this. :) <br><br></div><div style="font-family:monospace,monospace" class="gmail_default">And the worth to say, seems the patch only works on powerpc arch, others(x86_64, etc)<br>that does not works well, so a simple workaround is to isolate the code changes<br>to powerpc system?<br></div><div style="font-family:monospace,monospace" class="gmail_default"><br><br></div><div style="font-family:monospace,monospace" class="gmail_default">Hi Cyril & Jan, <br><br>Could any of you take a look at this patch, comments?<br></div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
diff --git a/testcases/kernel/syscalls/<wbr>mprotect/mprotect04.c b/testcases/kernel/syscalls/<wbr>mprotect/mprotect04.c<br>
index 1173afd..9fe9001 100644<br>
--- a/testcases/kernel/syscalls/<wbr>mprotect/mprotect04.c<br>
+++ b/testcases/kernel/syscalls/<wbr>mprotect/mprotect04.c<br>
@@ -189,18 +189,30 @@ static void clear_cache(void *start, int len)<br>
 #endif<br>
 }<br>
<br>
+typedef struct {<br>
+       uintptr_t entry;<br>
+       uintptr_t toc;<br>
+       uintptr_t env;<br>
+} func_descr_t;<br>
+<br>
+typedef void (*func_ptr_t)(void);<br>
+<br>
 /*<br>
  * Copy page where &exec_func resides. Also try to copy subsequent page<br>
  * in case exec_func is close to page boundary.<br>
  */<br>
-static void *get_func(void *mem)<br>
+void *get_func(void *mem)<br>
 {<br>
        uintptr_t page_sz = getpagesize();<br>
        uintptr_t page_mask = ~(page_sz - 1);<br>
-       uintptr_t func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);<br>
-       void *func_copy_start = mem + func_page_offset;<br>
-       void *page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);<br>
+       uintptr_t func_page_offset;<br>
+       void *func_copy_start, *page_to_copy;<br>
        void *mem_start = mem;<br>
+       func_descr_t *opd =  (func_descr_t *)&exec_func;<br>
+<br>
+       func_page_offset = (uintptr_t)opd->entry & (page_sz - 1);<br>
+       func_copy_start = mem + func_page_offset;<br>
+       page_to_copy = (void *)((uintptr_t)opd->entry & page_mask);<br>
<br>
        /* copy 1st page, if it's not present something is wrong */<br>
        if (!page_present(page_to_copy)) {<br>
@@ -228,15 +240,17 @@ static void *get_func(void *mem)<br>
<br>
 static void testfunc_protexec(void)<br>
 {<br>
-       void (*func)(void);<br>
        void *p;<br>
+       func_ptr_t func;<br>
+       func_descr_t opd;<br>
<br>
        sig_caught = 0;<br>
<br>
        p = SAFE_MMAP(cleanup, 0, copy_sz, PROT_READ | PROT_WRITE,<br>
                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);<br>
<br>
-       func = get_func(p);<br>
+       opd.entry = (uintptr_t)get_func(p);<br>
+       func = (func_ptr_t)&opd;<br>
<br>
        /* Change the protection to PROT_EXEC. */<br>
        TEST(mprotect(p, copy_sz, PROT_EXEC));<br>
<br>
<br>
RP<br>
<br>
</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">Li Wang<br><a href="mailto:liwang@redhat.com" target="_blank">liwang@redhat.com</a></div>
</div></div>