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.
This commit is contained in:
Carl Love 2022-02-11 14:07:20 -06:00 committed by Carl Love
parent 03a8b24ae3
commit 7f11271403
6 changed files with 54 additions and 30 deletions

1
NEWS
View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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)