(root)/
strace-6.5/
tests-m32/
s390_guarded_storage.c
       1  /*
       2   * Check decoding of s390_guarded_storage syscall.
       3   *
       4   * Copyright (c) 2018-2019 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  
      13  #if defined __NR_s390_guarded_storage && defined HAVE_ASM_GUARDED_STORAGE_H
      14  
      15  # include <inttypes.h>
      16  # include <stdint.h>
      17  # include <stdio.h>
      18  # include <unistd.h>
      19  
      20  # include <asm/guarded_storage.h>
      21  
      22  # ifndef VERBOSE
      23  #  define VERBOSE 0
      24  # endif
      25  
      26  static void
      27  gs_no_arg(kernel_ulong_t val, const char *val_str)
      28  {
      29  	static const kernel_ulong_t bogus_addr =
      30  		(kernel_ulong_t) 0xcaffeedadeadbed5ULL;
      31  	static const kernel_ulong_t bogus_cmd_mask =
      32  		(kernel_ulong_t) 0xbadc0ded00000000ULL;
      33  	long rc;
      34  
      35  	rc = syscall(__NR_s390_guarded_storage, val | bogus_cmd_mask,
      36  		     bogus_addr);
      37  	printf("s390_guarded_storage(%s) = %s\n", val_str, sprintrc(rc));
      38  }
      39  
      40  static void
      41  gs_print_epl(uint64_t addr, bool valid, const char *str)
      42  {
      43  	if (!valid) {
      44  		if (str)
      45  			printf("%s", str);
      46  		else
      47  			printf("%#" PRIx64, addr);
      48  
      49  		return;
      50  	}
      51  
      52  	struct gs_epl *gsepl = (struct gs_epl *) (uintptr_t) addr;
      53  
      54  	printf("[{");
      55  
      56  # if VERBOSE
      57  	if (gsepl->pad1)
      58  		printf("pad1=%#02x, ", gsepl->pad1);
      59  
      60  	printf("gs_eam=%#02x /* extended addressing mode: %u, "
      61  	       "basic addressing mode: %u */"
      62  	       ", gs_eci=%#02x /* CPU in TX: %u, CPU in CX: %u, "
      63  	       "instruction: %s */"
      64  	       ", gs_eai=%#02x /* DAT: %u, address space indication: %u, "
      65  	       "AR number: %u */, ",
      66  	       gsepl->gs_eam, gsepl->e, gsepl->b,
      67  	       gsepl->gs_eci, gsepl->tx, gsepl->cx,
      68  	       gsepl->in ? "LLGFGS": "LGG",
      69  	       gsepl->gs_eai, gsepl->t, gsepl->as, gsepl->ar);
      70  
      71  	if (gsepl->pad2)
      72  		printf("pad2=%#08x, ", gsepl->pad2);
      73  # endif /* VERBOSE */
      74  
      75  	printf("gs_eha=%#llx, ", (unsigned long long) gsepl->gs_eha);
      76  
      77  # if VERBOSE
      78  	printf("gs_eia=%#llx, gs_eoa=%#llx, gs_eir=%#llx, gs_era=%#llx",
      79  	       (unsigned long long) gsepl->gs_eia,
      80  	       (unsigned long long) gsepl->gs_eoa,
      81  	       (unsigned long long) gsepl->gs_eir,
      82  	       (unsigned long long) gsepl->gs_era);
      83  # else /* !VERBOSE */
      84  	printf("...");
      85  # endif /* VERBOSE */
      86  
      87  	printf("}]");
      88  }
      89  
      90  static void
      91  gs_set_cb(kernel_ulong_t addr, bool valid, bool epl_valid,
      92  	  const char *bc_str, const char *epl_str)
      93  {
      94  	static const kernel_ulong_t bogus_cmd_mask =
      95  		(kernel_ulong_t) 0xda7a105700000000ULL;
      96  
      97  	long rc;
      98  
      99  	printf("s390_guarded_storage(GS_SET_BC_CB, ");
     100  
     101  	if (valid) {
     102  		struct gs_cb *gscb = (struct gs_cb *) (uintptr_t) addr;
     103  
     104  		printf("{");
     105  
     106  		if (gscb->reserved)
     107  			printf("reserved=%#016llx, ",
     108  			       (unsigned long long) gscb->reserved);
     109  
     110  		printf("gsd=%#16llx",
     111  		       (unsigned long long) gscb->gsd);
     112  # if VERBOSE
     113  		printf(" /* GS origin: ");
     114  
     115  		unsigned int gsc = gscb->gsd & 0x3F;
     116  		unsigned int gls = (gscb->gsd >> 8) & 7;
     117  		bool gsc_valid = gsc >= 25 && gsc <= 56;
     118  
     119  		if (gsc_valid) {
     120  			uint64_t gls = gscb->gsd >> gsc;
     121  			int field_size = 2 + (67 - gsc) / 4;
     122  
     123  			printf("%#0*" PRIx64, field_size, gls);
     124  		} else {
     125  			printf("[invalid]");
     126  		}
     127  
     128  		printf(", guard load shift: %u, GS characteristic: %u */",
     129  		       gls, gsc);
     130  # endif /* VERBOSE */
     131  
     132  		printf(", gssm=%#016llx, gs_epl_a=",
     133  		       (unsigned long long) gscb->gssm);
     134  
     135  		gs_print_epl(gscb->gs_epl_a, epl_valid, epl_str);
     136  
     137  		printf("}");
     138  	} else {
     139  		if (bc_str)
     140  			printf("%s", bc_str);
     141  		else
     142  			printf("%#llx", (unsigned long long) addr);
     143  	}
     144  
     145  	rc = syscall(__NR_s390_guarded_storage,
     146  		     GS_SET_BC_CB | bogus_cmd_mask, addr);
     147  	printf(") = %s\n", sprintrc(rc));
     148  }
     149  
     150  int
     151  main(void)
     152  {
     153  	static const kernel_ulong_t bogus_cmd =
     154  		(kernel_ulong_t) 0xdeafbeefdeadc0deULL;
     155  	static const kernel_ulong_t bogus_addr =
     156  		(kernel_ulong_t) 0xfacefeedac0ffeedULL;
     157  
     158  	TAIL_ALLOC_OBJECT_CONST_PTR(struct gs_cb, gscb);
     159  	TAIL_ALLOC_OBJECT_CONST_PTR(struct gs_epl, gsepl);
     160  
     161  	long rc;
     162  
     163  	rc = syscall(__NR_s390_guarded_storage, 5, 0);
     164  	printf("s390_guarded_storage(0x5 /* GS_??? */, NULL) = %s\n",
     165  	       sprintrc(rc));
     166  
     167  	rc = syscall(__NR_s390_guarded_storage, bogus_cmd, bogus_addr);
     168  	printf("s390_guarded_storage(%#x /* GS_??? */, %#lx) = %s\n",
     169  	       (unsigned) bogus_cmd, (unsigned long) bogus_addr, sprintrc(rc));
     170  
     171  	gs_no_arg(ARG_STR(GS_BROADCAST));
     172  	gs_no_arg(ARG_STR(GS_CLEAR_BC_CB));
     173  	gs_no_arg(ARG_STR(GS_DISABLE));
     174  	gs_no_arg(ARG_STR(GS_ENABLE));
     175  
     176  	fill_memory(gscb, sizeof(*gscb));
     177  	fill_memory_ex(gsepl, sizeof(*gsepl), 0xA5, 0x5A);
     178  
     179  	gs_set_cb(0, false, false, "NULL", NULL);
     180  	gs_set_cb((uintptr_t) (gscb + 1), false, false, NULL, NULL);
     181  
     182  	gscb->gs_epl_a = 0;
     183  	gs_set_cb((uintptr_t) gscb, true, false, NULL, "NULL");
     184  
     185  	fill_memory_ex(gscb, sizeof(*gscb), 0x5A, 0xA5);
     186  	gscb->gs_epl_a = (uintptr_t) (gsepl + 1) |
     187  		 (sizeof(kernel_ulong_t) < sizeof(uint64_t) ?
     188  			0xc0debad000000000ULL : 0);
     189  	gs_set_cb((uintptr_t) gscb, true, false, NULL, NULL);
     190  
     191  	fill_memory_ex(gscb, sizeof(*gscb), 0xA7, 0xA5);
     192  	gscb->gs_epl_a = (uintptr_t) gsepl;
     193  	gs_set_cb((uintptr_t) gscb, true, true, NULL, NULL);
     194  
     195  	fill_memory_ex(gscb, sizeof(*gscb), 0x55, 0xAA);
     196  	fill_memory_ex(gsepl, sizeof(*gsepl), 0x5A, 0xA5);
     197  	gscb->gs_epl_a = (uintptr_t) gsepl;
     198  	gs_set_cb((uintptr_t) gscb, true, true, NULL, NULL);
     199  
     200  	puts("+++ exited with 0 +++");
     201  	return 0;
     202  }
     203  
     204  #else
     205  
     206  SKIP_MAIN_UNDEFINED("__NR_s390_guarded_storage && HAVE_ASM_GUARDED_STORAGE_H")
     207  
     208  #endif