From: "Alex Bennée" <alex.bennee@linaro.org>
To: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Richard Henderson <richard.henderson@linaro.org>,
Eduardo Habkost <eduardo@habkost.net>,
qemu-devel@nongnu.org
Subject: Re: [PATCH] tests/tcg/x86_64: add cross-modifying code test
Date: Sat, 03 Sep 2022 10:13:03 +0100 [thread overview]
Message-ID: <87sfl8lt0e.fsf@linaro.org> (raw)
In-Reply-To: <20220902174637.1174258-1-iii@linux.ibm.com>
Ilya Leoshkevich <iii@linux.ibm.com> writes:
> commit f025692c992c ("accel/tcg: Clear PAGE_WRITE before translation")
> fixed cross-modifying code handling, but did not add a test. The
> changed code was further improved recently [1], and I was not sure
> whether these modifications were safe (spoiler: they were fine).
>
> Add a test to make sure there are no regressions.
>
> [1] https://lists.gnu.org/archive/html/qemu-devel/2022-09/msg00034.html
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
> tests/tcg/x86_64/Makefile.target | 6 +-
> tests/tcg/x86_64/cross-modifying-code.c | 80 +++++++++++++++++++++++++
> 2 files changed, 85 insertions(+), 1 deletion(-)
> create mode 100644 tests/tcg/x86_64/cross-modifying-code.c
>
> diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target
> index b71a6bcd5e..58e7bfd681 100644
> --- a/tests/tcg/x86_64/Makefile.target
> +++ b/tests/tcg/x86_64/Makefile.target
> @@ -10,6 +10,7 @@ include $(SRC_PATH)/tests/tcg/i386/Makefile.target
>
> ifeq ($(filter %-linux-user, $(TARGET)),$(TARGET))
> X86_64_TESTS += vsyscall
> +X86_64_TESTS += cross-modifying-code
> TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64
> else
> TESTS=$(MULTIARCH_TESTS)
> @@ -20,5 +21,8 @@ test-x86_64: LDFLAGS+=-lm -lc
> test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
> $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
>
> -vsyscall: $(SRC_PATH)/tests/tcg/x86_64/vsyscall.c
> +%: $(SRC_PATH)/tests/tcg/x86_64/%.c
> $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
You shouldn't need to redefine the default rule when you can tweak the flags
> +
> +smc: CFLAGS+=-pthread
> +smc: LDFLAGS+=-pthread
I think this must be from an old iteration because:
make[1]: Entering directory '/home/alex/lsrc/qemu.git/builds/all/tests/tcg/x86_64-linux-user'
cc -Wall -Werror -O0 -g -fno-strict-aliasing /home/alex/lsrc/qemu.git/tests/tcg/x86_64/cross-modifying-code.c -o cross-modifying-code -static
/usr/bin/ld: /tmp/ccK05RAk.o: in function `main':
/home/alex/lsrc/qemu.git/tests/tcg/x86_64/cross-modifying-code.c:64: undefined reference to `pthread_create'
/usr/bin/ld: /home/alex/lsrc/qemu.git/tests/tcg/x86_64/cross-modifying-code.c:73: undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
make[1]: *** [/home/alex/lsrc/qemu.git/tests/tcg/x86_64/Makefile.target:25: cross-modifying-code] Error 1
make[1]: Leaving directory '/home/alex/lsrc/qemu.git/builds/all/tests/tcg/x86_64-linux-user'
make: *** [/home/alex/lsrc/qemu.git/tests/Makefile.include:52: build-tcg-tests-x86_64-linux-user] Error 2
> diff --git a/tests/tcg/x86_64/cross-modifying-code.c b/tests/tcg/x86_64/cross-modifying-code.c
> new file mode 100644
> index 0000000000..2704df6061
> --- /dev/null
> +++ b/tests/tcg/x86_64/cross-modifying-code.c
> @@ -0,0 +1,80 @@
> +/*
> + * Test patching code, running in one thread, from another thread.
> + *
> + * Intel SDM calls this "cross-modifying code" and recommends a special
> + * sequence, which requires both threads to cooperate.
> + *
> + * Linux kernel uses a different sequence that does not require cooperation and
> + * involves patching the first byte with int3.
> + *
> + * Finally, there is user-mode software out there that simply uses atomics, and
> + * that seems to be good enough in practice. Test that QEMU has no problems
> + * with this as well.
> + */
> +
> +#include <assert.h>
> +#include <pthread.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +
> +void add1_or_nop(long *x);
> +asm(".pushsection .rwx,\"awx\",@progbits\n"
> + ".globl add1_or_nop\n"
> + /* addq $0x1,(%rdi) */
> + "add1_or_nop: .byte 0x48, 0x83, 0x07, 0x01\n"
> + "ret\n"
> + ".popsection\n");
> +
> +#define THREAD_WAIT 0
> +#define THREAD_PATCH 1
> +#define THREAD_STOP 2
> +
> +static void *thread_func(void *arg)
> +{
> + int val = 0x0026748d; /* nop */
> +
> + while (true) {
> + switch (__atomic_load_n((int *)arg, __ATOMIC_SEQ_CST)) {
> + case THREAD_WAIT:
> + break;
> + case THREAD_PATCH:
> + val = __atomic_exchange_n((int *)&add1_or_nop, val,
> + __ATOMIC_SEQ_CST);
> + break;
> + case THREAD_STOP:
> + return NULL;
> + default:
> + assert(false);
> + __builtin_unreachable();
> + }
> + }
> +}
> +
> +#define INITIAL 42
> +#define COUNT 1000000
> +
> +int main(void)
> +{
> + int command = THREAD_WAIT;
> + pthread_t thread;
> + long x = 0;
> + int err;
> + int i;
> +
> + err = pthread_create(&thread, NULL, &thread_func, &command);
> + assert(err == 0);
> +
> + __atomic_store_n(&command, THREAD_PATCH, __ATOMIC_SEQ_CST);
> + for (i = 0; i < COUNT; i++) {
> + add1_or_nop(&x);
> + }
> + __atomic_store_n(&command, THREAD_STOP, __ATOMIC_SEQ_CST);
> +
> + err = pthread_join(thread, NULL);
> + assert(err == 0);
> +
> + assert(x >= INITIAL);
> + assert(x <= INITIAL + COUNT);
> +
> + return EXIT_SUCCESS;
> +}
--
Alex Bennée
next prev parent reply other threads:[~2022-09-03 9:15 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-02 17:46 [PATCH] tests/tcg/x86_64: add cross-modifying code test Ilya Leoshkevich
2022-09-03 9:13 ` Alex Bennée [this message]
2022-09-05 15:44 ` Ilya Leoshkevich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87sfl8lt0e.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=eduardo@habkost.net \
--cc=iii@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.