-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests/tcg/s390x: Test precise self-modifying code handling
Add small softmmu and user tests to prevent regressions. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20230807114921.438881-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
- Loading branch information
Showing
4 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ ASM_TESTS = \ | |
lpswe-early \ | ||
lra \ | ||
mc \ | ||
precise-smc-softmmu \ | ||
ssm-early \ | ||
stosm-early \ | ||
stpq \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Test s390x-softmmu precise self-modifying code handling. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
.org 0x8e | ||
program_interruption_code: | ||
.org 0x150 | ||
program_old_psw: | ||
.org 0x1D0 /* program new PSW */ | ||
.quad 0x180000000,pgm /* 64-bit mode */ | ||
.org 0x200 /* lowcore padding */ | ||
.globl _start | ||
_start: | ||
lctlg %c0,%c0,c0 | ||
lghi %r0,15 | ||
|
||
/* Test 1: replace sgr with agr. */ | ||
lghi %r1,21 | ||
vl %v0,patch1 | ||
jg 1f /* start a new TB */ | ||
0: | ||
.org . + 6 /* pad patched code to 16 bytes */ | ||
1: | ||
vstl %v0,%r0,0b /* start writing before TB */ | ||
sgr %r1,%r1 /* this becomes `agr %r1,%r1` */ | ||
cgijne %r1,42,failure | ||
|
||
/* Test 2: replace agr with division by zero. */ | ||
vl %v0,patch2 | ||
jg 1f /* start a new TB */ | ||
0: | ||
.org . + 6 /* pad patched code to 16 bytes */ | ||
1: | ||
vstl %v0,%r0,0b /* start writing before TB */ | ||
sgr %r1,%r1 /* this becomes `d %r0,zero` */ | ||
failure: | ||
lpswe failure_psw | ||
|
||
pgm: | ||
chhsi program_interruption_code,0x9 /* divide exception? */ | ||
jne failure | ||
clc program_old_psw(16),expected_old_psw2 /* correct old PSW? */ | ||
jne failure | ||
lpswe success_psw | ||
|
||
patch1: | ||
.fill 12 /* replaces padding and stpq */ | ||
agr %r1,%r1 /* replaces sgr */ | ||
patch2: | ||
.fill 12 /* replaces padding and stpq */ | ||
d %r0,zero /* replaces sgr */ | ||
zero: | ||
.long 0 | ||
expected_old_psw2: | ||
.quad 0x200180000000,failure /* cc is from addition */ | ||
.align 8 | ||
c0: | ||
.quad 0x60000 /* AFP, VX */ | ||
success_psw: | ||
.quad 0x2000000000000,0xfff /* see is_special_wait_psw() */ | ||
failure_psw: | ||
.quad 0x2000000000000,0 /* disabled wait */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Test s390x-linux-user precise self-modifying code handling. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
#include <assert.h> | ||
#include <sys/mman.h> | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
|
||
extern __uint128_t __attribute__((__aligned__(1))) smc; | ||
extern __uint128_t __attribute__((__aligned__(1))) patch; | ||
|
||
int main(void) | ||
{ | ||
char *aligned_smc = (char *)((uintptr_t)&smc & ~0xFFFULL); | ||
char *smc_end = (char *)&smc + sizeof(smc); | ||
uint64_t value = 21; | ||
int err; | ||
|
||
err = mprotect(aligned_smc, smc_end - aligned_smc, | ||
PROT_READ | PROT_WRITE | PROT_EXEC); | ||
assert(err == 0); | ||
|
||
asm("jg 0f\n" /* start a new TB */ | ||
"patch: .byte 0,0,0,0,0,0\n" /* replaces padding */ | ||
".byte 0,0,0,0,0,0\n" /* replaces vstl */ | ||
"agr %[value],%[value]\n" /* replaces sgr */ | ||
"smc: .org . + 6\n" /* pad patched code to 16 bytes */ | ||
"0: vstl %[patch],%[idx],%[smc]\n" /* start writing before TB */ | ||
"sgr %[value],%[value]" /* this becomes `agr %r0,%r0` */ | ||
: [smc] "=R" (smc) | ||
, [value] "+r" (value) | ||
: [patch] "v" (patch) | ||
, [idx] "r" (sizeof(patch) - 1) | ||
: "cc"); | ||
|
||
return value == 42 ? EXIT_SUCCESS : EXIT_FAILURE; | ||
} |