Message ID | 20220311184911.557245-4-iii@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix BRASL and BRCL with large negative offsets | expand |
On 11.03.22 19:49, Ilya Leoshkevich wrote: > Add a small test in order to prevent regressions. > > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> > --- > tests/tcg/s390x/Makefile.target | 1 + > tests/tcg/s390x/branch-relative-long.c | 29 ++++++++++++++++++++++++++ > 2 files changed, 30 insertions(+) > create mode 100644 tests/tcg/s390x/branch-relative-long.c > > diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target > index 257c568c58..fd34b130f7 100644 > --- a/tests/tcg/s390x/Makefile.target > +++ b/tests/tcg/s390x/Makefile.target > @@ -15,6 +15,7 @@ TESTS+=mvc > TESTS+=shift > TESTS+=trap > TESTS+=signals-s390x > +TESTS+=branch-relative-long > > ifneq ($(HAVE_GDB_BIN),) > GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py > diff --git a/tests/tcg/s390x/branch-relative-long.c b/tests/tcg/s390x/branch-relative-long.c > new file mode 100644 > index 0000000000..b9fcee9873 > --- /dev/null > +++ b/tests/tcg/s390x/branch-relative-long.c > @@ -0,0 +1,29 @@ > +#include <assert.h> > +#include <stddef.h> > +#include <sys/mman.h> > + > +int main(void) > +{ > + const unsigned short opcodes[] = { > + 0xc005, /* brasl %r0 */ > + 0xc0f4, /* brcl 0xf */ > + }; > + size_t length = 0x100000006; > + unsigned char *buf; > + int i; > + > + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + assert(buf != MAP_FAILED); > + > + *(unsigned short *)&buf[0] = 0x07fe; /* br %r14 */ > + *(unsigned int *)&buf[0x100000002] = 0x80000000; > + for (i = 0; i < sizeof(opcodes) / sizeof(opcodes[0]); i++) { > + *(unsigned short *)&buf[0x100000000] = opcodes[i]; > + ((void (*)(void))&buf[0x100000000])(); > + } Hmmm, can't we write some "nice" inline asm instead?
On Fri, 2022-03-11 at 19:57 +0100, David Hildenbrand wrote: > On 11.03.22 19:49, Ilya Leoshkevich wrote: > > Add a small test in order to prevent regressions. > > > > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> > > --- > > tests/tcg/s390x/Makefile.target | 1 + > > tests/tcg/s390x/branch-relative-long.c | 29 > > ++++++++++++++++++++++++++ > > 2 files changed, 30 insertions(+) > > create mode 100644 tests/tcg/s390x/branch-relative-long.c > > > > diff --git a/tests/tcg/s390x/Makefile.target > > b/tests/tcg/s390x/Makefile.target > > index 257c568c58..fd34b130f7 100644 > > --- a/tests/tcg/s390x/Makefile.target > > +++ b/tests/tcg/s390x/Makefile.target > > @@ -15,6 +15,7 @@ TESTS+=mvc > > TESTS+=shift > > TESTS+=trap > > TESTS+=signals-s390x > > +TESTS+=branch-relative-long > > > > ifneq ($(HAVE_GDB_BIN),) > > GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py > > diff --git a/tests/tcg/s390x/branch-relative-long.c > > b/tests/tcg/s390x/branch-relative-long.c > > new file mode 100644 > > index 0000000000..b9fcee9873 > > --- /dev/null > > +++ b/tests/tcg/s390x/branch-relative-long.c > > @@ -0,0 +1,29 @@ > > +#include <assert.h> > > +#include <stddef.h> > > +#include <sys/mman.h> > > + > > +int main(void) > > +{ > > + const unsigned short opcodes[] = { > > + 0xc005, /* brasl %r0 */ > > + 0xc0f4, /* brcl 0xf */ > > + }; > > + size_t length = 0x100000006; > > + unsigned char *buf; > > + int i; > > + > > + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, > > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > > + assert(buf != MAP_FAILED); > > + > > + *(unsigned short *)&buf[0] = 0x07fe; /* br %r14 */ > > + *(unsigned int *)&buf[0x100000002] = 0x80000000; > > + for (i = 0; i < sizeof(opcodes) / sizeof(opcodes[0]); i++) { > > + *(unsigned short *)&buf[0x100000000] = opcodes[i]; > > + ((void (*)(void))&buf[0x100000000])(); > > + } > > Hmmm, can't we write some "nice" inline asm instead? > > If we do this in a straightforward way, then the resulting binary will be 4G large. But maybe there is a way to play games with sections, I'll need to think about it.
On 3/11/22 10:49, Ilya Leoshkevich wrote: > + size_t length = 0x100000006; > + unsigned char *buf; > + int i; > + > + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + assert(buf != MAP_FAILED); I'm thinking exit success here, as such a large allocation may well fail depending on the host. r~
Am 11.03.22 um 21:32 schrieb Richard Henderson: > On 3/11/22 10:49, Ilya Leoshkevich wrote: >> + size_t length = 0x100000006; >> + unsigned char *buf; >> + int i; >> + >> + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, >> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >> + assert(buf != MAP_FAILED); > > I'm thinking exit success here, as such a large allocation may well fail depending on the host. What about using MAP_NORESERVE ?
On 14.03.22 09:30, Christian Borntraeger wrote: > > > Am 11.03.22 um 21:32 schrieb Richard Henderson: >> On 3/11/22 10:49, Ilya Leoshkevich wrote: >>> + size_t length = 0x100000006; >>> + unsigned char *buf; >>> + int i; >>> + >>> + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, >>> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >>> + assert(buf != MAP_FAILED); >> >> I'm thinking exit success here, as such a large allocation may well fail depending on the host. > > What about using MAP_NORESERVE ? +1
On 3/14/22 01:30, Christian Borntraeger wrote: > > > Am 11.03.22 um 21:32 schrieb Richard Henderson: >> On 3/11/22 10:49, Ilya Leoshkevich wrote: >>> + size_t length = 0x100000006; >>> + unsigned char *buf; >>> + int i; >>> + >>> + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, >>> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); >>> + assert(buf != MAP_FAILED); >> >> I'm thinking exit success here, as such a large allocation may well fail depending on >> the host. > > What about using MAP_NORESERVE ? That can help, certainly. But that doesn't affect RLIMIT_AS, or a 32-bit host. r~
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index 257c568c58..fd34b130f7 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -15,6 +15,7 @@ TESTS+=mvc TESTS+=shift TESTS+=trap TESTS+=signals-s390x +TESTS+=branch-relative-long ifneq ($(HAVE_GDB_BIN),) GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py diff --git a/tests/tcg/s390x/branch-relative-long.c b/tests/tcg/s390x/branch-relative-long.c new file mode 100644 index 0000000000..b9fcee9873 --- /dev/null +++ b/tests/tcg/s390x/branch-relative-long.c @@ -0,0 +1,29 @@ +#include <assert.h> +#include <stddef.h> +#include <sys/mman.h> + +int main(void) +{ + const unsigned short opcodes[] = { + 0xc005, /* brasl %r0 */ + 0xc0f4, /* brcl 0xf */ + }; + size_t length = 0x100000006; + unsigned char *buf; + int i; + + buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf != MAP_FAILED); + + *(unsigned short *)&buf[0] = 0x07fe; /* br %r14 */ + *(unsigned int *)&buf[0x100000002] = 0x80000000; + for (i = 0; i < sizeof(opcodes) / sizeof(opcodes[0]); i++) { + *(unsigned short *)&buf[0x100000000] = opcodes[i]; + ((void (*)(void))&buf[0x100000000])(); + } + + munmap(buf, length); + + return 0; +}
Add a small test in order to prevent regressions. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> --- tests/tcg/s390x/Makefile.target | 1 + tests/tcg/s390x/branch-relative-long.c | 29 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/tcg/s390x/branch-relative-long.c