user-exec: Push resume-from-signal code out to handle_cpu_signal()

Since the only caller of page_unprotect() which might cause it to
need to call cpu_resume_from_signal() is handle_cpu_signal() in
the user-mode code, push the longjump handling out to that function.

Since this is the only caller of cpu_resume_from_signal() which
passes a non-NULL puc argument, split the non-NULL handling into
a new cpu_exit_tb_from_sighandler() function. This allows us
to merge the softmmu and usermode implementations of the
cpu_resume_from_signal() function, which are now identical.

Backports commit f213e72f2356b77768b9cb73814a3b26ad5a0099 from qemu
This commit is contained in:
Peter Maydell 2018-02-24 17:21:00 -05:00 committed by Lioncash
parent 37b7538d85
commit b2013255aa
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 9 additions and 8 deletions

View file

@ -26,11 +26,8 @@
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
*/
#if defined(CONFIG_SOFTMMU)
void cpu_resume_from_signal(CPUState *cpu, void *puc)
{
#endif
/* XXX: restore cpu registers saved in host registers */
cpu->exception_index = -1;

View file

@ -2059,7 +2059,7 @@ static int page_check_range(target_ulong start, target_ulong len, int flags)
/* unprotect the page if it was put read-only because it
contains translated code */
if (!(p->flags & PAGE_WRITE)) {
if (!page_unprotect(addr, 0, NULL)) {
if (!page_unprotect(addr, 0)) {
return -1;
}
}
@ -2069,8 +2069,12 @@ static int page_check_range(target_ulong start, target_ulong len, int flags)
}
/* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was successfully handled. */
static int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
* page. Return 0 if the fault was not handled, 1 if it was handled,
* and 2 if it was handled but the caller must cause the TB to be
* immediately exited. (We can only return 2 if the 'pc' argument is
* non-zero.)
*/
int page_unprotect(target_ulong address, uintptr_t pc)
{
unsigned int prot;
PageDesc *p;
@ -2103,7 +2107,7 @@ static int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
the corresponding translated code. */
if (tb_invalidate_phys_page(addr, pc)) {
mmap_unlock();
cpu_resume_from_signal(current_cpu, puc);
return 2;
}
#ifdef DEBUG_TB_CHECK
tb_invalidate_check(addr);

View file

@ -28,7 +28,7 @@ void tb_invalidate_phys_range(struct uc_struct *uc, tb_page_addr_t start, tb_pag
void tb_cleanup(struct uc_struct *uc);
#ifdef CONFIG_USER_ONLY
int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
int page_unprotect(target_ulong address, uintptr_t pc);
#endif
#endif /* TRANSLATE_ALL_H */