1c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang/* 2c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Copyright (c) 2015 Author: Oleg Nesterov <oleg@redhat.com> 3c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Modify: Li Wang <liwang@redhat.com> 4c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 5c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * This program is free software; you can redistribute it and/or modify it 6c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * under the terms of version 2 of the GNU General Public License as 7c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * published by the Free Software Foundation. 8c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 9c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * This program is distributed in the hope that it would be useful, but 10c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * WITHOUT ANY WARRANTY; without even the implied warranty of 11c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 13c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * you should have received a copy of the GNU General Public License along 14c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * with this program; if not, write the Free Software Foundation, Inc., 15c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang */ 17c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 18c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang/* 19c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Description: 20c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 21c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * save_xstate_sig()->drop_init_fpu() doesn't look right. setup_rt_frame() 22c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * can fail after that, in this case the next setup_rt_frame() triggered 23c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * by SIGSEGV won't save fpu simply because the old state was lost. This 24c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * obviously mean that fpu won't be restored after sys_rt_sigreturn() from 25c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * SIGSEGV handler. 26c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 27c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * These commits fix the issue on v3.17-rc3-3 stable kernel: 28c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 29c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * commit df24fb859a4e200d9324e2974229fbb7adf00aef 30c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Author: Oleg Nesterov <oleg@redhat.com> 31c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Date: Tue Sep 2 19:57:17 2014 +0200 32c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 33c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * commit 66463db4fc5605d51c7bb81d009d5bf30a783a2c 34101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng * Author: Oleg Nesterov <oleg@redhat.com> 35101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng * Date: Tue Sep 2 19:57:13 2014 +0200 36c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * 37c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Reproduce: 38c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * Test-case (needs -O2). 39c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang */ 40c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 41c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <stdio.h> 42c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <signal.h> 43c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <unistd.h> 44c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <sys/syscall.h> 45c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <sys/mman.h> 46c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <pthread.h> 47c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <assert.h> 48c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include <errno.h> 49c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 50c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#include "test.h" 51817d8095fbfe5ebe22b29f58b7483f3d8d5e3fccRichard Palethorpe#include "lapi/syscalls.h" 52c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 53c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangchar *TCID = "signal06"; 54c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangint TST_TOTAL = 5; 55c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 56c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#if __x86_64__ 57c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 58101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng#define LOOPS 30000 59101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng#define VALUE 123.456 60c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 61c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangvolatile double D; 62c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangvolatile int FLAGE; 63c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 64c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangchar altstack[4096 * 10] __attribute__((aligned(4096))); 65c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 66101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Fengvoid test(void) 67c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang{ 68c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang int loop = 0; 69c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang int pid = getpid(); 70c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 71101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng D = VALUE; 72101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng while (D == VALUE && loop < LOOPS) { 73c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang /* sys_tkill(pid, SIGHUP); asm to avoid save/reload 74c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang * fp regs around c call */ 75c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang asm ("" : : "a"(__NR_tkill), "D"(pid), "S"(SIGHUP)); 76c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang asm ("syscall" : : : "ax"); 77c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 78c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang loop++; 79c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } 80c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 81c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang FLAGE = 1; 82c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_resm(TINFO, "loop = %d", loop); 83c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 84c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (loop == LOOPS) { 85c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_resm(TPASS, "%s call succeeded", TCID); 86c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } else { 87c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_resm(TFAIL, "Bug Reproduced!"); 88c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_exit(); 89c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } 90c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang} 91c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 92c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangvoid sigh(int sig LTP_ATTRIBUTE_UNUSED) 93c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang{ 94c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang} 95c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 96c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangvoid *tfunc(void *arg LTP_ATTRIBUTE_UNUSED) 97c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang{ 98101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng int i; 99101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng 100101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng for (i = -1; ; i *= -1) { 101101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng if (i == -1) { 102101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng TEST(mprotect(altstack, sizeof(altstack), PROT_READ)); 103101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng if (TEST_RETURN == -1) 104101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng tst_brkm(TBROK | TTERRNO, NULL, "mprotect failed"); 105101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng } 106c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 107101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng TEST(mprotect(altstack, sizeof(altstack), PROT_READ | PROT_WRITE)); 108c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (TEST_RETURN == -1) 109c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TBROK | TTERRNO, NULL, "mprotect failed"); 110c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 111c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (FLAGE == 1) 112c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang return NULL; 113c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } 114c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang} 115c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 116c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangint main(int ac, char **av) 117c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang{ 118c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang int i, lc; 119c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang pthread_t pt; 120c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 121c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_parse_opts(ac, av, NULL, NULL); 122c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 123c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang stack_t st = { 124c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang .ss_sp = altstack, 125c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang .ss_size = sizeof(altstack), 126c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang .ss_flags = SS_ONSTACK, 127c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang }; 128c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 129c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang struct sigaction sa = { 130c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang .sa_handler = sigh, 131c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang }; 132c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 133c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang TEST(sigaction(SIGSEGV, &sa, NULL)); 134c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (TEST_RETURN == -1) 135c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TBROK | TTERRNO, NULL, 136c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang "SIGSEGV signal setup failed"); 137c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang sigaltstack(&st, NULL); 138c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang sa.sa_flags = SA_ONSTACK; 139c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 140c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang TEST(sigaction(SIGHUP, &sa, NULL)); 141c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (TEST_RETURN == -1) 142c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TBROK | TTERRNO, NULL, 143c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang "SIGHUP signal setup failed"); 144c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 145c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang for (lc = 0; TEST_LOOPING(lc); lc++) { 146c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_count = 0; 147c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 148c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang for (i = 0; i < TST_TOTAL; i++) { 149c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang FLAGE = 0; 150c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 151c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang TEST(pthread_create(&pt, NULL, tfunc, NULL)); 152c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (TEST_RETURN) 153c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TBROK | TRERRNO, NULL, 154c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang "pthread_create failed"); 155c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 156101c928a6a01a1092615f22ee15aa0c843d5825dGuangwen Feng test(); 157c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 158c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang TEST(pthread_join(pt, NULL)); 159c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang if (TEST_RETURN) 160c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TBROK | TRERRNO, NULL, 161c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang "pthread_join failed"); 162c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } 163c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang } 164c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 165c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_exit(); 166c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang} 167c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang 168c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#else 169c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wangint main(void) 170c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang{ 171c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang tst_brkm(TCONF, NULL, "Only test on x86_64."); 172c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang} 173c4c0bcd8e1bd76626820fe3242484c7f84c146c6Li Wang#endif 174