@@ -75,20 +75,37 @@ static int PatchLoadImm (uintptr_t addr, unsigned int reg, size_t value)
7575
7676#endif
7777
78- #if defined(__i386__ ) || defined(__x86_64__ ) || defined(__ia64__ )
79-
80- static void flush_and_invalidate_cache (unsigned long a )
78+ static void flush_and_invalidate_cache (unsigned long a )
8179{
82- #if defined(__i386__ )
83- /* does not work with AMD processors */
84- __asm__ volatile ("mfence;clflush %0;mfence" : :"m" (* (char * )a ));
85- #elif defined(__x86_64__ )
80+ #if OPAL_ASSEMBLY_ARCH == OPAL_IA32
81+ static int have_clflush = -1 ;
82+
83+ if (OPAL_UNLIKELY (-1 == have_clflush )) {
84+ int32_t cpuid1 , cpuid2 , tmp ;
85+ const int32_t level = 1 ;
86+
87+ /* cpuid clobbers ebx but it must be restored for -fPIC so save
88+ * then restore ebx */
89+ __asm__ volatile ("xchgl %%ebx, %2\n"
90+ "cpuid\n"
91+ "xchgl %%ebx, %2\n" :
92+ "=a" (cpuid1 ), "=d" (cpuid2 ), "=r" (tmp ) :
93+ "a" (level ) :
94+ "ecx" );
95+ /* clflush is in edx bit 19 */
96+ have_clflush = !!(cpuid2 & (1 << 19 ));
97+ }
98+
99+ if (have_clflush ) {
100+ /* does not work with AMD processors */
101+ __asm__ volatile ("mfence;clflush %0;mfence" : :"m" (* (char * )a ));
102+ }
103+ #elif OPAL_ASSEMBLY_ARCH == OPAL_AMD64
86104 __asm__ volatile ("mfence;clflush %0;mfence" : :"m" (* (char * )a ));
87- #elif defined( __ia64__ )
105+ #elif OPAL_ASSEMBLY_ARCH == OPAL_IA64
88106 __asm__ volatile ("fc %0;; sync.i;; srlz.i;;" : : "r" (a ) : "memory" );
89107#endif
90108}
91- #endif
92109
93110// modify protection of memory range
94111static void ModifyMemoryProtection (uintptr_t addr , size_t length , int prot )
@@ -105,7 +122,7 @@ static void ModifyMemoryProtection (uintptr_t addr, size_t length, int prot)
105122 if (mprotect ((void * )base , page_size , prot ))
106123 perror ("MemHook: mprotect failed" );
107124 base += page_size ;
108- } while (base < addr + length );
125+ } while (base < bound );
109126#else
110127 if (mprotect ((void * ) base , length , prot )) {
111128 perror ("MemHook: mprotect failed" );
@@ -117,11 +134,9 @@ static inline void apply_patch (unsigned char *patch_data, uintptr_t address, si
117134{
118135 ModifyMemoryProtection (address , data_size , PROT_EXEC |PROT_READ |PROT_WRITE );
119136 memcpy ((void * ) address , patch_data , data_size );
120- #if defined(__i386__ ) || defined(__x86_64__ ) || defined(__ia64__ )
121137 for (size_t i = 0 ; i < data_size ; i += 16 ) {
122138 flush_and_invalidate_cache (address + i );
123139 }
124- #endif
125140
126141 ModifyMemoryProtection (address , data_size , PROT_EXEC |PROT_READ );
127142}
@@ -141,26 +156,26 @@ void mca_base_patcher_patch_apply_binary (mca_patcher_base_patch_t *patch)
141156
142157int mca_patcher_base_patch_hook (mca_patcher_base_module_t * module , uintptr_t hook_addr )
143158{
144- #if defined( __PPC64__ ) || defined( __powerpc64__ ) || defined( __PPC__ )
159+ #if ( OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64 )
145160 mca_patcher_base_patch_t * hook_patch ;
146161 const unsigned int nop = 0x60000000 ;
147- unsigned int * nop_addr ;
148162
149163 hook_patch = OBJ_NEW (mca_patcher_base_patch_t );
150164 if (OPAL_UNLIKELY (NULL == hook_patch )) {
151165 return OPAL_ERR_OUT_OF_RESOURCE ;
152166 }
153167
154168 // locate reserved code space in hook function
155- for (nop_addr = (unsigned int * )hook_addr ; ; nop_addr ++ ) {
169+ for (unsigned int * nop_addr = (unsigned int * )hook_addr ; ; nop_addr ++ ) {
156170 if (nop_addr [0 ] == nop && nop_addr [1 ] == nop && nop_addr [2 ] == nop
157171 && nop_addr [3 ] == nop && nop_addr [4 ] == nop ) {
172+ hook_patch -> patch_orig = (uintptr_t ) nop_addr ;
158173 break ;
159174 }
160175 }
176+
161177 // generate code to restore TOC
162178 register unsigned long toc asm("r2" );
163- hook_patch -> patch_orig = (uintptr_t ) nop_addr ;
164179 hook_patch -> patch_data_size = PatchLoadImm ((uintptr_t )hook_patch -> patch_data , 2 , toc );
165180
166181 /* put the hook patch on the patch list so it will be undone on finalize */
0 commit comments