]> sourceware.org Git - valgrind.git/commitdiff
Powerpc: Fix checking for scv support, add check to scv instruction parsing.
authorCarl Love <carll@us.ibm.com>
Fri, 11 Feb 2022 20:07:20 +0000 (14:07 -0600)
committerCarl Love <cel@us.ibm.com>
Fri, 18 Feb 2022 19:12:21 +0000 (19:12 +0000)
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.

NEWS
VEX/priv/guest_ppc_toIR.c
VEX/pub/libvex.h
coregrind/m_initimg/initimg-linux.c
coregrind/m_machine.c
coregrind/pub_core_machine.h

diff --git a/NEWS b/NEWS
index e4f2b7141105990c8c92691a5da65c75441bf668..8ed4898aab7b195049cc4c0b298e760a27a0775a 100644 (file)
--- 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
index afe66c0be5bebc894252a0ea7d5eeb4d46ea6104..e340562bf04bf9edfb86ad2fe478e815f0704e52 100644 (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;
 
index 143ec85e948cd2e898813b983f20466063e00621..ec50d52ca955f91dd2e777836a70a6eb804d34ce 100644 (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
index 95508ad1ed642a07da83603bcb33a5d92bee743c..48df8c12252ab79509a07b72c6fbb785b02bdeb5 100644 (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;
index 7aa15133f5b103385f98326efc9625f8c62c198e..052b5d186bd616b3de96a417a8539ae0a69e4ea7 100644 (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
 
 
index 38c9ce99c44d475a83397633d1deff92ac93fb03..a9b7dd8b17cabf80511eedf27f1275c02ca07416 100644 (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)
This page took 0.706788 seconds and 5 git commands to generate.