mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
tests/tcg/s390x: Test modifying code using the MVC instruction
Add a small test to prevent regressions. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-ID: <20250128001338.11474-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
e43ced8be1
commit
b497b0376c
2 changed files with 83 additions and 0 deletions
|
@ -42,6 +42,7 @@ $(ASM_TESTS): LDFLAGS += -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
|
|||
$(ASM_TESTS): $(LINK_SCRIPT)
|
||||
TESTS += $(ASM_TESTS)
|
||||
|
||||
MULTIARCH_TESTS += mvc-smc
|
||||
S390X_MULTIARCH_RUNTIME_OBJS = head64.o console.o $(MINILIB_OBJS)
|
||||
$(MULTIARCH_TESTS): $(S390X_MULTIARCH_RUNTIME_OBJS)
|
||||
$(MULTIARCH_TESTS): LDFLAGS += $(S390X_MULTIARCH_RUNTIME_OBJS)
|
||||
|
|
82
tests/tcg/s390x/mvc-smc.c
Normal file
82
tests/tcg/s390x/mvc-smc.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Test modifying code using the MVC instruction.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <minilib.h>
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define BR_14_SIZE 2
|
||||
#define RWX_OFFSET 2
|
||||
|
||||
static unsigned char rw[PAGE_SIZE + BR_14_SIZE];
|
||||
static unsigned char rwx[RWX_OFFSET + sizeof(rw)]
|
||||
__attribute__((aligned(PAGE_SIZE)));
|
||||
|
||||
typedef unsigned long (*function_t)(unsigned long);
|
||||
|
||||
static int emit_function(unsigned char *p, int n)
|
||||
{
|
||||
int i = 0, val = 0;
|
||||
|
||||
while (i < n - 2) {
|
||||
/* aghi %r2,1 */
|
||||
p[i++] = 0xa7;
|
||||
p[i++] = 0x2b;
|
||||
p[i++] = 0x00;
|
||||
p[i++] = 0x01;
|
||||
val++;
|
||||
}
|
||||
|
||||
/* br %r14 */
|
||||
p[i++] = 0x07;
|
||||
p[i++] = 0xfe;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void memcpy_mvc(void *dest, void *src, unsigned long n)
|
||||
{
|
||||
while (n >= 256) {
|
||||
asm("mvc 0(256,%[dest]),0(%[src])"
|
||||
:
|
||||
: [dest] "a" (dest)
|
||||
, [src] "a" (src)
|
||||
: "memory");
|
||||
dest += 256;
|
||||
src += 256;
|
||||
n -= 256;
|
||||
}
|
||||
asm("exrl %[n],0f\n"
|
||||
"j 1f\n"
|
||||
"0: mvc 0(1,%[dest]),0(%[src])\n"
|
||||
"1:"
|
||||
:
|
||||
: [dest] "a" (dest)
|
||||
, [src] "a" (src)
|
||||
, [n] "a" (n)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int expected, size;
|
||||
|
||||
/* Create a TB. */
|
||||
size = sizeof(rwx) - RWX_OFFSET - 4;
|
||||
expected = emit_function(rwx + RWX_OFFSET, size);
|
||||
if (((function_t)(rwx + RWX_OFFSET))(0) != expected) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Overwrite the TB. */
|
||||
size += 4;
|
||||
expected = emit_function(rw, size);
|
||||
memcpy_mvc(rwx + RWX_OFFSET, rw, size);
|
||||
if (((function_t)(rwx + RWX_OFFSET))(0) != expected) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue