Message ID | 20191228231124.18307-14-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | cputlb: Remove support for MMU_MODE*_SUFFIX | expand |
On Sunday, December 29, 2019, Richard Henderson < richard.henderson@linaro.org> wrote: > This finishes the new interface began with the previous patch. > Document the interface and deprecate MMU_MODE<N>_SUFFIX. > > Reviewed-by: Alex Bennée <alex.bennee@linaro.org> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > include/exec/cpu_ldst.h | 80 +++++++++++++- > docs/devel/loads-stores.rst | 211 ++++++++++++++++++++++++++---------- > 2 files changed, 230 insertions(+), 61 deletions(-) > > Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com> > diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h > index ef59ed61e4..41b98ba801 100644 > --- a/include/exec/cpu_ldst.h > +++ b/include/exec/cpu_ldst.h > @@ -25,9 +25,13 @@ > * > * The syntax for the accessors is: > * > - * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr) > + * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr) > + * cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr) > + * cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmu_idx, retaddr) > * > - * store: cpu_st{sign}{size}_{mmusuffix}(env, ptr, val) > + * store: cpu_st{size}_{mmusuffix}(env, ptr, val) > + * cpu_st{size}_{mmusuffix}_ra(env, ptr, val, retaddr) > + * cpu_st{size}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr) > * > * sign is: > * (empty): for 32 and 64 bit sizes > @@ -40,9 +44,10 @@ > * l: 32 bits > * q: 64 bits > * > - * mmusuffix is one of the generic suffixes "data" or "code", or > - * (for softmmu configs) a target-specific MMU mode suffix as defined > - * in target cpu.h. > + * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx". > + * The "mmuidx" suffix carries an extra mmu_idx argument that specifies > + * the index to use; the "data" and "code" suffixes take the index from > + * cpu_mmu_index(). > */ > #ifndef CPU_LDST_H > #define CPU_LDST_H > @@ -145,6 +150,71 @@ static inline void clear_helper_retaddr(void) > #undef MEMSUFFIX > #undef CODE_ACCESS > > +/* > + * Provide the same *_mmuidx_ra interface as for softmmu. > + * The mmu_idx argument is ignored. > + */ > + > +static inline uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr > addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_ldub_data_ra(env, addr, ra); > +} > + > +static inline uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr > addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_lduw_data_ra(env, addr, ra); > +} > + > +static inline uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_ldl_data_ra(env, addr, ra); > +} > + > +static inline uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_ldq_data_ra(env, addr, ra); > +} > + > +static inline int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_ldsb_data_ra(env, addr, ra); > +} > + > +static inline int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + int mmu_idx, uintptr_t ra) > +{ > + return cpu_ldsw_data_ra(env, addr, ra); > +} > + > +static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + uint32_t val, int mmu_idx, uintptr_t > ra) > +{ > + cpu_stb_data_ra(env, addr, val, ra); > +} > + > +static inline void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + uint32_t val, int mmu_idx, uintptr_t > ra) > +{ > + cpu_stw_data_ra(env, addr, val, ra); > +} > + > +static inline void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + uint32_t val, int mmu_idx, uintptr_t > ra) > +{ > + cpu_stl_data_ra(env, addr, val, ra); > +} > + > +static inline void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr, > + uint64_t val, int mmu_idx, uintptr_t > ra) > +{ > + cpu_stq_data_ra(env, addr, val, ra); > +} > + > #else > > /* Needed for TCG_OVERSIZED_GUEST */ > diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst > index 8a5bc912a5..03aa9e7ff8 100644 > --- a/docs/devel/loads-stores.rst > +++ b/docs/devel/loads-stores.rst > @@ -72,31 +72,34 @@ Regexes for git grep > - ``\<ldn_\([hbl]e\)?_p\>`` > - ``\<stn_\([hbl]e\)?_p\>`` > > -``cpu_{ld,st}_*`` > -~~~~~~~~~~~~~~~~~ > +``cpu_{ld,st}*_mmuidx_ra`` > +~~~~~~~~~~~~~~~~~~~~~~~~~~ > > -These functions operate on a guest virtual address. Be aware > -that these functions may cause a guest CPU exception to be > -taken (e.g. for an alignment fault or MMU fault) which will > -result in guest CPU state being updated and control longjumping > -out of the function call. They should therefore only be used > -in code that is implementing emulation of the target CPU. > +These functions operate on a guest virtual address plus a context, > +known as a "mmu index" or ``mmuidx``, which controls how that virtual > +address is translated. The meaning of the indexes are target specific, > +but specifying a particular index might be necessary if, for instance, > +the helper requires an "always as non-privileged" access rather that > +the default access for the current state of the guest CPU. > > -These functions may throw an exception (longjmp() back out > -to the top level TCG loop). This means they must only be used > -from helper functions where the translator has saved all > -necessary CPU state before generating the helper function call. > -It's usually better to use the ``_ra`` variants described below > -from helper functions, but these functions are the right choice > -for calls made from hooks like the CPU do_interrupt hook or > -when you know for certain that the translator had to save all > -the CPU state that ``cpu_restore_state()`` would restore anyway. > +These functions may cause a guest CPU exception to be taken > +(e.g. for an alignment fault or MMU fault) which will result in > +guest CPU state being updated and control longjmp'ing out of the > +function call. They should therefore only be used in code that is > +implementing emulation of the guest CPU. > + > +The ``retaddr`` parameter is used to control unwinding of the > +guest CPU state in case of a guest CPU exception. This is passed > +to ``cpu_restore_state()``. Therefore the value should either be 0, > +to indicate that the guest CPU state is already synchronized, or > +the result of ``GETPC()`` from the top level ``HELPER(foo)`` > +function, which is a return address into the generated code. > > Function names follow the pattern: > > -load: ``cpu_ld{sign}{size}_{mmusuffix}(env, ptr)`` > +load: ``cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmuidx, retaddr)`` > > -store: ``cpu_st{size}_{mmusuffix}(env, ptr, val)`` > +store: ``cpu_st{size}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)`` > > ``sign`` > - (empty) : for 32 or 64 bit sizes > @@ -109,56 +112,151 @@ store: ``cpu_st{size}_{mmusuffix}(env, ptr, val)`` > - ``l`` : 32 bits > - ``q`` : 64 bits > > -``mmusuffix`` is one of the generic suffixes ``data`` or ``code``, or > -(for softmmu configs) a target-specific MMU mode suffix as defined > -in the target's ``cpu.h``. > +Regexes for git grep: > + - ``\<cpu_ld[us]\?[bwlq]_mmuidx_ra\>`` > + - ``\<cpu_st[bwlq]_mmuidx_ra\>`` > > -Regexes for git grep > - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-Z0-9]\+\>`` > - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+\>`` > +``cpu_{ld,st}*_data_ra`` > +~~~~~~~~~~~~~~~~~~~~~~~~ > > -``cpu_{ld,st}_*_ra`` > -~~~~~~~~~~~~~~~~~~~~ > - > -These functions work like the ``cpu_{ld,st}_*`` functions except > -that they also take a ``retaddr`` argument. This extra argument > -allows for correct unwinding of any exception that is taken, > -and should generally be the result of GETPC() called directly > -from the top level HELPER(foo) function (i.e. the return address > -in the generated code). > +These functions work like the ``cpu_{ld,st}_mmuidx_ra`` functions > +except that the ``mmuidx`` parameter is taken from the current mode > +of the guest CPU, as determined by ``cpu_mmu_index(env, false)``. > > These are generally the preferred way to do accesses by guest > -virtual address from helper functions; see the documentation > -of the non-``_ra`` variants for when those would be better. > - > -Calling these functions with a ``retaddr`` argument of 0 is > -equivalent to calling the non-``_ra`` version of the function. > +virtual address from helper functions, unless the access should > +be performed with a context other than the default. > > Function names follow the pattern: > > -load: ``cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr)`` > +load: ``cpu_ld{sign}{size}_data_ra(env, ptr, ra)`` > > -store: ``cpu_st{sign}{size}_{mmusuffix}_ra(env, ptr, val, retaddr)`` > +store: ``cpu_st{size}_data_ra(env, ptr, val, ra)`` > + > +``sign`` > + - (empty) : for 32 or 64 bit sizes > + - ``u`` : unsigned > + - ``s`` : signed > + > +``size`` > + - ``b`` : 8 bits > + - ``w`` : 16 bits > + - ``l`` : 32 bits > + - ``q`` : 64 bits > + > +Regexes for git grep: > + - ``\<cpu_ld[us]\?[bwlq]_data_ra\>`` > + - ``\<cpu_st[bwlq]_data_ra\>`` > + > +``cpu_{ld,st}*_data`` > +~~~~~~~~~~~~~~~~~~~~~ > + > +These functions work like the ``cpu_{ld,st}_data_ra`` functions > +except that the ``retaddr`` parameter is 0, and thus does not > +unwind guest CPU state. > + > +This means they must only be used from helper functions where the > +translator has saved all necessary CPU state. These functions are > +the right choice for calls made from hooks like the CPU ``do_interrupt`` > +hook or when you know for certain that the translator had to save all > +the CPU state anyway. > + > +Function names follow the pattern: > + > +load: ``cpu_ld{sign}{size}_data(env, ptr)`` > + > +store: ``cpu_st{size}_data(env, ptr, val)`` > + > +``sign`` > + - (empty) : for 32 or 64 bit sizes > + - ``u`` : unsigned > + - ``s`` : signed > + > +``size`` > + - ``b`` : 8 bits > + - ``w`` : 16 bits > + - ``l`` : 32 bits > + - ``q`` : 64 bits > > Regexes for git grep > - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-Z0-9]\+_ra\>`` > - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+_ra\>`` > + - ``\<cpu_ld[us]\?[bwlq]_data\>`` > + - ``\<cpu_st[bwlq]_data\+\>`` > > -``helper_*_{ld,st}*mmu`` > -~~~~~~~~~~~~~~~~~~~~~~~~ > +``cpu_ld*_code`` > +~~~~~~~~~~~~~~~~ > + > +These functions perform a read for instruction execution. The ``mmuidx`` > +parameter is taken from the current mode of the guest CPU, as determined > +by ``cpu_mmu_index(env, true)``. The ``retaddr`` parameter is 0, and > +thus does not unwind guest CPU state, because CPU state is always > +synchronized while translating instructions. Any guest CPU exception > +that is raised will indicate an instruction execution fault rather than > +a data read fault. > + > +In general these functions should not be used directly during translation. > +There are wrapper functions that are to be used which also take care of > +plugins for tracing. > + > +Function names follow the pattern: > + > +load: ``cpu_ld{sign}{size}_code(env, ptr)`` > + > +``sign`` > + - (empty) : for 32 or 64 bit sizes > + - ``u`` : unsigned > + - ``s`` : signed > + > +``size`` > + - ``b`` : 8 bits > + - ``w`` : 16 bits > + - ``l`` : 32 bits > + - ``q`` : 64 bits > + > +Regexes for git grep: > + - ``\<cpu_ld[us]\?[bwlq]_code\>`` > + > +``translator_ld*`` > +~~~~~~~~~~~~~~~~~~ > + > +These functions are a wrapper for ``cpu_ld*_code`` which also perform > +any actions required by any tracing plugins. They are only to be > +called during the translator callback ``translate_insn``. > + > +There is a set of functions ending in ``_swap`` which, if the parameter > +is true, returns the value in the endianness that is the reverse of > +the guest native endianness, as determined by ``TARGET_WORDS_BIGENDIAN``. > + > +Function names follow the pattern: > + > +load: ``translator_ld{sign}{size}(env, ptr)`` > + > +swap: ``translator_ld{sign}{size}_swap(env, ptr, swap)`` > + > +``sign`` > + - (empty) : for 32 or 64 bit sizes > + - ``u`` : unsigned > + - ``s`` : signed > + > +``size`` > + - ``b`` : 8 bits > + - ``w`` : 16 bits > + - ``l`` : 32 bits > + - ``q`` : 64 bits > + > +Regexes for git grep > + - ``\<translator_ld[us]\?[bwlq]\(_swap\)\?\>`` > + > +``helper_*_{ld,st}*_mmu`` > +~~~~~~~~~~~~~~~~~~~~~~~~~ > > These functions are intended primarily to be called by the code > generated by the TCG backend. They may also be called by target > -CPU helper function code. Like the ``cpu_{ld,st}_*_ra`` functions > -they perform accesses by guest virtual address; the difference is > -that these functions allow you to specify an ``opindex`` parameter > -which encodes (among other things) the mmu index to use for the > -access. This is necessary if your helper needs to make an access > -via a specific mmu index (for instance, an "always as non-privileged" > -access) rather than using the default mmu index for the current state > -of the guest CPU. > +CPU helper function code. Like the ``cpu_{ld,st}_mmuidx_ra`` functions > +they perform accesses by guest virtual address, with a given ``mmuidx``. > > -The ``opindex`` parameter should be created by calling > ``make_memop_idx()``. > +These functions specify an ``opindex`` parameter which encodes > +(among other things) the mmu index to use for the access. This parameter > +should be created by calling ``make_memop_idx()``. > > The ``retaddr`` parameter should be the result of GETPC() called directly > from the top level HELPER(foo) function (or 0 if no guest CPU state > @@ -166,8 +264,9 @@ unwinding is required). > > **TODO** The names of these functions are a bit odd for historical > reasons because they were originally expected to be called only from > -within generated code. We should rename them to bring them > -more in line with the other memory access functions. > +within generated code. We should rename them to bring them more in > +line with the other memory access functions. The explicit endianness > +is the only feature they have beyond ``*_mmuidx_ra``. > > load: ``helper_{endian}_ld{sign}{size}_mmu(env, addr, opindex, retaddr)`` > > -- > 2.20.1 > > > <br><br>On Sunday, December 29, 2019, Richard Henderson <<a href="mailto:richard.henderson@linaro.org">richard.henderson@linaro.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This finishes the new interface began with the previous patch.<br> Document the interface and deprecate MMU_MODE<N>_SUFFIX.<br> <br> Reviewed-by: Alex Bennée <<a href="mailto:alex.bennee@linaro.org">alex.bennee@linaro.org</a>><br> Signed-off-by: Richard Henderson <<a href="mailto:richard.henderson@linaro.org">richard.henderson@linaro.org</a>><br> ---<br> include/exec/cpu_ldst.h | 80 +++++++++++++-<br> docs/devel/loads-stores.rst | 211 ++++++++++++++++++++++++++----<wbr>------<br> 2 files changed, 230 insertions(+), 61 deletions(-)<br> <br></blockquote><div><br></div><div><br></div><div><span style="color:rgb(34,34,34);font-size:14px;line-height:22.1200008392334px">Reviewed-by: Aleksandar Markovic <</span><a href="mailto:amarkovic@wavecomp.com" style="font-size:14px;line-height:22.1200008392334px">amarkovic@wavecomp.com</a><span style="color:rgb(34,34,34);font-size:14px;line-height:22.1200008392334px">></span></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h<br> index ef59ed61e4..41b98ba801 100644<br> --- a/include/exec/cpu_ldst.h<br> +++ b/include/exec/cpu_ldst.h<br> @@ -25,9 +25,13 @@<br> *<br> * The syntax for the accessors is:<br> *<br> - * load: cpu_ld{sign}{size}_{mmusuffix}<wbr>(env, ptr)<br> + * load: cpu_ld{sign}{size}_{mmusuffix}<wbr>(env, ptr)<br> + * cpu_ld{sign}{size}_{mmusuffix}<wbr>_ra(env, ptr, retaddr)<br> + * cpu_ld{sign}{size}_mmuidx_ra(<wbr>env, ptr, mmu_idx, retaddr)<br> *<br> - * store: cpu_st{sign}{size}_{mmusuffix}<wbr>(env, ptr, val)<br> + * store: cpu_st{size}_{mmusuffix}(env, ptr, val)<br> + * cpu_st{size}_{mmusuffix}_ra(<wbr>env, ptr, val, retaddr)<br> + * cpu_st{size}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)<br> *<br> * sign is:<br> * (empty): for 32 and 64 bit sizes<br> @@ -40,9 +44,10 @@<br> * l: 32 bits<br> * q: 64 bits<br> *<br> - * mmusuffix is one of the generic suffixes "data" or "code", or<br> - * (for softmmu configs) a target-specific MMU mode suffix as defined<br> - * in target cpu.h.<br> + * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx".<br> + * The "mmuidx" suffix carries an extra mmu_idx argument that specifies<br> + * the index to use; the "data" and "code" suffixes take the index from<br> + * cpu_mmu_index().<br> */<br> #ifndef CPU_LDST_H<br> #define CPU_LDST_H<br> @@ -145,6 +150,71 @@ static inline void clear_helper_retaddr(void)<br> #undef MEMSUFFIX<br> #undef CODE_ACCESS<br> <br> +/*<br> + * Provide the same *_mmuidx_ra interface as for softmmu.<br> + * The mmu_idx argument is ignored.<br> + */<br> +<br> +static inline uint32_t cpu_ldub_mmuidx_ra(<wbr>CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_ldub_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline uint32_t cpu_lduw_mmuidx_ra(<wbr>CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_lduw_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_ldl_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_ldq_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline int cpu_ldsb_mmuidx_ra(<wbr>CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_ldsb_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline int cpu_ldsw_mmuidx_ra(<wbr>CPUArchState *env, abi_ptr addr,<br> + int mmu_idx, uintptr_t ra)<br> +{<br> + return cpu_ldsw_data_ra(env, addr, ra);<br> +}<br> +<br> +static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + uint32_t val, int mmu_idx, uintptr_t ra)<br> +{<br> + cpu_stb_data_ra(env, addr, val, ra);<br> +}<br> +<br> +static inline void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + uint32_t val, int mmu_idx, uintptr_t ra)<br> +{<br> + cpu_stw_data_ra(env, addr, val, ra);<br> +}<br> +<br> +static inline void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + uint32_t val, int mmu_idx, uintptr_t ra)<br> +{<br> + cpu_stl_data_ra(env, addr, val, ra);<br> +}<br> +<br> +static inline void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr,<br> + uint64_t val, int mmu_idx, uintptr_t ra)<br> +{<br> + cpu_stq_data_ra(env, addr, val, ra);<br> +}<br> +<br> #else<br> <br> /* Needed for TCG_OVERSIZED_GUEST */<br> diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst<br> index 8a5bc912a5..03aa9e7ff8 100644<br> --- a/docs/devel/loads-stores.rst<br> +++ b/docs/devel/loads-stores.rst<br> @@ -72,31 +72,34 @@ Regexes for git grep<br> - ``\<ldn_\([hbl]e\)?_p\>``<br> - ``\<stn_\([hbl]e\)?_p\>``<br> <br> -``cpu_{ld,st}_*``<br> -~~~~~~~~~~~~~~~~~<br> +``cpu_{ld,st}*_mmuidx_ra``<br> +~~~~~~~~~~~~~~~~~~~~~~~~~~<br> <br> -These functions operate on a guest virtual address. Be aware<br> -that these functions may cause a guest CPU exception to be<br> -taken (e.g. for an alignment fault or MMU fault) which will<br> -result in guest CPU state being updated and control longjumping<br> -out of the function call. They should therefore only be used<br> -in code that is implementing emulation of the target CPU.<br> +These functions operate on a guest virtual address plus a context,<br> +known as a "mmu index" or ``mmuidx``, which controls how that virtual<br> +address is translated. The meaning of the indexes are target specific,<br> +but specifying a particular index might be necessary if, for instance,<br> +the helper requires an "always as non-privileged" access rather that<br> +the default access for the current state of the guest CPU.<br> <br> -These functions may throw an exception (longjmp() back out<br> -to the top level TCG loop). This means they must only be used<br> -from helper functions where the translator has saved all<br> -necessary CPU state before generating the helper function call.<br> -It's usually better to use the ``_ra`` variants described below<br> -from helper functions, but these functions are the right choice<br> -for calls made from hooks like the CPU do_interrupt hook or<br> -when you know for certain that the translator had to save all<br> -the CPU state that ``cpu_restore_state()`` would restore anyway.<br> +These functions may cause a guest CPU exception to be taken<br> +(e.g. for an alignment fault or MMU fault) which will result in<br> +guest CPU state being updated and control longjmp'ing out of the<br> +function call. They should therefore only be used in code that is<br> +implementing emulation of the guest CPU.<br> +<br> +The ``retaddr`` parameter is used to control unwinding of the<br> +guest CPU state in case of a guest CPU exception. This is passed<br> +to ``cpu_restore_state()``. Therefore the value should either be 0,<br> +to indicate that the guest CPU state is already synchronized, or<br> +the result of ``GETPC()`` from the top level ``HELPER(foo)``<br> +function, which is a return address into the generated code.<br> <br> Function names follow the pattern:<br> <br> -load: ``cpu_ld{sign}{size}_{<wbr>mmusuffix}(env, ptr)``<br> +load: ``cpu_ld{sign}{size}_mmuidx_<wbr>ra(env, ptr, mmuidx, retaddr)``<br> <br> -store: ``cpu_st{size}_{mmusuffix}(<wbr>env, ptr, val)``<br> +store: ``cpu_st{size}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)``<br> <br> ``sign``<br> - (empty) : for 32 or 64 bit sizes<br> @@ -109,56 +112,151 @@ store: ``cpu_st{size}_{mmusuffix}(<wbr>env, ptr, val)``<br> - ``l`` : 32 bits<br> - ``q`` : 64 bits<br> <br> -``mmusuffix`` is one of the generic suffixes ``data`` or ``code``, or<br> -(for softmmu configs) a target-specific MMU mode suffix as defined<br> -in the target's ``cpu.h``.<br> +Regexes for git grep:<br> + - ``\<cpu_ld[us]\?[bwlq]_mmuidx_<wbr>ra\>``<br> + - ``\<cpu_st[bwlq]_mmuidx_ra\>``<br> <br> -Regexes for git grep<br> - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-<wbr>Z0-9]\+\>``<br> - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+<wbr>\>``<br> +``cpu_{ld,st}*_data_ra``<br> +~~~~~~~~~~~~~~~~~~~~~~~~<br> <br> -``cpu_{ld,st}_*_ra``<br> -~~~~~~~~~~~~~~~~~~~~<br> -<br> -These functions work like the ``cpu_{ld,st}_*`` functions except<br> -that they also take a ``retaddr`` argument. This extra argument<br> -allows for correct unwinding of any exception that is taken,<br> -and should generally be the result of GETPC() called directly<br> -from the top level HELPER(foo) function (i.e. the return address<br> -in the generated code).<br> +These functions work like the ``cpu_{ld,st}_mmuidx_ra`` functions<br> +except that the ``mmuidx`` parameter is taken from the current mode<br> +of the guest CPU, as determined by ``cpu_mmu_index(env, false)``.<br> <br> These are generally the preferred way to do accesses by guest<br> -virtual address from helper functions; see the documentation<br> -of the non-``_ra`` variants for when those would be better.<br> -<br> -Calling these functions with a ``retaddr`` argument of 0 is<br> -equivalent to calling the non-``_ra`` version of the function.<br> +virtual address from helper functions, unless the access should<br> +be performed with a context other than the default.<br> <br> Function names follow the pattern:<br> <br> -load: ``cpu_ld{sign}{size}_{<wbr>mmusuffix}_ra(env, ptr, retaddr)``<br> +load: ``cpu_ld{sign}{size}_data_ra(<wbr>env, ptr, ra)``<br> <br> -store: ``cpu_st{sign}{size}_{<wbr>mmusuffix}_ra(env, ptr, val, retaddr)``<br> +store: ``cpu_st{size}_data_ra(env, ptr, val, ra)``<br> +<br> +``sign``<br> + - (empty) : for 32 or 64 bit sizes<br> + - ``u`` : unsigned<br> + - ``s`` : signed<br> +<br> +``size``<br> + - ``b`` : 8 bits<br> + - ``w`` : 16 bits<br> + - ``l`` : 32 bits<br> + - ``q`` : 64 bits<br> +<br> +Regexes for git grep:<br> + - ``\<cpu_ld[us]\?[bwlq]_data_<wbr>ra\>``<br> + - ``\<cpu_st[bwlq]_data_ra\>``<br> +<br> +``cpu_{ld,st}*_data``<br> +~~~~~~~~~~~~~~~~~~~~~<br> +<br> +These functions work like the ``cpu_{ld,st}_data_ra`` functions<br> +except that the ``retaddr`` parameter is 0, and thus does not<br> +unwind guest CPU state.<br> +<br> +This means they must only be used from helper functions where the<br> +translator has saved all necessary CPU state. These functions are<br> +the right choice for calls made from hooks like the CPU ``do_interrupt``<br> +hook or when you know for certain that the translator had to save all<br> +the CPU state anyway.<br> +<br> +Function names follow the pattern:<br> +<br> +load: ``cpu_ld{sign}{size}_data(env, ptr)``<br> +<br> +store: ``cpu_st{size}_data(env, ptr, val)``<br> +<br> +``sign``<br> + - (empty) : for 32 or 64 bit sizes<br> + - ``u`` : unsigned<br> + - ``s`` : signed<br> +<br> +``size``<br> + - ``b`` : 8 bits<br> + - ``w`` : 16 bits<br> + - ``l`` : 32 bits<br> + - ``q`` : 64 bits<br> <br> Regexes for git grep<br> - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-<wbr>Z0-9]\+_ra\>``<br> - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+<wbr>_ra\>``<br> + - ``\<cpu_ld[us]\?[bwlq]_data\>`<wbr>`<br> + - ``\<cpu_st[bwlq]_data\+\>``<br> <br> -``helper_*_{ld,st}*mmu``<br> -~~~~~~~~~~~~~~~~~~~~~~~~<br> +``cpu_ld*_code``<br> +~~~~~~~~~~~~~~~~<br> +<br> +These functions perform a read for instruction execution. The ``mmuidx``<br> +parameter is taken from the current mode of the guest CPU, as determined<br> +by ``cpu_mmu_index(env, true)``. The ``retaddr`` parameter is 0, and<br> +thus does not unwind guest CPU state, because CPU state is always<br> +synchronized while translating instructions. Any guest CPU exception<br> +that is raised will indicate an instruction execution fault rather than<br> +a data read fault.<br> +<br> +In general these functions should not be used directly during translation.<br> +There are wrapper functions that are to be used which also take care of<br> +plugins for tracing.<br> +<br> +Function names follow the pattern:<br> +<br> +load: ``cpu_ld{sign}{size}_code(env, ptr)``<br> +<br> +``sign``<br> + - (empty) : for 32 or 64 bit sizes<br> + - ``u`` : unsigned<br> + - ``s`` : signed<br> +<br> +``size``<br> + - ``b`` : 8 bits<br> + - ``w`` : 16 bits<br> + - ``l`` : 32 bits<br> + - ``q`` : 64 bits<br> +<br> +Regexes for git grep:<br> + - ``\<cpu_ld[us]\?[bwlq]_code\>`<wbr>`<br> +<br> +``translator_ld*``<br> +~~~~~~~~~~~~~~~~~~<br> +<br> +These functions are a wrapper for ``cpu_ld*_code`` which also perform<br> +any actions required by any tracing plugins. They are only to be<br> +called during the translator callback ``translate_insn``.<br> +<br> +There is a set of functions ending in ``_swap`` which, if the parameter<br> +is true, returns the value in the endianness that is the reverse of<br> +the guest native endianness, as determined by ``TARGET_WORDS_BIGENDIAN``.<br> +<br> +Function names follow the pattern:<br> +<br> +load: ``translator_ld{sign}{size}(<wbr>env, ptr)``<br> +<br> +swap: ``translator_ld{sign}{size}_<wbr>swap(env, ptr, swap)``<br> +<br> +``sign``<br> + - (empty) : for 32 or 64 bit sizes<br> + - ``u`` : unsigned<br> + - ``s`` : signed<br> +<br> +``size``<br> + - ``b`` : 8 bits<br> + - ``w`` : 16 bits<br> + - ``l`` : 32 bits<br> + - ``q`` : 64 bits<br> +<br> +Regexes for git grep<br> + - ``\<translator_ld[us]\?[bwlq]\<wbr>(_swap\)\?\>``<br> +<br> +``helper_*_{ld,st}*_mmu``<br> +~~~~~~~~~~~~~~~~~~~~~~~~~<br> <br> These functions are intended primarily to be called by the code<br> generated by the TCG backend. They may also be called by target<br> -CPU helper function code. Like the ``cpu_{ld,st}_*_ra`` functions<br> -they perform accesses by guest virtual address; the difference is<br> -that these functions allow you to specify an ``opindex`` parameter<br> -which encodes (among other things) the mmu index to use for the<br> -access. This is necessary if your helper needs to make an access<br> -via a specific mmu index (for instance, an "always as non-privileged"<br> -access) rather than using the default mmu index for the current state<br> -of the guest CPU.<br> +CPU helper function code. Like the ``cpu_{ld,st}_mmuidx_ra`` functions<br> +they perform accesses by guest virtual address, with a given ``mmuidx``.<br> <br> -The ``opindex`` parameter should be created by calling ``make_memop_idx()``.<br> +These functions specify an ``opindex`` parameter which encodes<br> +(among other things) the mmu index to use for the access. This parameter<br> +should be created by calling ``make_memop_idx()``.<br> <br> The ``retaddr`` parameter should be the result of GETPC() called directly<br> from the top level HELPER(foo) function (or 0 if no guest CPU state<br> @@ -166,8 +264,9 @@ unwinding is required).<br> <br> **TODO** The names of these functions are a bit odd for historical<br> reasons because they were originally expected to be called only from<br> -within generated code. We should rename them to bring them<br> -more in line with the other memory access functions.<br> +within generated code. We should rename them to bring them more in<br> +line with the other memory access functions. The explicit endianness<br> +is the only feature they have beyond ``*_mmuidx_ra``.<br> <br> load: ``helper_{endian}_ld{sign}{<wbr>size}_mmu(env, addr, opindex, retaddr)``<br> <br> -- <br> 2.20.1<br> <br> <br> </blockquote>
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index ef59ed61e4..41b98ba801 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -25,9 +25,13 @@ * * The syntax for the accessors is: * - * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr) + * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr) + * cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr) + * cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmu_idx, retaddr) * - * store: cpu_st{sign}{size}_{mmusuffix}(env, ptr, val) + * store: cpu_st{size}_{mmusuffix}(env, ptr, val) + * cpu_st{size}_{mmusuffix}_ra(env, ptr, val, retaddr) + * cpu_st{size}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr) * * sign is: * (empty): for 32 and 64 bit sizes @@ -40,9 +44,10 @@ * l: 32 bits * q: 64 bits * - * mmusuffix is one of the generic suffixes "data" or "code", or - * (for softmmu configs) a target-specific MMU mode suffix as defined - * in target cpu.h. + * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx". + * The "mmuidx" suffix carries an extra mmu_idx argument that specifies + * the index to use; the "data" and "code" suffixes take the index from + * cpu_mmu_index(). */ #ifndef CPU_LDST_H #define CPU_LDST_H @@ -145,6 +150,71 @@ static inline void clear_helper_retaddr(void) #undef MEMSUFFIX #undef CODE_ACCESS +/* + * Provide the same *_mmuidx_ra interface as for softmmu. + * The mmu_idx argument is ignored. + */ + +static inline uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_ldub_data_ra(env, addr, ra); +} + +static inline uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_lduw_data_ra(env, addr, ra); +} + +static inline uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_ldl_data_ra(env, addr, ra); +} + +static inline uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_ldq_data_ra(env, addr, ra); +} + +static inline int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_ldsb_data_ra(env, addr, ra); +} + +static inline int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr, + int mmu_idx, uintptr_t ra) +{ + return cpu_ldsw_data_ra(env, addr, ra); +} + +static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, + uint32_t val, int mmu_idx, uintptr_t ra) +{ + cpu_stb_data_ra(env, addr, val, ra); +} + +static inline void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr, + uint32_t val, int mmu_idx, uintptr_t ra) +{ + cpu_stw_data_ra(env, addr, val, ra); +} + +static inline void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr, + uint32_t val, int mmu_idx, uintptr_t ra) +{ + cpu_stl_data_ra(env, addr, val, ra); +} + +static inline void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr, + uint64_t val, int mmu_idx, uintptr_t ra) +{ + cpu_stq_data_ra(env, addr, val, ra); +} + #else /* Needed for TCG_OVERSIZED_GUEST */ diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst index 8a5bc912a5..03aa9e7ff8 100644 --- a/docs/devel/loads-stores.rst +++ b/docs/devel/loads-stores.rst @@ -72,31 +72,34 @@ Regexes for git grep - ``\<ldn_\([hbl]e\)?_p\>`` - ``\<stn_\([hbl]e\)?_p\>`` -``cpu_{ld,st}_*`` -~~~~~~~~~~~~~~~~~ +``cpu_{ld,st}*_mmuidx_ra`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ -These functions operate on a guest virtual address. Be aware -that these functions may cause a guest CPU exception to be -taken (e.g. for an alignment fault or MMU fault) which will -result in guest CPU state being updated and control longjumping -out of the function call. They should therefore only be used -in code that is implementing emulation of the target CPU. +These functions operate on a guest virtual address plus a context, +known as a "mmu index" or ``mmuidx``, which controls how that virtual +address is translated. The meaning of the indexes are target specific, +but specifying a particular index might be necessary if, for instance, +the helper requires an "always as non-privileged" access rather that +the default access for the current state of the guest CPU. -These functions may throw an exception (longjmp() back out -to the top level TCG loop). This means they must only be used -from helper functions where the translator has saved all -necessary CPU state before generating the helper function call. -It's usually better to use the ``_ra`` variants described below -from helper functions, but these functions are the right choice -for calls made from hooks like the CPU do_interrupt hook or -when you know for certain that the translator had to save all -the CPU state that ``cpu_restore_state()`` would restore anyway. +These functions may cause a guest CPU exception to be taken +(e.g. for an alignment fault or MMU fault) which will result in +guest CPU state being updated and control longjmp'ing out of the +function call. They should therefore only be used in code that is +implementing emulation of the guest CPU. + +The ``retaddr`` parameter is used to control unwinding of the +guest CPU state in case of a guest CPU exception. This is passed +to ``cpu_restore_state()``. Therefore the value should either be 0, +to indicate that the guest CPU state is already synchronized, or +the result of ``GETPC()`` from the top level ``HELPER(foo)`` +function, which is a return address into the generated code. Function names follow the pattern: -load: ``cpu_ld{sign}{size}_{mmusuffix}(env, ptr)`` +load: ``cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmuidx, retaddr)`` -store: ``cpu_st{size}_{mmusuffix}(env, ptr, val)`` +store: ``cpu_st{size}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)`` ``sign`` - (empty) : for 32 or 64 bit sizes @@ -109,56 +112,151 @@ store: ``cpu_st{size}_{mmusuffix}(env, ptr, val)`` - ``l`` : 32 bits - ``q`` : 64 bits -``mmusuffix`` is one of the generic suffixes ``data`` or ``code``, or -(for softmmu configs) a target-specific MMU mode suffix as defined -in the target's ``cpu.h``. +Regexes for git grep: + - ``\<cpu_ld[us]\?[bwlq]_mmuidx_ra\>`` + - ``\<cpu_st[bwlq]_mmuidx_ra\>`` -Regexes for git grep - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-Z0-9]\+\>`` - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+\>`` +``cpu_{ld,st}*_data_ra`` +~~~~~~~~~~~~~~~~~~~~~~~~ -``cpu_{ld,st}_*_ra`` -~~~~~~~~~~~~~~~~~~~~ - -These functions work like the ``cpu_{ld,st}_*`` functions except -that they also take a ``retaddr`` argument. This extra argument -allows for correct unwinding of any exception that is taken, -and should generally be the result of GETPC() called directly -from the top level HELPER(foo) function (i.e. the return address -in the generated code). +These functions work like the ``cpu_{ld,st}_mmuidx_ra`` functions +except that the ``mmuidx`` parameter is taken from the current mode +of the guest CPU, as determined by ``cpu_mmu_index(env, false)``. These are generally the preferred way to do accesses by guest -virtual address from helper functions; see the documentation -of the non-``_ra`` variants for when those would be better. - -Calling these functions with a ``retaddr`` argument of 0 is -equivalent to calling the non-``_ra`` version of the function. +virtual address from helper functions, unless the access should +be performed with a context other than the default. Function names follow the pattern: -load: ``cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr)`` +load: ``cpu_ld{sign}{size}_data_ra(env, ptr, ra)`` -store: ``cpu_st{sign}{size}_{mmusuffix}_ra(env, ptr, val, retaddr)`` +store: ``cpu_st{size}_data_ra(env, ptr, val, ra)`` + +``sign`` + - (empty) : for 32 or 64 bit sizes + - ``u`` : unsigned + - ``s`` : signed + +``size`` + - ``b`` : 8 bits + - ``w`` : 16 bits + - ``l`` : 32 bits + - ``q`` : 64 bits + +Regexes for git grep: + - ``\<cpu_ld[us]\?[bwlq]_data_ra\>`` + - ``\<cpu_st[bwlq]_data_ra\>`` + +``cpu_{ld,st}*_data`` +~~~~~~~~~~~~~~~~~~~~~ + +These functions work like the ``cpu_{ld,st}_data_ra`` functions +except that the ``retaddr`` parameter is 0, and thus does not +unwind guest CPU state. + +This means they must only be used from helper functions where the +translator has saved all necessary CPU state. These functions are +the right choice for calls made from hooks like the CPU ``do_interrupt`` +hook or when you know for certain that the translator had to save all +the CPU state anyway. + +Function names follow the pattern: + +load: ``cpu_ld{sign}{size}_data(env, ptr)`` + +store: ``cpu_st{size}_data(env, ptr, val)`` + +``sign`` + - (empty) : for 32 or 64 bit sizes + - ``u`` : unsigned + - ``s`` : signed + +``size`` + - ``b`` : 8 bits + - ``w`` : 16 bits + - ``l`` : 32 bits + - ``q`` : 64 bits Regexes for git grep - - ``\<cpu_ld[us]\?[bwlq]_[a-zA-Z0-9]\+_ra\>`` - - ``\<cpu_st[bwlq]_[a-zA-Z0-9]\+_ra\>`` + - ``\<cpu_ld[us]\?[bwlq]_data\>`` + - ``\<cpu_st[bwlq]_data\+\>`` -``helper_*_{ld,st}*mmu`` -~~~~~~~~~~~~~~~~~~~~~~~~ +``cpu_ld*_code`` +~~~~~~~~~~~~~~~~ + +These functions perform a read for instruction execution. The ``mmuidx`` +parameter is taken from the current mode of the guest CPU, as determined +by ``cpu_mmu_index(env, true)``. The ``retaddr`` parameter is 0, and +thus does not unwind guest CPU state, because CPU state is always +synchronized while translating instructions. Any guest CPU exception +that is raised will indicate an instruction execution fault rather than +a data read fault. + +In general these functions should not be used directly during translation. +There are wrapper functions that are to be used which also take care of +plugins for tracing. + +Function names follow the pattern: + +load: ``cpu_ld{sign}{size}_code(env, ptr)`` + +``sign`` + - (empty) : for 32 or 64 bit sizes + - ``u`` : unsigned + - ``s`` : signed + +``size`` + - ``b`` : 8 bits + - ``w`` : 16 bits + - ``l`` : 32 bits + - ``q`` : 64 bits + +Regexes for git grep: + - ``\<cpu_ld[us]\?[bwlq]_code\>`` + +``translator_ld*`` +~~~~~~~~~~~~~~~~~~ + +These functions are a wrapper for ``cpu_ld*_code`` which also perform +any actions required by any tracing plugins. They are only to be +called during the translator callback ``translate_insn``. + +There is a set of functions ending in ``_swap`` which, if the parameter +is true, returns the value in the endianness that is the reverse of +the guest native endianness, as determined by ``TARGET_WORDS_BIGENDIAN``. + +Function names follow the pattern: + +load: ``translator_ld{sign}{size}(env, ptr)`` + +swap: ``translator_ld{sign}{size}_swap(env, ptr, swap)`` + +``sign`` + - (empty) : for 32 or 64 bit sizes + - ``u`` : unsigned + - ``s`` : signed + +``size`` + - ``b`` : 8 bits + - ``w`` : 16 bits + - ``l`` : 32 bits + - ``q`` : 64 bits + +Regexes for git grep + - ``\<translator_ld[us]\?[bwlq]\(_swap\)\?\>`` + +``helper_*_{ld,st}*_mmu`` +~~~~~~~~~~~~~~~~~~~~~~~~~ These functions are intended primarily to be called by the code generated by the TCG backend. They may also be called by target -CPU helper function code. Like the ``cpu_{ld,st}_*_ra`` functions -they perform accesses by guest virtual address; the difference is -that these functions allow you to specify an ``opindex`` parameter -which encodes (among other things) the mmu index to use for the -access. This is necessary if your helper needs to make an access -via a specific mmu index (for instance, an "always as non-privileged" -access) rather than using the default mmu index for the current state -of the guest CPU. +CPU helper function code. Like the ``cpu_{ld,st}_mmuidx_ra`` functions +they perform accesses by guest virtual address, with a given ``mmuidx``. -The ``opindex`` parameter should be created by calling ``make_memop_idx()``. +These functions specify an ``opindex`` parameter which encodes +(among other things) the mmu index to use for the access. This parameter +should be created by calling ``make_memop_idx()``. The ``retaddr`` parameter should be the result of GETPC() called directly from the top level HELPER(foo) function (or 0 if no guest CPU state @@ -166,8 +264,9 @@ unwinding is required). **TODO** The names of these functions are a bit odd for historical reasons because they were originally expected to be called only from -within generated code. We should rename them to bring them -more in line with the other memory access functions. +within generated code. We should rename them to bring them more in +line with the other memory access functions. The explicit endianness +is the only feature they have beyond ``*_mmuidx_ra``. load: ``helper_{endian}_ld{sign}{size}_mmu(env, addr, opindex, retaddr)``