From: Richard Henderson <richard.henderson@linaro.org>
To: Yeqi Fu <fufuyqqqqqq@gmail.com>, alex.bennee@linaro.org
Cc: qemu-devel@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>,
Eduardo Habkost <eduardo@habkost.net>
Subject: Re: [RFC v2 3/6] target/i386: Add native library calls
Date: Wed, 7 Jun 2023 12:08:02 -0700 [thread overview]
Message-ID: <592d1cc2-9e32-4526-f8fe-7595544a7263@linaro.org> (raw)
In-Reply-To: <20230607164750.829586-4-fufuyqqqqqq@gmail.com>
On 6/7/23 09:47, Yeqi Fu wrote:
> + arg0 = *(target_ulong *)g2h(cs, env->regs[R_ESP] + 4); \
> + arg1 = *(target_ulong *)g2h(cs, env->regs[R_ESP] + 8); \
> + arg2 = *(target_ulong *)g2h(cs, env->regs[R_ESP] + 12);
This is not correct, and will fail on big-endian hosts.
You need to use
uintptr_t ra = GETPC();
cpu_ldl_data_ra(env, guest_pointer, ra);
which will (amongst other things) take care of the byte swapping.
> +void helper_native_memcpy(CPUX86State *env)
> +{
> + CPUState *cs = env_cpu(env);
> + NATIVE_FN_W_3W();
> + void *ret;
> + void *dest = g2h(cs, arg0);
> + void *src = g2h(cs, arg1);
> + size_t n = (size_t)arg2;
> + ret = memcpy(dest, src, n);
> + env->regs[R_EAX] = (target_ulong)h2g(ret);
> +}
You need to do something for the case in which either src or dst is not accessible.
Routines like cpu_ldl_data_ra handle this for you, but you don't want to use that for memcpy.
There are several ways of doing this. None of the existing helpers are ideal.
(A) void *dest = probe_write(env, arg0, arg2, MMU_USER_IDX, ra);
void *src = probe_read(env, arg1, arg2, MMU_USER_IDX, ra);
which will raise SIGSEGV in case any byte of either region is not correctly mapped, and
also perform the guest-to-host address remapping. However, probe_* are written to expect
probing of no more than one page. Which means you'd need a loop, processing remaining
page fractions.
(B) There is page_check_range(), which can check a large region, but doesn't handle
address translation. And you still wind up with a race condition if another thread
changes page mappings at the same time.
(C) Perform the address translation etc yourself, and then protect the actual host memory
operation in the same way as exec/cpu_ldst.h functions:
set_helper_retaddr(ra);
memcpy(dest, src, n);
clear_helper_retaddr();
In this case you must also validate that 'n' is representable. This is only an issue for
32-bit host and 64-bit guest. A check like (arg2 > SIZE_MAX) is likely to generate a
silly warning about always false comparison on 64-bit hosts. Therefore I suggest
if (n != arg2) {
/*
* Overflow of size_t means that sequential pointer access would wrap.
* We know that NULL is unmapped, so at least that one byte would fault.
* There is nothing in the specification of memcpy that requires bytes
* to be accessed in order, so we are allowed to fault early.
*/
cpu_loop_exit_sigsegv(env_cpu(env), 0, MMU_DATA_LOAD, true, ra);
}
Finally, you know the return value from the specification of memcpy: arg0.
There is no need to remap the return value back from host to guest space.
r~
next prev parent reply other threads:[~2023-06-07 19:08 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-07 16:47 [RFC v2 0/6] Native Library Calls Yeqi Fu
2023-06-07 16:47 ` [RFC v2 1/6] build: Add configure options for native calls Yeqi Fu
2023-06-09 5:08 ` Manos Pitsidianakis
2023-06-12 11:54 ` Alex Bennée
2023-06-12 13:02 ` Alex Bennée
2023-06-07 16:47 ` [RFC v2 2/6] Add the libnative library Yeqi Fu
2023-06-15 7:59 ` Alex Bennée
2023-06-07 16:47 ` [RFC v2 3/6] target/i386: Add native library calls Yeqi Fu
2023-06-07 19:08 ` Richard Henderson [this message]
2023-06-07 19:19 ` Richard Henderson
2023-06-07 16:47 ` [RFC v2 4/6] target/mips: " Yeqi Fu
2023-06-07 19:15 ` Richard Henderson
2023-06-07 16:47 ` [RFC v2 5/6] target/arm: " Yeqi Fu
2023-06-07 16:47 ` [RFC v2 6/6] linux-user: Add '-native-bypass' option Yeqi Fu
2023-06-09 5:24 ` Manos Pitsidianakis
2023-06-12 13:06 ` Alex Bennée
2023-06-12 13:23 ` Alex Bennée
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=592d1cc2-9e32-4526-f8fe-7595544a7263@linaro.org \
--to=richard.henderson@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=eduardo@habkost.net \
--cc=fufuyqqqqqq@gmail.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).