From: Carl Love Date: Fri, 11 Feb 2022 20:07:20 +0000 (-0600) Subject: Powerpc: Fix checking for scv support, add check to scv instruction parsing. X-Git-Tag: VALGRIND_3_19_0~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f11271403219d21c46e3b831cc1709336e792f1;p=thirdparty%2Fvalgrind.git Powerpc: Fix checking for scv support, add check to scv instruction parsing. The check for the scv instruction in coregrind/m_machine.c issues an scv instruction and uses sigill to determine if the instruction is supported. Issuing scv on systems that don't support scv, i.e. scv support is not in HWCAPS2, generates a message in dmesg "Facility 'SCV' unavailable (12), exception". This patch removes the sigill based scv instruction test from coregrind/m_machine.c. The scv support is now determined by reading the HWCAPS2 in setup_client_stack(). VG_(machine_ppc64_set_scv_support) is called to set the flag ppc_scv_supported in struct VexArchInfo. The allow_scv flag is added in disInstr_PPC_WRK. The allow_scv flag is used to ensure the host has support for scv before generating the iops for the scv instruction. --- diff --git a/NEWS b/NEWS index e4f2b71411..8ed4898aab 100644 --- a/NEWS +++ b/NEWS @@ -70,6 +70,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 449838 sigsegv liburing the 'impossible' happened for io_uring_setup 450025 Powerc: ACC file not implemented as a logical overlay of the VSR registers. +450536 Powerpc: valgrind throws 'facility scv unavailable exception' To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index afe66c0be5..e340562bf0 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -10755,7 +10755,8 @@ static Bool dis_trap ( UInt prefix, UInt theInstr, */ static Bool dis_syslink ( UInt prefix, UInt theInstr, - const VexAbiInfo* abiinfo, DisResult* dres ) + const VexAbiInfo* abiinfo, DisResult* dres, + Bool allow_scv, Bool sigill_diag ) { IRType ty = mode64 ? Ity_I64 : Ity_I32; @@ -10776,9 +10777,14 @@ static Bool dis_syslink ( UInt prefix, UInt theInstr, DIP("sc\n"); put_syscall_flag( mkU32(SC_FLAG) ); } else if (theInstr == 0x44000001) { - // scv - DIP("scv\n"); - put_syscall_flag( mkU32(SCV_FLAG) ); + if (allow_scv) { // scv + DIP("scv\n"); + put_syscall_flag( mkU32(SCV_FLAG) ); + } else { + if (sigill_diag) + vex_printf("The scv instruction is not supported in this environment per the HWCAPS2 capability flags.\n"); + return False; + } } else { /* Unknown instruction */ return False; @@ -35703,6 +35709,7 @@ DisResult disInstr_PPC_WRK ( Bool allow_isa_2_07 = False; Bool allow_isa_3_0 = False; Bool allow_isa_3_1 = False; + Bool allow_scv = False; Bool is_prefix; /* In ISA 3.1 the ACC is implemented on top of the vsr0 thru vsr31. @@ -35731,6 +35738,7 @@ DisResult disInstr_PPC_WRK ( allow_isa_2_07 = (0 != (hwcaps & VEX_HWCAPS_PPC64_ISA2_07)); allow_isa_3_0 = (0 != (hwcaps & VEX_HWCAPS_PPC64_ISA3_0)); allow_isa_3_1 = (0 != (hwcaps & VEX_HWCAPS_PPC64_ISA3_1)); + allow_scv = archinfo->ppc_scv_supported; } else { allow_F = (0 != (hwcaps & VEX_HWCAPS_PPC32_F)); allow_V = (0 != (hwcaps & VEX_HWCAPS_PPC32_V)); @@ -35741,6 +35749,7 @@ DisResult disInstr_PPC_WRK ( allow_isa_2_07 = (0 != (hwcaps & VEX_HWCAPS_PPC32_ISA2_07)); allow_isa_3_0 = (0 != (hwcaps & VEX_HWCAPS_PPC32_ISA3_0)); /* ISA 3.1 is not supported in 32-bit mode */ + /* The scv instruction is not supported in 32-bit mode */ } /* Enable writting the OV32 and CA32 bits added with ISA3.0 */ @@ -36140,7 +36149,8 @@ DisResult disInstr_PPC_WRK ( /* System Linkage Instructions */ case 0x11: // sc, scv - if (dis_syslink( prefix, theInstr, abiinfo, &dres)) + if (dis_syslink( prefix, theInstr, abiinfo, &dres, allow_scv, + sigill_diag)) goto decode_success; goto decode_failure; diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 143ec85e94..ec50d52ca9 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -362,6 +362,8 @@ typedef /* PPC32/PPC64 only: sizes zeroed by the dcbz/dcbzl instructions (bug#135264) */ UInt ppc_dcbz_szB; + /* PPC32/PPC64 only: True scv is supported */ + Bool ppc_scv_supported; UInt ppc_dcbzl_szB; /* 0 means unsupported (SIGILL) */ /* ARM64: I- and D- minimum line sizes in log2(bytes), as obtained from ctr_el0.DminLine and .IminLine. For example, a diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 95508ad1ed..48df8c1225 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -727,7 +727,7 @@ Addr setup_client_stack( void* init_sp, Bool auxv_2_07, hw_caps_2_07; Bool auxv_3_0, hw_caps_3_0; Bool auxv_3_1, hw_caps_3_1; - Bool auxv_scv_supported, hw_caps_scv_supported; + Bool auxv_scv_supported; /* The HWCAP2 field may contain an arch_2_07 entry that indicates * if the processor is compliant with the 2.07 ISA. (i.e. Power 8 @@ -799,17 +799,16 @@ Addr setup_client_stack( void* init_sp, ADD PUBLIC LINK WHEN AVAILABLE */ - /* Check for SCV support */ + /* Check for SCV support, Can not test scv instruction to see + if the system supports scv. Issuing an scv intruction on a + system that does not have scv in the HWCAPS results in a + message in dmsg "Facility 'SCV' unavailable (12), exception". + Will have to just use the scv setting from HWCAPS2 to determine + if the host supports scv. */ auxv_scv_supported = (auxv->u.a_val & 0x00100000ULL) == 0x00100000ULL; - hw_caps_scv_supported = - (vex_archinfo->hwcaps & VEX_HWCAPS_PPC64_SCV) - == VEX_HWCAPS_PPC64_SCV; - /* Verify the scv_supported setting in HWCAP2 matches the setting - in VEX HWCAPS. - */ - vg_assert(auxv_scv_supported == hw_caps_scv_supported); + VG_(machine_ppc64_set_scv_support)(auxv_scv_supported); /* ISA 3.1 */ auxv_3_1 = (auxv->u.a_val & 0x00040000ULL) == 0x00040000ULL; diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index 7aa15133f5..052b5d186b 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -1251,6 +1251,8 @@ Bool VG_(machine_get_hwcaps)( void ) // ISA 3.1 not supported on 32-bit systems + // scv instruction not supported on 32-bit systems. + /* determine dcbz/dcbzl sizes while we still have the signal * handlers registered */ find_ppc_dcbz_sz(&vai); @@ -1289,6 +1291,7 @@ Bool VG_(machine_get_hwcaps)( void ) if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA2_07; if (have_isa_3_0) vai.hwcaps |= VEX_HWCAPS_PPC32_ISA3_0; /* ISA 3.1 not supported on 32-bit systems. */ + /* SCV not supported on PPC32 */ VG_(machine_get_cache_info)(&vai); @@ -1306,7 +1309,6 @@ Bool VG_(machine_get_hwcaps)( void ) volatile Bool have_F, have_V, have_FX, have_GX, have_VX, have_DFP; volatile Bool have_isa_2_07, have_isa_3_0, have_isa_3_1; - volatile Bool have_scv_support; Int r; /* This is a kludge. Really we ought to back-convert saved_act @@ -1409,6 +1411,19 @@ Bool VG_(machine_get_hwcaps)( void ) __asm__ __volatile__(".long 0x7f140434":::"r20"); /* cnttzw r20,r24 */ } + /* Check if Host supports scv instruction. + Note, can not use the usual method of issuing the scv instruction and + checking if it is supported or not. Issuing scv on a system that does + not have scv support in the HWCAPS generates a message in dmesg, + "Facility 'SCV' unavailable (12), exception". It is considered bad + form to issue and scv on systems that do not support it. + + The function VG_(machine_ppc64_set_scv_support), is called in + initimg-linux.c to set the flag ppc_scv_supported based on HWCAPS2 + value. The flag ppc_scv_supported is defined struct VexArchInfo, + in file libvex.h The setting of ppc_scv_supported in VexArchInfo + is checked in disInstr_PPC_WRK() to set the allow_scv flag. */ + /* Check for ISA 3.1 support. */ have_isa_3_1 = True; if (VG_MINIMAL_SETJMP(env_unsup_insn)) { @@ -1417,18 +1432,6 @@ Bool VG_(machine_get_hwcaps)( void ) __asm__ __volatile__(".long 0x7f1401b6":::"r20"); /* brh r20,r24 */ } - /* Check if Host supports scv instruction */ - have_scv_support = True; - if (VG_MINIMAL_SETJMP(env_unsup_insn)) { - have_scv_support = False; - } else { - /* Set r0 to 13 for the system time call. Don't want to make a random - system call. */ - __asm__ __volatile__(".long 0x7c000278"); /* clear r0 with xor r0,r0,r0 */ - __asm__ __volatile__(".long 0x6000000d"); /* set r0 to 13 with ori r0,r0,13 */ - __asm__ __volatile__(".long 0x44000001"); /* scv 0 */ - } - /* determine dcbz/dcbzl sizes while we still have the signal * handlers registered */ find_ppc_dcbz_sz(&vai); @@ -1464,12 +1467,12 @@ Bool VG_(machine_get_hwcaps)( void ) if (have_isa_2_07) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA2_07; if (have_isa_3_0) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA3_0; if (have_isa_3_1) vai.hwcaps |= VEX_HWCAPS_PPC64_ISA3_1; - if (have_scv_support) vai.hwcaps |= VEX_HWCAPS_PPC64_SCV; VG_(machine_get_cache_info)(&vai); - /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be - called before we're ready to go. */ + /* But we're not done yet: VG_(machine_ppc64_set_clszB) and + VG_(machine_ppc64_set_scv_support) must be called before we're + ready to go. */ return True; } @@ -2262,6 +2265,13 @@ void VG_(machine_ppc64_set_clszB)( Int szB ) vg_assert(szB == 16 || szB == 32 || szB == 64 || szB == 128); vai.ppc_icache_line_szB = szB; } + +void VG_(machine_ppc64_set_scv_support)( Int is_supported ) +{ + vg_assert(hwcaps_done); + vai.ppc_scv_supported = is_supported; +} + #endif diff --git a/coregrind/pub_core_machine.h b/coregrind/pub_core_machine.h index 38c9ce99c4..a9b7dd8b17 100644 --- a/coregrind/pub_core_machine.h +++ b/coregrind/pub_core_machine.h @@ -221,6 +221,7 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, ------------- ppc64: initially: call VG_(machine_get_hwcaps) call VG_(machine_ppc64_set_clszB) + call VG_(machine_ppc64_set_scv_support) then safe to use VG_(machine_get_VexArchInfo) and VG_(machine_ppc64_has_VMX) @@ -255,6 +256,7 @@ extern void VG_(machine_ppc32_set_clszB)( Int ); #if defined(VGA_ppc64be) || defined(VGA_ppc64le) extern void VG_(machine_ppc64_set_clszB)( Int ); +extern void VG_(machine_ppc64_set_scv_support)( Int ); #endif #if defined(VGA_arm)