Commit 391bdbe4 authored by Kir Kolyshkin's avatar Kir Kolyshkin Committed by Pavel Emelyanov

zdtm/grow_map: fix test failure for clang

When this code is compiled by clang, it optimizes two byte writes into
one word write, like this:

>        fake_grow_down[0] = 'c';
>        *(fake_grow_down - 1) = 'b';
> 401b60:       66 41 c7 46 ff 62 63    movw   $0x6362,-0x1(%r14)

This is incorrect, as the stack is supposed to grow page by page,
so we need to touch one page then another, i.e. the order is important.

To fix, let's use volatile pointer. After this change, the following
(correct) code is generated:

>        *p-- = 'c';
>   401b60:       41 c6 06 63             movb   $0x63,(%r14)
>        *p = 'b';
>   401b64:       41 c6 46 ff 62          movb   $0x62,-0x1(%r14)

[v2: same fix for another similar place]

Cc: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarKir Kolyshkin <kir@openvz.org>
Acked-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 5465179f
...@@ -11,6 +11,7 @@ const char *test_author = "Andrew Vagin <avagin@openvz.org>"; ...@@ -11,6 +11,7 @@ const char *test_author = "Andrew Vagin <avagin@openvz.org>";
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *start_addr, *fake_grow_down, *test_addr, *grow_down; char *start_addr, *fake_grow_down, *test_addr, *grow_down;
volatile char *p;
test_init(argc, argv); test_init(argc, argv);
start_addr = mmap(NULL, PAGE_SIZE * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); start_addr = mmap(NULL, PAGE_SIZE * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
...@@ -28,8 +29,9 @@ int main(int argc, char **argv) ...@@ -28,8 +29,9 @@ int main(int argc, char **argv)
return 1; return 1;
} }
fake_grow_down[0] = 'c'; p = fake_grow_down;
*(fake_grow_down - 1) = 'b'; *p-- = 'c';
*p = 'b';
/* overlap the guard page of fake_grow_down */ /* overlap the guard page of fake_grow_down */
test_addr = mmap(start_addr + PAGE_SIZE * 3, PAGE_SIZE, test_addr = mmap(start_addr + PAGE_SIZE * 3, PAGE_SIZE,
...@@ -57,8 +59,9 @@ int main(int argc, char **argv) ...@@ -57,8 +59,9 @@ int main(int argc, char **argv)
return 1; return 1;
} }
grow_down[0] = 'z'; p = grow_down;
*(grow_down - 1) = 'x'; *p-- = 'z';
*p = 'x';
pass(); pass();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment