xref: /qemu/include/accel/tcg/helper-retaddr.h (revision 7cef6d686309e2792186504ae17cf4f3eb57ef68)
1*0baf907bSRichard Henderson /*
2*0baf907bSRichard Henderson  * Get user helper pc for memory unwinding.
3*0baf907bSRichard Henderson  * SPDX-License-Identifier: LGPL-2.1-or-later
4*0baf907bSRichard Henderson  */
5*0baf907bSRichard Henderson 
6*0baf907bSRichard Henderson #ifndef ACCEL_TCG_HELPER_RETADDR_H
7*0baf907bSRichard Henderson #define ACCEL_TCG_HELPER_RETADDR_H
8*0baf907bSRichard Henderson 
9*0baf907bSRichard Henderson /*
10*0baf907bSRichard Henderson  * For user-only, helpers that use guest to host address translation
11*0baf907bSRichard Henderson  * must protect the actual host memory access by recording 'retaddr'
12*0baf907bSRichard Henderson  * for the signal handler.  This is required for a race condition in
13*0baf907bSRichard Henderson  * which another thread unmaps the page between a probe and the
14*0baf907bSRichard Henderson  * actual access.
15*0baf907bSRichard Henderson  */
16*0baf907bSRichard Henderson #ifdef CONFIG_USER_ONLY
17*0baf907bSRichard Henderson extern __thread uintptr_t helper_retaddr;
18*0baf907bSRichard Henderson 
set_helper_retaddr(uintptr_t ra)19*0baf907bSRichard Henderson static inline void set_helper_retaddr(uintptr_t ra)
20*0baf907bSRichard Henderson {
21*0baf907bSRichard Henderson     helper_retaddr = ra;
22*0baf907bSRichard Henderson     /*
23*0baf907bSRichard Henderson      * Ensure that this write is visible to the SIGSEGV handler that
24*0baf907bSRichard Henderson      * may be invoked due to a subsequent invalid memory operation.
25*0baf907bSRichard Henderson      */
26*0baf907bSRichard Henderson     signal_barrier();
27*0baf907bSRichard Henderson }
28*0baf907bSRichard Henderson 
clear_helper_retaddr(void)29*0baf907bSRichard Henderson static inline void clear_helper_retaddr(void)
30*0baf907bSRichard Henderson {
31*0baf907bSRichard Henderson     /*
32*0baf907bSRichard Henderson      * Ensure that previous memory operations have succeeded before
33*0baf907bSRichard Henderson      * removing the data visible to the signal handler.
34*0baf907bSRichard Henderson      */
35*0baf907bSRichard Henderson     signal_barrier();
36*0baf907bSRichard Henderson     helper_retaddr = 0;
37*0baf907bSRichard Henderson }
38*0baf907bSRichard Henderson #else
39*0baf907bSRichard Henderson #define set_helper_retaddr(ra)   do { } while (0)
40*0baf907bSRichard Henderson #define clear_helper_retaddr()   do { } while (0)
41*0baf907bSRichard Henderson #endif
42*0baf907bSRichard Henderson 
43*0baf907bSRichard Henderson #endif /* ACCEL_TCG_HELPER_RETADDR_H */
44