mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
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:
parent
03a8b24ae3
commit
7f11271403
1
NEWS
1
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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user