Re: [PATCH v2 23/35] semihosting: Write back semihosting data before completion callback

2023-01-25 Thread Philippe Mathieu-Daudé

On 24/1/23 19:01, Alex Bennée wrote:

From: Keith Packard 

'lock_user' allocates a host buffer to shadow a target buffer,
'unlock_user' copies that host buffer back to the target and frees the
host memory. If the completion function uses the target buffer, it
must be called after unlock_user to ensure the data are present.

This caused the arm-compatible TARGET_SYS_READC to fail as the
completion function, common_semi_readc_cb, pulled data from the target
buffer which would not have been gotten the console data.

I decided to fix all instances of this pattern instead of just the
console_read function to make things consistent and potentially fix
bugs in other cases.

Signed-off-by: Keith Packard 
Reviewed-by: Richard Henderson 
Message-Id: <20221012014822.1242170-1-kei...@keithp.com>
Signed-off-by: Alex Bennée 
---
  semihosting/syscalls.c | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2 23/35] semihosting: Write back semihosting data before completion callback

2023-01-24 Thread Alex Bennée
From: Keith Packard 

'lock_user' allocates a host buffer to shadow a target buffer,
'unlock_user' copies that host buffer back to the target and frees the
host memory. If the completion function uses the target buffer, it
must be called after unlock_user to ensure the data are present.

This caused the arm-compatible TARGET_SYS_READC to fail as the
completion function, common_semi_readc_cb, pulled data from the target
buffer which would not have been gotten the console data.

I decided to fix all instances of this pattern instead of just the
console_read function to make things consistent and potentially fix
bugs in other cases.

Signed-off-by: Keith Packard 
Reviewed-by: Richard Henderson 
Message-Id: <20221012014822.1242170-1-kei...@keithp.com>
Signed-off-by: Alex Bennée 
---
 semihosting/syscalls.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 5893c760c5..ba28194b59 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -319,11 +319,11 @@ static void host_read(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 ret = RETRY_ON_EINTR(read(gf->hostfd, ptr, len));
 if (ret == -1) {
-complete(cs, -1, errno);
 unlock_user(ptr, buf, 0);
+complete(cs, -1, errno);
 } else {
-complete(cs, ret, 0);
 unlock_user(ptr, buf, ret);
+complete(cs, ret, 0);
 }
 }
 
@@ -339,8 +339,8 @@ static void host_write(CPUState *cs, 
gdb_syscall_complete_cb complete,
 return;
 }
 ret = write(gf->hostfd, ptr, len);
-complete(cs, ret, ret == -1 ? errno : 0);
 unlock_user(ptr, buf, 0);
+complete(cs, ret, ret == -1 ? errno : 0);
 }
 
 static void host_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -426,8 +426,8 @@ static void host_stat(CPUState *cs, gdb_syscall_complete_cb 
complete,
 ret = -1;
 }
 }
-complete(cs, ret, err);
 unlock_user(name, fname, 0);
+complete(cs, ret, err);
 }
 
 static void host_remove(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -444,8 +444,8 @@ static void host_remove(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 
 ret = remove(p);
-complete(cs, ret, ret ? errno : 0);
 unlock_user(p, fname, 0);
+complete(cs, ret, ret ? errno : 0);
 }
 
 static void host_rename(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -469,9 +469,9 @@ static void host_rename(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 
 ret = rename(ostr, nstr);
-complete(cs, ret, ret ? errno : 0);
 unlock_user(ostr, oname, 0);
 unlock_user(nstr, nname, 0);
+complete(cs, ret, ret ? errno : 0);
 }
 
 static void host_system(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -488,8 +488,8 @@ static void host_system(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 
 ret = system(p);
-complete(cs, ret, ret == -1 ? errno : 0);
 unlock_user(p, cmd, 0);
+complete(cs, ret, ret == -1 ? errno : 0);
 }
 
 static void host_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -554,8 +554,8 @@ static void staticfile_read(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 memcpy(ptr, gf->staticfile.data + gf->staticfile.off, len);
 gf->staticfile.off += len;
-complete(cs, len, 0);
 unlock_user(ptr, buf, len);
+complete(cs, len, 0);
 }
 
 static void staticfile_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -608,8 +608,8 @@ static void console_read(CPUState *cs, 
gdb_syscall_complete_cb complete,
 return;
 }
 ret = qemu_semihosting_console_read(cs, ptr, len);
-complete(cs, ret, 0);
 unlock_user(ptr, buf, ret);
+complete(cs, ret, 0);
 }
 
 static void console_write(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -624,8 +624,8 @@ static void console_write(CPUState *cs, 
gdb_syscall_complete_cb complete,
 return;
 }
 ret = qemu_semihosting_console_write(ptr, len);
-complete(cs, ret ? ret : -1, ret ? 0 : EIO);
 unlock_user(ptr, buf, 0);
+complete(cs, ret ? ret : -1, ret ? 0 : EIO);
 }
 
 static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
-- 
2.34.1