Re: [PATCH for 6.2 12/49] bsd-user: implement path searching

2021-08-07 Thread Kyle Evans
On Sat, Aug 7, 2021 at 10:11 PM Richard Henderson
 wrote:
>
> On 8/7/21 11:42 AM, Warner Losh wrote:
> > +path = g_strdup(p);
> > +if (path == NULL) {
>
> Only returns null when the input is null, which you've already eliminated.
>
> > +static bool find_in_path(char *path, const char *filename, char *retpath,
> > + size_t rpsize)
> > +{
> > +const char *d;
> > +
> > +while ((d = strsep(, ":")) != NULL) {
> > +if (*d == '\0') {
> > +d = ".";
> > +}
> > +if (snprintf(retpath, rpsize, "%s/%s", d, filename) >= 
> > (int)rpsize) {
> > +continue;
> > +}
> > +if (is_there((const char *)retpath)) {
> > +return true;
> > +}
> > +}
> > +return false;
>
> Hmm.  Fixed size retpath buffer isn't ideal.
> Any reason not to use g_find_program_in_path?
>

g_find_program_in_path may work well here, as well...

> I note that we don't search the path at all in linux-user/.
>

IIRC imgact_binmisc will have the resolved path but preserve argv as
it should have been were it not emulated, so we have to re-evaluate
the PATH search here because we try to be faithful to the context.

Thanks,

Kyle Evans



Re: [PATCH for 6.2 22/49] bsd-user: Move per-cpu code into target_arch_cpu.h

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
index 7f2f755a11..71998e5ba5 100644
--- a/bsd-user/i386/target_arch_cpu.c
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -1,6 +1,7 @@
  /*
   *  i386 cpu related code
   *
+ * Copyright (c) 2013 Stacey Son 
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by


Should be in previous.


+static inline void target_cpu_init(CPUX86State *env,
+struct target_pt_regs *regs)
+{
+uint64_t *gdt_table;
+
+env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+env->hflags |= HF_PE_MASK | HF_CPL_MASK;
+if (env->features[FEAT_1_EDX] & CPUID_SSE) {
+env->cr[4] |= CR4_OSFXSR_MASK;
+env->hflags |= HF_OSFXSR_MASK;
+}
+
+/* flags setup : we activate the IRQs by default as in user mode */
+env->eflags |= IF_MASK;
+
+/* register setup */
+env->regs[R_EAX] = regs->eax;
+env->regs[R_EBX] = regs->ebx;
+env->regs[R_ECX] = regs->ecx;
+env->regs[R_EDX] = regs->edx;
+env->regs[R_ESI] = regs->esi;
+env->regs[R_EDI] = regs->edi;
+env->regs[R_EBP] = regs->ebp;
+env->regs[R_ESP] = regs->esp;
+env->eip = regs->eip;
+
+/* interrupt setup */
+env->idt.limit = 255;
+
+env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+bsd_i386_set_idt_base(env->idt.base);
+bsd_i386_set_idt(0, 0);
+bsd_i386_set_idt(1, 0);
+bsd_i386_set_idt(2, 0);
+bsd_i386_set_idt(3, 3);
+bsd_i386_set_idt(4, 3);
+bsd_i386_set_idt(5, 0);
+bsd_i386_set_idt(6, 0);
+bsd_i386_set_idt(7, 0);
+bsd_i386_set_idt(8, 0);
+bsd_i386_set_idt(9, 0);
+bsd_i386_set_idt(10, 0);
+bsd_i386_set_idt(11, 0);
+bsd_i386_set_idt(12, 0);
+bsd_i386_set_idt(13, 0);
+bsd_i386_set_idt(14, 0);
+bsd_i386_set_idt(15, 0);
+bsd_i386_set_idt(16, 0);
+bsd_i386_set_idt(17, 0);
+bsd_i386_set_idt(18, 0);
+bsd_i386_set_idt(19, 0);
+bsd_i386_set_idt(0x80, 3);
+
+/* segment setup */
+env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
+gdt_table = g2h_untagged(env->gdt.base);
+
+bsd_i386_write_dt(_table[__USER_CS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
+
+bsd_i386_write_dt(_table[__USER_DS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
+
+cpu_x86_load_seg(env, R_CS, __USER_CS);
+cpu_x86_load_seg(env, R_SS, __USER_DS);
+cpu_x86_load_seg(env, R_DS, __USER_DS);
+cpu_x86_load_seg(env, R_ES, __USER_DS);
+cpu_x86_load_seg(env, R_FS, __USER_DS);
+cpu_x86_load_seg(env, R_GS, __USER_DS);
+/* This hack makes Wine work... */
+env->segs[R_FS].selector = 0;
+}
+
+static inline void target_cpu_loop(CPUX86State *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr;
+abi_ulong pc;
+/* target_siginfo_t info; */
+
+for (;;) {
+   cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+   cpu_exec_end(cs);
+   process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case 0x80:
+/* syscall from int $0x80 */
+if (bsd_type == target_freebsd) {
+abi_ulong params = (abi_ulong) env->regs[R_ESP] +
+sizeof(int32_t);
+int32_t syscall_nr = env->regs[R_EAX];
+int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
+
+if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
+get_user_s32(syscall_nr, params);
+params += sizeof(int32_t);
+} else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
+get_user_s32(syscall_nr, params);
+params += sizeof(int64_t);
+}
+get_user_s32(arg1, params);
+params += sizeof(int32_t);
+get_user_s32(arg2, params);
+params += sizeof(int32_t);
+get_user_s32(arg3, params);
+params += sizeof(int32_t);
+get_user_s32(arg4, params);
+params += sizeof(int32_t);
+get_user_s32(arg5, params);
+params += sizeof(int32_t);
+get_user_s32(arg6, params);
+params += sizeof(int32_t);
+get_user_s32(arg7, params);
+params += sizeof(int32_t);
+get_user_s32(arg8, params);
+env->regs[R_EAX] = do_freebsd_syscall(env,
+

Re: [PATCH for 6.2 20/49] bsd-user: save the path the qemu emulator

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Save the path to the qemu emulator. This will be used later when we have
a more complete implementation of exec.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
  bsd-user/main.c | 21 +
  bsd-user/qemu.h |  1 +
  2 files changed, 22 insertions(+)


Acked-by: Richard Henderson 


+char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */

...

+len = PATH_MAX;


Maybe better with sizeof?


r~



Re: [PATCH for 6.2 19/49] bsd-user: Include host-os.h from main

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Include host-os.h from main.c to pick up the default OS to emulate.  Set
that default in main().

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/freebsd/host-os.h | 2 ++
  bsd-user/main.c| 4 +++-
  bsd-user/netbsd/host-os.h  | 2 ++
  bsd-user/openbsd/host-os.h | 2 ++
  4 files changed, 9 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 18/49] bsd-user: add host-os.h

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Host OS specific bits for this implementation go in this file.

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/freebsd/host-os.h | 23 +++
  bsd-user/netbsd/host-os.h  | 23 +++
  bsd-user/openbsd/host-os.h | 23 +++
  3 files changed, 69 insertions(+)
  create mode 100644 bsd-user/freebsd/host-os.h
  create mode 100644 bsd-user/netbsd/host-os.h
  create mode 100644 bsd-user/openbsd/host-os.h


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 17/49] bsd-user: assume pthreads and support of __thread

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

All compilers for some time have supported this. Follow linux-user and
eliminate the #define THREAD and unconditionally insert __thread where
needed.

Signed-off-by: Warner Losh
---
  bsd-user/main.c |  2 +-
  bsd-user/qemu.h | 10 +-
  2 files changed, 2 insertions(+), 10 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 16/49] bsd-user: elfload: simplify bswap a bit.

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Reduce the number of ifdefs by always calling the swapping routine, but
making them empty when swapping isn't needed.

Signed-off-by: Warner Losh
---
  bsd-user/elfload.c | 97 ++
  1 file changed, 47 insertions(+), 50 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 15/49] bsd-user: TARGET_NGROUPS unused in this file, remove

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c | 2 --
  1 file changed, 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 14/49] bsd-user: remove a.out support

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Remove still-born a.out support. The BSDs switched from a.out to ELF 20+ years
ago. It's out of scope for bsd-user, and what little support there was would
simply wind up at a not-implemented message. Simplify the whole mess by removing
it entirely. Should future support be required, it would be better to start from
scratch.

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c |   9 +---
  bsd-user/elfload.c | 105 -
  bsd-user/qemu.h|   2 +-
  3 files changed, 21 insertions(+), 95 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 13/49] bsd-user: Eliminate elf personality

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

The linux kernel supports a number of different ELF binaries. The Linux userland
emulator inheritted some of that. And we inheritted it from there. However, for
BSD there's only one kind of ELF file supported per platform, so there's no need
to cope with historical quirks. Simply the code as a result.

Signed-off-by: Warner Losh
---
  bsd-user/elfload.c | 87 --
  bsd-user/qemu.h|  1 -
  2 files changed, 88 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 12/49] bsd-user: implement path searching

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

+path = g_strdup(p);
+if (path == NULL) {


Only returns null when the input is null, which you've already eliminated.


+static bool find_in_path(char *path, const char *filename, char *retpath,
+ size_t rpsize)
+{
+const char *d;
+
+while ((d = strsep(, ":")) != NULL) {
+if (*d == '\0') {
+d = ".";
+}
+if (snprintf(retpath, rpsize, "%s/%s", d, filename) >= (int)rpsize) {
+continue;
+}
+if (is_there((const char *)retpath)) {
+return true;
+}
+}
+return false;


Hmm.  Fixed size retpath buffer isn't ideal.
Any reason not to use g_find_program_in_path?

I note that we don't search the path at all in linux-user/.


r~



Re: [PATCH for 6.2 11/49] bsd-user: Fix calculation of size to allocate

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

It was incorrect to subtract off the size of an unsigned int here.  In
bsd-user fork, this change was made when moving the arch specific items
to specific files.  The size in BSD that's available for the arguments
does not need a return address subtracted from it.

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 10/49] bsd-user: pass the bsd_param into loader_exec

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Pass the bsd_param into loader_exec, and adjust.

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c | 37 +++--
  bsd-user/main.c|  7 ++-
  bsd-user/qemu.h|  3 ++-
  3 files changed, 27 insertions(+), 20 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 09/49] bsd-user: add license

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Pull in the license statement at the top of the bsdload.c file
from the bsd-user fork version of this file. No functional changes.

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c | 17 -
  1 file changed, 16 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 08/49] bsd-user: style nits: fix whitespace issues to be qemu standard

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Signed-off-by: Warner Losh
---
  bsd-user/bsdload.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 07/49] bsd-user: style nits: apply qemu style to these files

2021-08-07 Thread Richard Henderson

On 8/7/21 11:42 AM, Warner Losh wrote:

Fix style wrt {} placement, spaces around () and line lengths.

Signed-off-by: Warner Losh
---
  bsd-user/i386/target_arch_elf.h   | 27 ---
  bsd-user/x86_64/target_arch_elf.h | 11 +++
  2 files changed, 23 insertions(+), 15 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 06/49] bsd-user: merge comments and guards from bsd-user fork

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

Diff reduction against bsd-user fork: bring in the copyright/license
comments, and guard ifdefs.

Signed-off-by: Warner Losh
---
  bsd-user/i386/target_arch_elf.h   | 22 ++
  bsd-user/x86_64/target_arch_elf.h | 23 +++
  2 files changed, 45 insertions(+)


Could reasonably be squashed with previous, but not required.

Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 05/49] bsd-user: move arch specific defines out of elfload.c

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

Move the arcitecture specific defines to target_arch_elf.h and delete them from
elfload.c. unifdef as appropriate for i386 vs x86_64 versions.

Signed-off-by: Warner Losh
---
  bsd-user/elfload.c| 81 +--
  bsd-user/i386/target_arch_elf.h   | 54 +
  bsd-user/x86_64/target_arch_elf.h | 41 
  3 files changed, 97 insertions(+), 79 deletions(-)
  create mode 100644 bsd-user/i386/target_arch_elf.h
  create mode 100644 bsd-user/x86_64/target_arch_elf.h


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 03/49] bsd-user: Add Stacey's copyright to main.c

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

From: Warner Losh

Add Stacey's updated copyright to main.c

Signed-off-by: Warner Losh
Signed-off-by: Stacey Son

Sponsored by:   Netflix
---
  bsd-user/main.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 04/49] bsd-user: Remove all non-x86 code from elfload.c

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

bsd-user only builds x86 at the moment. Remove all non x86 code from
elfload.c. We'll move the x86 code to {i386,x86_64}/target_arch_elf.h
and bring it that support code from the forked bsd-user when the time
comes.

Signed-off-by: Warner Losh
---
  bsd-user/elfload.c | 347 +
  1 file changed, 2 insertions(+), 345 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 02/49] bsd-user: add copyright header to elfload.c

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

From: Warner Losh

Add Stacey's copyright to elfload.c

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/elfload.c | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 6.2 01/49] bsd-user: remove sparc and sparc64

2021-08-07 Thread Richard Henderson

On 8/7/21 11:41 AM, Warner Losh wrote:

From: Warner Losh

These are broken here and in the bsd-user fork. They won't be fixed as
FreeBSD has dropped support for sparc. If people wish to support this in
other BSDs, you're better off starting over than starting from these
files.

Signed-off-by: Warner Losh
---
  bsd-user/main.c| 290 -
  bsd-user/sparc/target_arch_sysarch.h   |  52 -
  bsd-user/sparc/target_syscall.h|  36 ---
  bsd-user/sparc64/target_arch_sysarch.h |  52 -
  bsd-user/sparc64/target_syscall.h  |  37 
  bsd-user/syscall.c |  11 -
  6 files changed, 478 deletions(-)
  delete mode 100644 bsd-user/sparc/target_arch_sysarch.h
  delete mode 100644 bsd-user/sparc/target_syscall.h
  delete mode 100644 bsd-user/sparc64/target_arch_sysarch.h
  delete mode 100644 bsd-user/sparc64/target_syscall.h



Reviewed-by: Richard Henderson 

r~



[PATCH] hw/ssi: imx_spi: Improve chip select handling

2021-08-07 Thread Guenter Roeck
The control register does not really have a means to deselect
all chip selects directly. As result, CS is effectively never
deselected, and connected flash chips fail to perform read
operations since they don't get the expected chip select signals
to reset their state machine.

Normally and per controller documentation one would assume that
chip select should be set whenever a transfer starts (XCH is
set or the tx fifo is written into), and that it should be disabled
whenever a transfer is complete. However, that does not work in
practice: attempts to implement this approach resulted in failures,
presumably because a single transaction can be split into multiple
transfers.

At the same time, there is no explicit signal from the host indicating
if chip select should be active or not. In the absence of such a direct
signal, use the burst length written into the control register to
determine if an access is ongoing or not. Disable all chip selects
if the burst length field in the configuration register is set to 0,
and (re-)enable chip select if a transfer is started. This is possible
because the Linux driver clears the burst length field whenever it
prepares the controller for the next transfer.
This solution  is less than perfect since it effectively only disables
chip select when initiating the next transfer, but it does work with
Linux and should otherwise do no harm.

Stop complaining if the burst length field is set to a value of 0,
since that is done by Linux for every transfer.

With this patch, a command line parameter such as "-drive
file=flash.sabre,format=raw,if=mtd" can be used to instantiate the
flash chip in the sabrelite emulation. Without this patch, the
flash instantiates, but it only reads zeroes.

Signed-off-by: Guenter Roeck 
---
I am not entirely happy with this solution, but it is the best I was
able to come up with. If anyone has a better idea, I'll be happy
to give it a try.

 hw/ssi/imx_spi.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index 189423bb3a..7a093156bd 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -167,6 +167,8 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
 fifo32_num_used(>tx_fifo), fifo32_num_used(>rx_fifo));
 
+qemu_set_irq(s->cs_lines[imx_spi_selected_channel(s)], 0);
+
 while (!fifo32_is_empty(>tx_fifo)) {
 int tx_burst = 0;
 
@@ -385,13 +387,6 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 case ECSPI_CONREG:
 s->regs[ECSPI_CONREG] = value;
 
-burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
-if (burst % 8) {
-qemu_log_mask(LOG_UNIMP,
-  "[%s]%s: burst length %d not supported: rounding up 
to next multiple of 8\n",
-  TYPE_IMX_SPI, __func__, burst);
-}
-
 if (!imx_spi_is_enabled(s)) {
 /* device is disabled, so this is a soft reset */
 imx_spi_soft_reset(s);
@@ -404,9 +399,11 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 
 /* We are in master mode */
 
-for (i = 0; i < ECSPI_NUM_CS; i++) {
-qemu_set_irq(s->cs_lines[i],
- i == imx_spi_selected_channel(s) ? 0 : 1);
+burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH);
+if (burst == 0) {
+for (i = 0; i < ECSPI_NUM_CS; i++) {
+qemu_set_irq(s->cs_lines[i], 1);
+}
 }
 
 if ((value & change_mask & ECSPI_CONREG_SMC) &&
-- 
2.25.1




Re: [PATCH] hw/riscv: virt: Move flash node to root

2021-08-07 Thread Alistair Francis
On Sat, Aug 7, 2021 at 1:57 PM Bin Meng  wrote:
>
> The flash is not inside the SoC, so it's inappropriate to put it
> under the /soc node. Move it to root instead.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  hw/riscv/virt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4a3cd2599a..89fb607c47 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -455,7 +455,7 @@ static void create_fdt(RISCVVirtState *s, const 
> MemMapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ);
>  g_free(name);
>
> -name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase);
> +name = g_strdup_printf("/flash@%" PRIx64, flashbase);
>  qemu_fdt_add_subnode(mc->fdt, name);
>  qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
>  qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg",
> --
> 2.25.1
>
>



Re: [PATCH] target/riscv: Correct a comment in riscv_csrrw()

2021-08-07 Thread Alistair Francis
On Sun, Aug 8, 2021 at 12:10 AM Bin Meng  wrote:
>
> When privilege check fails, RISCV_EXCP_ILLEGAL_INST is returned,
> not -1 (RISCV_EXCP_NONE).
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  target/riscv/csr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 9a4ed18ac5..e747fbe0e9 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1423,7 +1423,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int 
> csrno,
>  target_ulong old_value;
>  RISCVCPU *cpu = env_archcpu(env);
>
> -/* check privileges and return -1 if check fails */
> +/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
>  #if !defined(CONFIG_USER_ONLY)
>  int effective_priv = env->priv;
>  int read_only = get_field(csrno, 0xC00) == 3;
> --
> 2.25.1
>
>



[PATCH for 6.2 49/49] bsd-user: Add '-0 argv0' option to bsd-user/main.c

2021-08-07 Thread Warner Losh
From: Colin Percival 

Previously it was impossible to emulate a program with a file name
different from its argv[0].  With this change, you can run
qemu -0 fakename realname args
which runs the program "realname" with an argv of "fakename args".

Signed-off-by: Colin Percival 
Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 1de5dc189b..c3ecdaf824 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -284,6 +284,7 @@ int main(int argc, char **argv)
 char **target_environ, **wrk;
 envlist_t *envlist = NULL;
 bsd_type = HOST_DEFAULT_BSD_TYPE;
+char * argv0 = NULL;
 
 adjust_ssize();
 
@@ -405,6 +406,8 @@ int main(int argc, char **argv)
 do_strace = 1;
 } else if (!strcmp(r, "trace")) {
 trace_opt_parse(optarg);
+} else if (!strcmp(r, "0")) {
+argv0 = argv[optind++];
 } else {
 usage();
 }
@@ -428,6 +431,8 @@ int main(int argc, char **argv)
 usage();
 }
 filename = argv[optind];
+if (argv0)
+argv[optind] = argv0;
 
 if (!trace_init_backends()) {
 exit(1);
-- 
2.32.0




[PATCH for 6.2 46/49] bsd-user: move qemu_log to later in the file

2021-08-07 Thread Warner Losh
From: Warner Losh 

Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index c8fafa78d0..7ba616a995 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -85,14 +85,6 @@ unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial 
data size limit */
 unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
 unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
-void gemu_log(const char *fmt, ...)
-{
-va_list ap;
-
-va_start(ap, fmt);
-vfprintf(stderr, fmt, ap);
-va_end(ap);
-}
 
 void fork_start(void)
 {
@@ -181,6 +173,15 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+void gemu_log(const char *fmt, ...)
+{
+va_list ap;
+
+va_start(ap, fmt);
+vfprintf(stderr, fmt, ap);
+va_end(ap);
+}
+
 static void
 adjust_ssize(void)
 {
-- 
2.32.0




[PATCH for 6.2 48/49] bsd-user: Implement cpu_copy() helper routine

2021-08-07 Thread Warner Losh
From: Warner Losh 

cpu_copy shouldbe called when processes are creating new threads. It
copies the current state of the CPU to a new cpu state needed for the
new thread.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Signed-off-by: Justin Hibbits 
---
 bsd-user/main.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 2b0716d245..1de5dc189b 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -196,6 +196,36 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+CPUArchState *cpu_copy(CPUArchState *env)
+{
+CPUState *cpu = env_cpu(env);
+CPUState *new_cpu = cpu_create(cpu_type);
+CPUArchState *new_env = new_cpu->env_ptr;
+CPUBreakpoint *bp;
+CPUWatchpoint *wp;
+
+/* Reset non arch specific state */
+cpu_reset(new_cpu);
+
+memcpy(new_env, env, sizeof(CPUArchState));
+
+/*
+ * Clone all break/watchpoints.
+ * Note: Once we support ptrace with hw-debug register access, make sure
+ * BP_CPU break/watchpoints are handled correctly on clone.
+ */
+QTAILQ_INIT(>breakpoints);
+QTAILQ_INIT(>watchpoints);
+QTAILQ_FOREACH(bp, >breakpoints, entry) {
+cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
+}
+QTAILQ_FOREACH(wp, >watchpoints, entry) {
+cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
+}
+
+return new_env;
+}
+
 void gemu_log(const char *fmt, ...)
 {
 va_list ap;
-- 
2.32.0




[PATCH for 6.2 41/49] bsd-user: Add target_os_user.h to capture the user/kernel structures

2021-08-07 Thread Warner Losh
From: Warner Losh 

This file evolved over the years to capture the user/kernel interfaces,
including those that changed over time.

Signed-off-by: Stacey Son 
Signed-off-by: Michal Meloun 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/target_os_user.h | 429 ++
 1 file changed, 429 insertions(+)
 create mode 100644 bsd-user/freebsd/target_os_user.h

diff --git a/bsd-user/freebsd/target_os_user.h 
b/bsd-user/freebsd/target_os_user.h
new file mode 100644
index 00..a265e02439
--- /dev/null
+++ b/bsd-user/freebsd/target_os_user.h
@@ -0,0 +1,429 @@
+/*
+ *  sys/user.h definitions 
+ *
+ *  Copyright (c) 2015 Stacey D. Son (sson at FreeBSD)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_USER_H_
+#define _TARGET_OS_USER_H_
+
+/*
+ * from sys/priority.h
+ */
+struct target_priority {
+uint8_t pri_class;  /* Scheduling class. */
+uint8_t pri_level;  /* Normal priority level. */
+uint8_t pri_native; /* Priority before propogation. */
+uint8_t pri_user;   /* User priority based on p_cpu and p_nice. */
+};
+
+/*
+ * sys/caprights.h
+ */
+#define TARGET_CAP_RIGHTS_VERSION  0
+
+typedef struct target_cap_rights {
+uint64_tcr_rights[TARGET_CAP_RIGHTS_VERSION + 2];
+} target_cap_rights_t;
+
+/*
+ * From sys/_socketaddr_storage.h
+ *
+ */
+#define TARGET_SS_MAXSIZE 128U
+#define TARGET_SS_ALIGNSIZE   (sizeof(__int64_t))
+#define TARGET_SS_PAD1SIZE(TARGET_SS_ALIGNSIZE - sizeof(unsigned char) - \
+sizeof(uint8_t))
+#define TARGET_SS_PAD2SIZE(TARGET_SS_MAXSIZE - sizeof(unsigned char) - \
+sizeof(uint8_t) - TARGET_SS_PAD1SIZE - TARGET_SS_ALIGNSIZE)
+
+struct target_sockaddr_storage {
+unsigned char   ss_len; /* address length */
+uint8_t ss_family;  /* address family */
+char__ss_pad1[TARGET_SS_PAD1SIZE];
+__int64_t   __ss_align; /* force desired struct alignment */
+char__ss_pad2[TARGET_SS_PAD2SIZE];
+};
+
+/*
+ * from sys/user.h
+ */
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031
+#define TARGET_KI_NSPARE_INT2
+#elif defined(__FreeBSD_version) && __FreeBSD_version >= 110
+#define TARGET_KI_NSPARE_INT4
+#elif defined(__FreeBSD_version) && __FreeBSD_version >= 100
+#define TARGET_KI_NSPARE_INT7
+#else
+#define TARGET_KI_NSPARE_INT9
+#endif /* ! __FreeBSD_version >= 100 */
+#define TARGET_KI_NSPARE_LONG   12
+#define TARGET_KI_NSPARE_PTR6
+
+#define TARGET_WMESGLEN 8
+#define TARGET_LOCKNAMELEN  8
+#define TARGET_TDNAMLEN 16
+#define TARGET_COMMLEN  19
+#define TARGET_KI_EMULNAMELEN   16
+#define TARGET_KI_NGROUPS   16
+#define TARGET_LOGNAMELEN   17
+#define TARGET_LOGINCLASSLEN17
+
+#defineTARGET_KF_TYPE_NONE 0
+#defineTARGET_KF_TYPE_VNODE1
+#defineTARGET_KF_TYPE_SOCKET   2
+#defineTARGET_KF_TYPE_PIPE 3
+#defineTARGET_KF_TYPE_FIFO 4
+#defineTARGET_KF_TYPE_KQUEUE   5
+#defineTARGET_KF_TYPE_CRYPTO   6
+#defineTARGET_KF_TYPE_MQUEUE   7
+#defineTARGET_KF_TYPE_SHM  8
+#defineTARGET_KF_TYPE_SEM  9
+#defineTARGET_KF_TYPE_PTS  10
+#defineTARGET_KF_TYPE_PROCDESC 11
+#defineTARGET_KF_TYPE_DEV  12
+#defineTARGET_KF_TYPE_UNKNOWN  255
+
+struct target_kinfo_proc {
+int32_t ki_structsize;  /* size of this structure */
+int32_t ki_layout;  /* reserved: layout identifier */
+abi_ulong   ki_args;/* address of command arguments */
+abi_ulong   ki_paddr;   /* address of proc */
+abi_ulong   ki_addr;/* kernel virtual addr of u-area */
+abi_ulong   ki_tracep;  /* pointer to trace file */
+abi_ulong   ki_textvp;  /* pointer to executable file */
+abi_ulong   ki_fd;  /* pointer to open file info */
+abi_ulong   ki_vmspace; /* pointer to kernel vmspace struct */
+abi_ulong   ki_wchan;   /* sleep address */
+int32_t ki_pid; /* Process identifier */
+int32_t ki_ppid;/* parent process id */
+int32_t ki_pgid;/* process group id */
+int32_t

[PATCH for 6.2 39/49] bsd-user: Need to reset CPU after creation.

2021-08-07 Thread Warner Losh
From: Warner Losh 

Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 36852604f8..08f88d9668 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -405,8 +405,10 @@ int main(int argc, char **argv)
 accel_init_interfaces(ac);
 ac->init_machine(NULL);
 }
+
 cpu = cpu_create(cpu_type);
 env = cpu->env_ptr;
+cpu_reset(cpu);
 thread_cpu = cpu;
 
 if (getenv("QEMU_STRACE")) {
-- 
2.32.0




[PATCH for 6.2 37/49] bsd-user: update debugging in mmap.c

2021-08-07 Thread Warner Losh
From: Warner Losh 

Update the debugging code for new features and different targets.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Sean Bruno 
Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
---
 bsd-user/mmap.c | 49 ++---
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 03119b1f20..99563d61aa 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -68,8 +68,8 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot)
 int prot1, ret;
 
 #ifdef DEBUG_MMAP
-printf("mprotect: start=0x" TARGET_FMT_lx
-   " len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len,
+printf("mprotect: start=0x" TARGET_ABI_FMT_lx
+   "len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
@@ -250,28 +250,37 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 mmap_lock();
 #ifdef DEBUG_MMAP
 {
-printf("mmap: start=0x" TARGET_FMT_lx
-   " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=",
+printf("mmap: start=0x" TARGET_ABI_FMT_lx
+   " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=",
start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
+if (flags & MAP_ALIGNMENT_MASK)
+printf ("MAP_ALIGNED(%u) ", (flags & MAP_ALIGNMENT_MASK) >> 
MAP_ALIGNMENT_SHIFT);
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200035
+if (flags & MAP_GUARD)
+printf("MAP_GUARD ");
+#endif
 if (flags & MAP_FIXED)
 printf("MAP_FIXED ");
-if (flags & MAP_ANON)
+if (flags & MAP_ANONYMOUS)
 printf("MAP_ANON ");
-switch (flags & TARGET_BSD_MAP_FLAGMASK) {
-case MAP_PRIVATE:
-printf("MAP_PRIVATE ");
-break;
-case MAP_SHARED:
-printf("MAP_SHARED ");
-break;
-default:
-printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK);
-break;
-}
-printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset);
+#ifdef MAP_EXCL
+if (flags & MAP_EXCL)
+printf("MAP_EXCL ");
+#endif
+   if (flags & MAP_PRIVATE)
+   printf("MAP_PRIVATE ");
+   if (flags & MAP_SHARED)
+   printf("MAP_SHARED ");
+   if (flags & MAP_NOCORE)
+   printf("MAP_NOCORE ");
+#ifdef MAP_STACK
+   if (flags & MAP_STACK)
+   printf("MAP_STACK ");
+#endif
+printf("fd=%d offset=0x%llx\n", fd, offset);
 }
 #endif
 
@@ -399,7 +408,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 page_set_flags(start, start + len, prot | PAGE_VALID);
  the_end:
 #ifdef DEBUG_MMAP
-printf("ret=0x" TARGET_FMT_lx "\n", start);
+printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);
 page_dump(stdout);
 printf("\n");
 #endif
@@ -416,7 +425,9 @@ int target_munmap(abi_ulong start, abi_ulong len)
 int prot, ret;
 
 #ifdef DEBUG_MMAP
-printf("munmap: start=0x%lx len=0x%lx\n", start, len);
+printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x"
+   TARGET_ABI_FMT_lx "\n",
+   start, len);
 #endif
 if (start & ~TARGET_PAGE_MASK)
 return -EINVAL;
-- 
2.32.0




[PATCH for 6.2 38/49] bsd-user: Update mapping to handle reserved and starting conditions

2021-08-07 Thread Warner Losh
From: Warner Losh 

Update the reserved base based on what platform we're on, as well as the
start of the mmap range. Update routines that find va ranges to interact
with the reserved ranges as well as properly align the mapping (this is
especially important for targets whose page size does not match the
host's). Loop where appropriate when the initial address space offered
by mmap does not meet the contraints.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/main.c |  23 ++-
 bsd-user/mmap.c | 372 
 bsd-user/qemu.h |   5 +-
 3 files changed, 335 insertions(+), 65 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 93ef9298b8..36852604f8 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -49,12 +49,29 @@
 #include "target_arch_cpu.h"
 
 int singlestep;
-unsigned long mmap_min_addr;
 uintptr_t guest_base;
 static const char *cpu_model;
 static const char *cpu_type;
 bool have_guest_base;
+#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
+/*
+ * When running 32-on-64 we should make sure we can fit all of the possible
+ * guest address space into a contiguous chunk of virtual host memory.
+ *
+ * This way we will never overlap with our own libraries or binaries or stack
+ * or anything else that QEMU maps.
+ */
+# ifdef TARGET_MIPS
+/* MIPS only supports 31 bits of virtual address space for user space */
+unsigned long reserved_va = 0x7700;
+# elif defined(TARGET_PPC64)
+unsigned long reserved_va = 0xf000;
+# else
+unsigned long reserved_va = 0xf700;
+# endif
+#else
 unsigned long reserved_va;
+#endif
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
@@ -399,6 +416,10 @@ int main(int argc, char **argv)
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
+if (reserved_va) {
+mmap_next_start = reserved_va;
+}
+
 /*
  * Now that page sizes are configured we can do
  * proper page alignment for guest_base.
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 99563d61aa..07e985b0c5 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -188,64 +188,191 @@ static int mmap_frag(abi_ulong real_start,
 return 0;
 }
 
-static abi_ulong mmap_next_start = 0x4000;
+#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
+# define TASK_UNMAPPED_BASE  (1ul << 38)
+#else
+# define TASK_UNMAPPED_BASE  0x4000
+#endif
+abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
-/* find a free memory area of size 'size'. The search starts at
-   'start'. If 'start' == 0, then a default start address is used.
-   Return -1 if error.
-*/
-/* page_init() marks pages used by the host as reserved to be sure not
-   to use them. */
-static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
+/* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk
+   of guest address space.  */
+static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size, 
abi_ulong alignment)
 {
-abi_ulong addr, addr1, addr_start;
+abi_ulong addr;
+abi_ulong end_addr;
 int prot;
-unsigned long new_brk;
-
-new_brk = (unsigned long)sbrk(0);
-if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) {
-/* This is a hack to catch the host allocating memory with brk().
-   If it uses mmap then we loose.
-   FIXME: We really want to avoid the host allocating memory in
-   the first place, and maybe leave some slack to avoid switching
-   to mmap.  */
-page_set_flags(last_brk & TARGET_PAGE_MASK,
-   TARGET_PAGE_ALIGN(new_brk),
-   PAGE_RESERVED);
+int looped = 0;
+
+if (size > reserved_va) {
+return (abi_ulong)-1;
+}
+
+size = HOST_PAGE_ALIGN(size) + alignment;
+end_addr = start + size;
+if (end_addr > reserved_va) {
+end_addr = reserved_va;
+}
+addr = end_addr - qemu_host_page_size;
+
+while (1) {
+if (addr > end_addr) {
+if (looped) {
+return (abi_ulong)-1;
+}
+end_addr = reserved_va;
+addr = end_addr - qemu_host_page_size;
+looped = 1;
+continue;
+}
+prot = page_get_flags(addr);
+if (prot) {
+end_addr = addr;
+}
+if (end_addr - addr >= size) {
+break;
+}
+addr -= qemu_host_page_size;
+}
+
+if (start == mmap_next_start) {
+mmap_next_start = addr;
+}
+/* addr is sufficiently low to align it up */
+if (alignment != 0)
+addr = (addr + alignment) & ~(alignment - 1);
+return addr;
+}
+
+/*
+ * Find and reserve a free memory area of size 'size'. The search
+ * starts at 'start'.
+ * It must be called with mmap_lock() held.
+ * Return -1 if error.
+ */
+static abi_ulong 

[PATCH for 6.2 36/49] bsd-user: Make cpu_model and cpu_type visible to all of main.c

2021-08-07 Thread Warner Losh
From: Warner Losh 

cpu_model and cpu_type will be used future commits, so move them from
main() scoped to file scoped.

Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 7e20430fb7..93ef9298b8 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -51,6 +51,8 @@
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
+static const char *cpu_model;
+static const char *cpu_type;
 bool have_guest_base;
 unsigned long reserved_va;
 
@@ -197,8 +199,6 @@ static void save_proc_pathname(char *argv0)
 int main(int argc, char **argv)
 {
 const char *filename;
-const char *cpu_model;
-const char *cpu_type;
 const char *log_file = NULL;
 const char *log_mask = NULL;
 struct target_pt_regs regs1, *regs = 
-- 
2.32.0




[PATCH for 6.2 32/49] bsd-user: *BSD specific siginfo defintions

2021-08-07 Thread Warner Losh
From: Warner Losh 

Add FreeBSD, NetBSD and OpenBSD values for the various signal info types
and defines to decode different signals to discover more information
about the specific signal types.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/target_os_siginfo.h | 145 +++
 bsd-user/freebsd/target_os_signal.h  |  78 ++
 bsd-user/i386/target_arch_signal.h   |  94 +
 bsd-user/netbsd/target_os_siginfo.h  |  82 +++
 bsd-user/netbsd/target_os_signal.h   |  70 +
 bsd-user/openbsd/target_os_siginfo.h |  82 +++
 bsd-user/openbsd/target_os_signal.h  |  70 +
 bsd-user/qemu.h  |   3 +-
 bsd-user/syscall_defs.h  |  10 --
 bsd-user/x86_64/target_arch_signal.h |  94 +
 10 files changed, 716 insertions(+), 12 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_siginfo.h
 create mode 100644 bsd-user/freebsd/target_os_signal.h
 create mode 100644 bsd-user/i386/target_arch_signal.h
 create mode 100644 bsd-user/netbsd/target_os_siginfo.h
 create mode 100644 bsd-user/netbsd/target_os_signal.h
 create mode 100644 bsd-user/openbsd/target_os_siginfo.h
 create mode 100644 bsd-user/openbsd/target_os_signal.h
 create mode 100644 bsd-user/x86_64/target_arch_signal.h

diff --git a/bsd-user/freebsd/target_os_siginfo.h 
b/bsd-user/freebsd/target_os_siginfo.h
new file mode 100644
index 00..d12b2e213e
--- /dev/null
+++ b/bsd-user/freebsd/target_os_siginfo.h
@@ -0,0 +1,145 @@
+/*
+ *  FreeBSD siginfo related definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_OS_SIGINFO_H_
+#define _TARGET_OS_SIGINFO_H_
+
+#define TARGET_NSIG 128
+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8)
+#define TARGET_NSIG_WORDS   (TARGET_NSIG / TARGET_NSIG_BPW)
+
+/* this struct defines a stack used during syscall handling */
+typedef struct target_sigaltstack {
+abi_longss_sp;
+abi_ulong   ss_size;
+abi_longss_flags;
+} target_stack_t;
+
+typedef struct {
+uint32_t __bits[TARGET_NSIG_WORDS];
+} target_sigset_t;
+
+struct target_sigaction {
+abi_ulong   _sa_handler;
+int32_t sa_flags;
+target_sigset_t sa_mask;
+};
+
+typedef union target_sigval {
+int32_t sival_int;
+abi_ulong sival_ptr;
+int32_t sigval_int;
+abi_ulong sigval_ptr;
+} target_sigval_t;
+
+typedef struct target_siginfo {
+int32_t si_signo;   /* signal number */
+int32_t si_errno;   /* errno association */
+int32_t si_code;/* signal code */
+int32_t si_pid; /* sending process */
+int32_t si_uid; /* sender's ruid */
+int32_t si_status;  /* exit value */
+abi_ulong si_addr;  /* faulting instruction */
+union target_sigval si_value;   /* signal value */
+union {
+struct {
+int32_t _trapno;/* machine specific trap code */
+} _fault;
+
+/* POSIX.1b timers */
+struct {
+int32_t _timerid;
+int32_t _overrun;
+} _timer;
+
+struct {
+int32_t _mqd;
+} _mesgp;
+
+/* SIGPOLL */
+struct {
+int _band;  /* POLL_IN, POLL_OUT, POLL_MSG */
+} _poll;
+
+struct {
+abi_long __spare1__;
+int32_t  __spare2_[7];
+} __spare__;
+} _reason;
+} target_siginfo_t;
+
+struct target_sigevent {
+abi_int sigev_notify;
+abi_int sigev_signo;
+target_sigval_t sigev_value;
+union {
+abi_int _threadid;
+
+/* The kernel (and thus QEMU) never looks at these;
+ * they're only used as part of the ABI between a
+ * userspace program and libc.
+ */
+struct {
+abi_ulong _function;
+abi_ulong _attribute;
+} _sigev_thread;
+abi_ushort _kevent_flags;
+abi_long _pad[8];
+} _sigev_un;
+};
+
+#define target_si_signo si_signo
+#define target_si_code  si_code
+#define target_si_errno si_errno
+#define target_si_addr  si_addr
+
+/* SIGILL si_codes */
+#define TARGET_ILL_ILLOPC   (1) /* Illegal opcode. */
+#define TARGET_ILL_ILLOPN   (2) /* Illegal operand. */
+#define TARGET_ILL_ILLADR   (3) /* Illegal addressing mode. */
+#define TARGET_ILL_ILLTRP   (4) 

[PATCH for 6.2 44/49] bsd-user: Refactor load_elf_sections and is_target_elf_binary

2021-08-07 Thread Warner Losh
From: Warner Losh 

Factor out load_elf_sections and is_target_elf_binary out of
load_elf_interp.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 350 +
 1 file changed, 164 insertions(+), 186 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index bdf18f3dce..aed28f2f73 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -36,6 +36,8 @@ abi_ulong target_stksiz;
 abi_ulong target_stkbas;
 
 static int elf_core_dump(int signr, CPUArchState *env);
+static int load_elf_sections(const struct elfhdr *hdr, struct elf_phdr *phdr,
+int fd, abi_ulong rbase, abi_ulong *baddrp);
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
@@ -271,16 +273,10 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
  abi_ulong *interp_load_addr)
 {
 struct elf_phdr *elf_phdata  =  NULL;
-struct elf_phdr *eppnt;
-abi_ulong load_addr = 0;
-int load_addr_set = 0;
+abi_ulong rbase;
 int retval;
-abi_ulong last_bss, elf_bss;
-abi_ulong error;
-int i;
+abi_ulong baddr, error;
 
-elf_bss = 0;
-last_bss = 0;
 error = 0;
 
 bswap_ehdr(interp_elf_ex);
@@ -325,6 +321,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 }
 bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
 
+rbase = 0;
 if (interp_elf_ex->e_type == ET_DYN) {
 /*
  * In order to avoid hardcoding the interpreter load
@@ -332,86 +329,25 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
  */
 error = target_mmap(0, INTERP_MAP_SIZE, PROT_NONE,
 MAP_PRIVATE | MAP_ANON, -1, 0);
-if (error == -1) {
+if (rbase == -1) {
 perror("mmap");
 exit(-1);
 }
-load_addr = error;
-load_addr_set = 1;
-}
-
-eppnt = elf_phdata;
-for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++)
-if (eppnt->p_type == PT_LOAD) {
-int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
-int elf_prot = 0;
-abi_ulong vaddr = 0;
-abi_ulong k;
-
-if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
-if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
-if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
-if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
-elf_type |= MAP_FIXED;
-vaddr = eppnt->p_vaddr;
-}
-error = target_mmap(load_addr + TARGET_ELF_PAGESTART(vaddr),
-eppnt->p_filesz + 
TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
-elf_prot,
-elf_type,
-interpreter_fd,
-eppnt->p_offset - 
TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
-
-if (error == -1) {
-/* Real error */
-close(interpreter_fd);
-free(elf_phdata);
-return ~((abi_ulong)0UL);
-}
-
-if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
-load_addr = error;
-load_addr_set = 1;
-}
-
-/*
- * Find the end of the file  mapping for this phdr, and keep
- * track of the largest address we see for this.
- */
-k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
-if (k > elf_bss) elf_bss = k;
+}
 
-/*
- * Do the same thing for the memory mapping - between
- * elf_bss and last_bss is the bss section.
- */
-k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
-if (k > last_bss) last_bss = k;
-}
+error = load_elf_sections(interp_elf_ex, elf_phdata, interpreter_fd, rbase,
+);
+if (error != 0) {
+perror("load_elf_sections");
+exit(-1);
+}
 
 /* Now use mmap to map the library into memory. */
-
 close(interpreter_fd);
-
-/*
- * Now fill out the bss section.  First pad the last page up
- * to the page boundary, and then perform a mmap to make sure
- * that there are zeromapped pages up to and including the last
- * bss page.
- */
-padzero(elf_bss, last_bss);
-elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What 
we have mapped so far */
-
-/* Map the last of the bss segment */
-if (last_bss > elf_bss) {
-target_mmap(elf_bss, last_bss - elf_bss,
-PROT_READ | PROT_WRITE | PROT_EXEC,
-MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-}
 free(elf_phdata);
 
-*interp_load_addr = load_addr;
-return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
+*interp_load_addr = baddr;
+return ((abi_ulong) 

[PATCH for 6.2 31/49] bsd-user: Remove dead #ifdefs from elfload.c

2021-08-07 Thread Warner Losh
From: Warner Losh 

LOW_ELF_STACK doesn't exist on FreeBSD and likely never will. Remove it.
Likewise, remove an #if 0 block that's not useful

Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index a09f8fb315..c0787a4e52 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -558,9 +558,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 abi_ulong elf_entry, interp_load_addr = 0;
 abi_ulong start_code, end_code, start_data, end_data;
 abi_ulong reloc_func_desc = 0;
-#ifdef LOW_ELF_STACK
-abi_ulong elf_stack = ~((abi_ulong)0UL);
-#endif
 
 load_addr = 0;
 load_bias = 0;
@@ -761,11 +758,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 exit(-1);
 }
 
-#ifdef LOW_ELF_STACK
-if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
-elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
-#endif
-
 if (!load_addr_set) {
 load_addr_set = 1;
 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
@@ -823,9 +815,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 close(bprm->fd);
 
-#ifdef LOW_ELF_STACK
-info->start_stack = bprm->p = elf_stack - 4;
-#endif
 bprm->p = target_create_elf_tables(bprm->p, bprm->argc, bprm->envc, 
bprm->stringp,
_ex, load_addr, load_bias, 
interp_load_addr, info);
 info->load_addr = reloc_func_desc;
@@ -842,15 +831,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 padzero(elf_bss, elf_brk);
 
-#if 0
-printf("(start_brk) %x\n" , info->start_brk);
-printf("(end_code) %x\n" , info->end_code);
-printf("(start_code) %x\n" , info->start_code);
-printf("(end_data) %x\n" , info->end_data);
-printf("(start_stack) %x\n" , info->start_stack);
-printf("(brk) %x\n" , info->brk);
-#endif
-
 info->entry = elf_entry;
 
 return 0;
-- 
2.32.0




[PATCH for 6.2 34/49] bsd-user: Fix initializtion of task state

2021-08-07 Thread Warner Losh
From: Warner Losh 

Fix a number of mismerges in initializing the task state. Save a copy of
bprm in this structure and move it earlier before starting to setup
other state. Remove linux specific procfs access to find minimal vm
address that likely is here through a misguided merge. Remove duplicate
initialization as well.

Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 
---
 bsd-user/main.c | 42 --
 bsd-user/qemu.h |  1 +
 2 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 5ca1173f04..b5527537b4 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -205,7 +205,7 @@ int main(int argc, char **argv)
 struct target_pt_regs regs1, *regs = 
 struct image_info info1, *info = 
 struct bsd_binprm bprm;
-TaskState ts1, *ts = 
+TaskState *ts;
 CPUArchState *env;
 CPUState *cpu;
 int optind, rv;
@@ -407,31 +407,7 @@ int main(int argc, char **argv)
  */
 guest_base = HOST_PAGE_ALIGN(guest_base);
 
-/*
- * Read in mmap_min_addr kernel parameter.  This value is used
- * When loading the ELF image to determine whether guest_base
- * is needed.
- *
- * When user has explicitly set the quest base, we skip this
- * test.
- */
-if (!have_guest_base) {
-FILE *fp;
-
-fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
-if (fp != NULL) {
-unsigned long tmp;
-if (fscanf(fp, "%lu", ) == 1) {
-mmap_min_addr = tmp;
-qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
-  mmap_min_addr);
-}
-fclose(fp);
-}
-}
-
-if (loader_exec(filename, argv+optind, target_environ, regs, info,
-) != 0) {
+if (loader_exec(filename, argv+optind, target_environ, regs, info, )) 
{
 printf("Error loading %s\n", filename);
 _exit(1);
 }
@@ -459,21 +435,11 @@ int main(int argc, char **argv)
 qemu_log("entry   0x" TARGET_ABI_FMT_lx "\n", info->entry);
 }
 
-target_set_brk(info->brk);
-syscall_init();
-signal_init();
-
-/*
- * Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
- * generating the prologue until now so that the prologue can take
- * the real value of GUEST_BASE into account.
- */
-tcg_prologue_init(tcg_ctx);
-
 /* build Task State */
-memset(ts, 0, sizeof(TaskState));
+ts = g_new0(TaskState, 1);
 init_task_state(ts);
 ts->info = info;
+ts->bprm = 
 cpu->opaque = ts;
 
 target_set_brk(info->brk);
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index a22fc19cd6..bfd7b8eaa5 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -90,6 +90,7 @@ typedef struct TaskState {
 pid_t ts_tid; /* tid (or pid) of this task */
 
 struct TaskState *next;
+struct bsd_binprm *bprm;
 int used; /* non zero if used */
 struct image_info *info;
 
-- 
2.32.0




[PATCH for 6.2 45/49] bsd-user: Make guest_base an unsigned long

2021-08-07 Thread Warner Losh
From: Warner Losh 

Make the guest_base a plan, uneigned long rather than a uintptr_t. It
isn't really a pointer.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 08f88d9668..c8fafa78d0 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -49,9 +49,9 @@
 #include "target_arch_cpu.h"
 
 int singlestep;
-uintptr_t guest_base;
 static const char *cpu_model;
 static const char *cpu_type;
+unsigned long guest_base;
 bool have_guest_base;
 #if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
 /*
@@ -440,7 +440,7 @@ int main(int argc, char **argv)
 g_free(target_environ);
 
 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
-qemu_log("guest_base  %p\n", (void *)guest_base);
+qemu_log("guest_base  0x%lx\n", guest_base);
 log_page_dump("binary load");
 
 qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
-- 
2.32.0




[PATCH for 6.2 29/49] bsd-user: Add system independent stack, data and text limiting

2021-08-07 Thread Warner Losh
From: Warner Losh 

Eliminate the x86 specific stack stuff in favor of more generic control
over the process size:
target_maxtsiz  max text size
target_dfldsiz  initial data size limit
target_maxdsiz  max data size
target_dflssiz  initial stack size limit
target_maxssiz  max stack size
target_sgrowsiz amount to grow stack
These can be set on a per-arch basis, and the stack size can be set
on the command line. Adjust the stack size parameters at startup.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 

Sponsored by:   Netflix
---
 bsd-user/elfload.c |  2 +-
 bsd-user/main.c| 51 +-
 bsd-user/qemu.h|  7 ++-
 3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 70a0f81f3d..5ceb60b1c2 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -204,7 +204,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct 
bsd_binprm *bprm,
 /* Create enough stack to hold everything.  If we don't use
  * it for args, we'll use it for something else...
  */
-size = x86_stack_size;
+size = target_dflssiz;
 if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE)
 size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
 error = target_mmap(0,
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 91e6abb6e4..5ca1173f04 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -18,6 +18,11 @@
  *  along with this program; if not, see .
  */
 
+#include 
+#include 
+#include 
+#include 
+
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/units.h"
@@ -44,8 +49,6 @@
 #include "host-os.h"
 #include "target_arch_cpu.h"
 
-#include 
-
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -57,12 +60,12 @@ const char *qemu_uname_release;
 enum BSDType bsd_type;
 char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */
 
-/*
- * XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
- * we allocate a bigger stack. Need a better solution, for example
- * by remapping the process stack directly at the right place
- */
-unsigned long x86_stack_size = 512 * 1024;
+unsigned long target_maxtsiz = TARGET_MAXTSIZ;   /* max text size */
+unsigned long target_dfldsiz = TARGET_DFLDSIZ;   /* initial data size limit */
+unsigned long target_maxdsiz = TARGET_MAXDSIZ;   /* max data size */
+unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial data size limit */
+unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
+unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
 void gemu_log(const char *fmt, ...)
 {
@@ -112,7 +115,6 @@ static void usage(void)
"-d item1[,...]enable logging of specified items\n"
"  (use '-d help' for a list of log items)\n"
"-D logfilewrite logs to 'logfile' (default stderr)\n"
-   "-p pagesize   set the host page size to 'pagesize'\n"
"-singlestep   always run in singlestep mode\n"
"-strace   log system calls\n"
"-trace
[[enable=]][,events=][,file=]\n"
@@ -132,7 +134,7 @@ static void usage(void)
,
TARGET_NAME,
interp_prefix,
-   x86_stack_size);
+   target_dflssiz);
 exit(1);
 }
 
@@ -161,6 +163,22 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+static void
+adjust_ssize(void)
+{
+struct rlimit rl;
+
+if (getrlimit(RLIMIT_STACK, ) != 0)
+return;
+
+target_maxssiz = MIN(target_maxssiz, rl.rlim_max);
+target_dflssiz = MIN(MAX(target_dflssiz, rl.rlim_cur), target_maxssiz);
+
+rl.rlim_max = target_maxssiz;
+rl.rlim_cur = target_dflssiz;
+setrlimit(RLIMIT_STACK, );
+}
+
 static void save_proc_pathname(char *argv0)
 {
 int mib[4];
@@ -197,6 +215,8 @@ int main(int argc, char **argv)
 envlist_t *envlist = NULL;
 bsd_type = HOST_DEFAULT_BSD_TYPE;
 
+adjust_ssize();
+
 if (argc <= 1) {
 usage();
 }
@@ -257,14 +277,17 @@ int main(int argc, char **argv)
 }
 } else if (!strcmp(r, "s")) {
 r = argv[optind++];
-rv = qemu_strtoul(r, , 0, _stack_size);
-if (rv < 0 || x86_stack_size <= 0) {
+rv = qemu_strtoul(r, , 0, _dflssiz);
+if (rv < 0 || target_dflssiz <= 0) {
 usage();
 }
 if (*r == 'M') {
-x86_stack_size *= MiB;
+target_dflssiz *= 1024 * 1024;
 } else if (*r == 'k' || *r == 'K') {
-x86_stack_size *= KiB;
+target_dflssiz *= 1024;
+}
+if (target_dflssiz > target_maxssiz) {
+usage();
 }
 } else if (!strcmp(r, "L")) {
 interp_prefix = argv[optind++];
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 

[PATCH for 6.2 33/49] bsd-user: Rewrite target system call definintion glue

2021-08-07 Thread Warner Losh
From: Warner Losh 

Rewrite target definnitions to interface with the FreeBSD system calls.
This covers basic types (time_t, iovec, umtx_time, timespec, timeval,
rusage, rwusage) and basic defines (mmap, rusage). Also included are
FreeBSD version-specific variations.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-mman.h | 121 
 bsd-user/mmap.c |   2 -
 bsd-user/syscall_defs.h | 247 ++--
 3 files changed, 162 insertions(+), 208 deletions(-)
 delete mode 100644 bsd-user/bsd-mman.h

diff --git a/bsd-user/bsd-mman.h b/bsd-user/bsd-mman.h
deleted file mode 100644
index 910e8c1921..00
--- a/bsd-user/bsd-mman.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1993
- *  The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *may be used to endorse or promote products derived from this software
- *without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *  @(#)mman.h  8.2 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/sys/mman.h,v 1.42 2008/03/28 04:29:27 ps Exp $
- */
-
-#define TARGET_FREEBSD_MAP_RESERVED0080 0x0080  /* previously misimplemented 
MAP_INHERIT */
-#define TARGET_FREEBSD_MAP_RESERVED0100 0x0100  /* previously unimplemented 
MAP_NOEXTEND */
-#define TARGET_FREEBSD_MAP_STACK0x0400  /* region grows down, like a 
stack */
-#define TARGET_FREEBSD_MAP_NOSYNC   0x0800  /* page to but do not sync 
underlying file */
-
-#define TARGET_FREEBSD_MAP_FLAGMASK 0x1ff7
-
-/*  $NetBSD: mman.h,v 1.42 2008/11/18 22:13:49 ad Exp $ */
-
-/*-
- * Copyright (c) 1982, 1986, 1993
- *  The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *may be used to endorse or promote products derived from this software
- *without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *  @(#)mman.h  8.2 (Berkeley) 1/9/95
- */
-#define TARGET_NETBSD_MAP_INHERIT   0x0080  /* region is retained after 
exec */
-#define TARGET_NETBSD_MAP_TRYFIXED  0x0400 /* attempt hint address, even 
within break */
-#define TARGET_NETBSD_MAP_WIRED 0x0800  /* mlock() mapping when it is 
established */
-
-#define TARGET_NETBSD_MAP_STACK   

[PATCH for 6.2 42/49] bsd-user: add stubbed out core dump support

2021-08-07 Thread Warner Losh
From: Warner Losh 

Add a stubbed-out version of the bsd-user fork's core dump support. This
allows elfload.c to be almost the same between what's upstream and
what's in qemu-project upstream w/o the burden of reviewing the core
dump support.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 

Sponsored by:   Netflix
---
 bsd-user/elfcore.c | 10 ++
 bsd-user/elfload.c | 24 ++--
 bsd-user/qemu.h|  6 ++
 3 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 bsd-user/elfcore.c

diff --git a/bsd-user/elfcore.c b/bsd-user/elfcore.c
new file mode 100644
index 00..e3c161942d
--- /dev/null
+++ b/bsd-user/elfcore.c
@@ -0,0 +1,10 @@
+/* Stubbed out version of core dump support, explicitly in public domain */
+
+static int elf_core_dump(int signr, CPUArchState *env)
+{
+struct elf_note en;
+
+bswap_note();
+
+return 0;
+}
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index c0787a4e52..4390a88b07 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -26,15 +26,19 @@
 static abi_ulong target_auxents;   /* Where the AUX entries are in target */
 static size_t target_auxents_sz;   /* Size of AUX entries including AT_NULL */
 
+#include "target_arch_reg.h"
 #include "target_os_elf.h"
 #include "target_os_stack.h"
 #include "target_os_thread.h"
-
-#include "elf.h"
+#include "target_os_user.h"
 
 abi_ulong target_stksiz;
 abi_ulong target_stkbas;
 
+static int elf_core_dump(int signr, CPUArchState *env);
+static int load_elf_sections(const struct elfhdr *hdr, struct elf_phdr *phdr,
+int fd, abi_ulong rbase, abi_ulong *baddrp);
+
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
 memcpy(to, from, n);
@@ -100,15 +104,25 @@ static void bswap_sym(struct elf_sym *sym)
 bswap16s(>st_shndx);
 }
 
+static void bswap_note(struct elf_note *en)
+{
+bswap32s(>n_namesz);
+bswap32s(>n_descsz);
+bswap32s(>n_type);
+}
+
 #else /* ! BSWAP_NEEDED */
 
 static void bswap_ehdr(struct elfhdr *ehdr) { }
 static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
 static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
 static void bswap_sym(struct elf_sym *sym) { }
+static void bswap_note(struct elf_note *en) { }
 
 #endif /* ! BSWAP_NEEDED */
 
+#include "elfcore.c"
+
 /*
  * 'copy_elf_strings()' copies argument/envelope strings from user
  * memory to free pages in kernel mem. These are in a format ready
@@ -833,6 +847,12 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 info->entry = elf_entry;
 
+#ifdef USE_ELF_CORE_DUMP
+bprm->core_dump = _core_dump;
+#else
+bprm->core_dump = NULL;
+#endif
+
 return 0;
 }
 
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index a85abb8fe1..b2b7c3b29a 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -54,6 +54,7 @@ extern enum BSDType bsd_type;
  * kernel
  */
 struct image_info {
+abi_ulong load_bias;
 abi_ulong load_addr;
 abi_ulong start_code;
 abi_ulong end_code;
@@ -68,6 +69,9 @@ struct image_info {
 abi_ulong entry;
 abi_ulong code_offset;
 abi_ulong data_offset;
+abi_ulong arg_start;
+abi_ulong arg_end;
+uint32_t  elf_flags;
 };
 
 #define MAX_SIGQUEUE_SIZE 1024
@@ -134,6 +138,7 @@ struct bsd_binprm {
 char **envp;
 char *filename; /* (Given) Name of binary */
 char *fullpath; /* Full path of binary */
+int (*core_dump)(int, CPUArchState *);
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
@@ -147,6 +152,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 struct image_info *info);
 int load_flt_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 struct image_info *info);
+int is_target_elf_binary(int fd);
 
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
   unsigned long len);
-- 
2.32.0




[PATCH for 6.2 35/49] bsd-user: remove error_init

2021-08-07 Thread Warner Losh
From: Warner Losh 

Error reporting isn't used, so gc it until it's used.

Signed-off-by: Warner Losh  
---
 bsd-user/main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index b5527537b4..7e20430fb7 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -34,7 +34,6 @@
 #include "qapi/error.h"
 #include "qemu.h"
 #include "qemu/config-file.h"
-#include "qemu/error-report.h"
 #include "qemu/path.h"
 #include "qemu/help_option.h"
 #include "qemu/module.h"
@@ -223,7 +222,6 @@ int main(int argc, char **argv)
 
 save_proc_pathname(argv[0]);
 
-error_init(argv[0]);
 module_call_init(MODULE_INIT_TRACE);
 qemu_init_cpu_list();
 module_call_init(MODULE_INIT_QOM);
-- 
2.32.0




[PATCH for 6.2 30/49] bsd-user: elf cleanup

2021-08-07 Thread Warner Losh
From: Warner Losh 

Move OS-dependent defines into target_os_elf.h. Move the architectural
dependent stuff into target_arch_elf.h. Adjust elfload.c to use
target_create_elf_tables instead of create_elf_tables.

Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 
Signed-off-by: Kyle Evans 
Signed-off-by: Justin Hibbits 
Signed-off-by: Alexander Kabaev 

Sponsored by:   Netflix
---
 bsd-user/elfload.c   | 190 ---
 bsd-user/freebsd/target_os_elf.h | 149 
 bsd-user/netbsd/target_os_elf.h  | 143 +++
 bsd-user/openbsd/target_os_elf.h | 143 +++
 bsd-user/qemu.h  |   1 +
 5 files changed, 459 insertions(+), 167 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_elf.h
 create mode 100644 bsd-user/netbsd/target_os_elf.h
 create mode 100644 bsd-user/openbsd/target_os_elf.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 5ceb60b1c2..a09f8fb315 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,48 +23,17 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
-#include "target_arch_elf.h"
-#include "target_os_thread.h"
-
-/* this flag is uneffective under linux too, should be deleted */
-#ifndef MAP_DENYWRITE
-#define MAP_DENYWRITE 0
-#endif
-
-/* should probably go in elf.h */
-#ifndef ELIBBAD
-#define ELIBBAD 80
-#endif
-
-#ifndef ELF_PLATFORM
-#define ELF_PLATFORM (NULL)
-#endif
-
-#ifndef ELF_HWCAP
-#define ELF_HWCAP 0
-#endif
+static abi_ulong target_auxents;   /* Where the AUX entries are in target */
+static size_t target_auxents_sz;   /* Size of AUX entries including AT_NULL */
 
-#ifdef TARGET_ABI32
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
-#undef bswaptls
-#define bswaptls(ptr) bswap32s(ptr)
-#endif
+#include "target_os_elf.h"
+#include "target_os_stack.h"
+#include "target_os_thread.h"
 
 #include "elf.h"
 
-/* max code+data+bss space allocated to elf interpreter */
-#define INTERP_MAP_SIZE (32 * 1024 * 1024)
-
-/* max code+data+bss+brk space allocated to ET_DYN executables */
-#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
-
-/* Necessary parameters */
-#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
-#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned 
long)(TARGET_ELF_EXEC_PAGESIZE - 1))
-#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
-
-#define DLINFO_ITEMS 12
+abi_ulong target_stksiz;
+abi_ulong target_stkbas;
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
@@ -195,43 +164,36 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 return p;
 }
 
-static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
- struct image_info *info)
+static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
+abi_ulong *stackp, abi_ulong *stringp)
 {
-abi_ulong stack_base, size, error;
-int i;
+abi_ulong stack_base, size;
+abi_long addr;
 
 /* Create enough stack to hold everything.  If we don't use
  * it for args, we'll use it for something else...
  */
 size = target_dflssiz;
-if (size < MAX_ARG_PAGES * TARGET_PAGE_SIZE)
-size = MAX_ARG_PAGES * TARGET_PAGE_SIZE;
-error = target_mmap(0,
+stack_base = TARGET_USRSTACK - size;
+addr = target_mmap(stack_base,
 size + qemu_host_page_size,
 PROT_READ | PROT_WRITE,
 MAP_PRIVATE | MAP_ANON,
 -1, 0);
-if (error == -1) {
+if (addr == -1) {
 perror("stk mmap");
 exit(-1);
 }
 /* we reserve one extra page at the top of the stack as guard */
-target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
+target_mprotect(addr + size, qemu_host_page_size, PROT_NONE);
 
-stack_base = error + size - MAX_ARG_PAGES * TARGET_PAGE_SIZE;
-p += stack_base;
+target_stksiz = size;
+target_stkbas = addr;
 
-for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-if (bprm->page[i]) {
-info->rss++;
-/* FIXME - check return value of memcpy_to_target() for failure */
-memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
-g_free(bprm->page[i]);
-}
-stack_base += TARGET_PAGE_SIZE;
+if (setup_initial_stack(bprm, stackp, stringp) != 0) {
+perror("stk setup");
+exit(-1);
 }
-return p;
 }
 
 static void set_brk(abi_ulong start, abi_ulong end)
@@ -287,86 +249,6 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 }
 }
 
-
-static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
-   struct elfhdr * exec,
-   abi_ulong load_addr,
-   abi_ulong load_bias,
-   abi_ulong interp_load_addr,
-

[PATCH for 6.2 22/49] bsd-user: Move per-cpu code into target_arch_cpu.h

2021-08-07 Thread Warner Losh
From: Warner Losh 

Move cpu_loop() into target_cpu_loop(), and put that in
target_arch_cpu.h for each architecture.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_cpu.c   |   1 +
 bsd-user/i386/target_arch_cpu.h   | 306 
 bsd-user/main.c   | 309 ++--
 bsd-user/x86_64/target_arch_cpu.c |   1 +
 bsd-user/x86_64/target_arch_cpu.h | 328 ++
 5 files changed, 651 insertions(+), 294 deletions(-)
 create mode 100644 bsd-user/i386/target_arch_cpu.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.h

diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
index 7f2f755a11..71998e5ba5 100644
--- a/bsd-user/i386/target_arch_cpu.c
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -1,6 +1,7 @@
 /*
  *  i386 cpu related code
  *
+ * Copyright (c) 2013 Stacey Son 
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
new file mode 100644
index 00..c7603d4ec6
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -0,0 +1,306 @@
+/*
+ *  i386 cpu init and loop
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "qemu32"
+
+#define TARGET_CPU_RESET(cpu)
+
+static inline void target_cpu_init(CPUX86State *env,
+struct target_pt_regs *regs)
+{
+uint64_t *gdt_table;
+
+env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+env->hflags |= HF_PE_MASK | HF_CPL_MASK;
+if (env->features[FEAT_1_EDX] & CPUID_SSE) {
+env->cr[4] |= CR4_OSFXSR_MASK;
+env->hflags |= HF_OSFXSR_MASK;
+}
+
+/* flags setup : we activate the IRQs by default as in user mode */
+env->eflags |= IF_MASK;
+
+/* register setup */
+env->regs[R_EAX] = regs->eax;
+env->regs[R_EBX] = regs->ebx;
+env->regs[R_ECX] = regs->ecx;
+env->regs[R_EDX] = regs->edx;
+env->regs[R_ESI] = regs->esi;
+env->regs[R_EDI] = regs->edi;
+env->regs[R_EBP] = regs->ebp;
+env->regs[R_ESP] = regs->esp;
+env->eip = regs->eip;
+
+/* interrupt setup */
+env->idt.limit = 255;
+
+env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+bsd_i386_set_idt_base(env->idt.base);
+bsd_i386_set_idt(0, 0);
+bsd_i386_set_idt(1, 0);
+bsd_i386_set_idt(2, 0);
+bsd_i386_set_idt(3, 3);
+bsd_i386_set_idt(4, 3);
+bsd_i386_set_idt(5, 0);
+bsd_i386_set_idt(6, 0);
+bsd_i386_set_idt(7, 0);
+bsd_i386_set_idt(8, 0);
+bsd_i386_set_idt(9, 0);
+bsd_i386_set_idt(10, 0);
+bsd_i386_set_idt(11, 0);
+bsd_i386_set_idt(12, 0);
+bsd_i386_set_idt(13, 0);
+bsd_i386_set_idt(14, 0);
+bsd_i386_set_idt(15, 0);
+bsd_i386_set_idt(16, 0);
+bsd_i386_set_idt(17, 0);
+bsd_i386_set_idt(18, 0);
+bsd_i386_set_idt(19, 0);
+bsd_i386_set_idt(0x80, 3);
+
+/* segment setup */
+env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
+gdt_table = g2h_untagged(env->gdt.base);
+
+bsd_i386_write_dt(_table[__USER_CS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
+
+bsd_i386_write_dt(_table[__USER_DS >> 3], 0, 0xf,
+DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+(3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
+
+cpu_x86_load_seg(env, R_CS, __USER_CS);
+cpu_x86_load_seg(env, R_SS, __USER_DS);
+cpu_x86_load_seg(env, R_DS, __USER_DS);
+cpu_x86_load_seg(env, R_ES, __USER_DS);
+cpu_x86_load_seg(env, R_FS, __USER_DS);
+cpu_x86_load_seg(env, R_GS, __USER_DS);
+/* This hack makes Wine work... */
+env->segs[R_FS].selector = 0;
+}
+
+static inline void target_cpu_loop(CPUX86State *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr;
+abi_ulong pc;
+/* target_siginfo_t info; */

[PATCH for 6.2 23/49] bsd-user: pull in target_arch_thread.h update target_arch_elf.h

2021-08-07 Thread Warner Losh
From: Warner Losh 

Update target_arch_elf.h to remove thread_init. Move its contents to
target_arch_thread.h and rename to target_thread_init(). Update
elfload.c to call it. Create thread_os_thread.h to hold the os specific
parts of the thread and threat manipulation routines. Currently, it just
includes target_arch_thread.h. target_arch_thread.h contains the at the
moment unused target_thread_set_upcall which will be used in the future
when creating actual thread (i386 has this stubbed, but other
architectures in the bsd-user tree have real ones).

These changes are all interrelated and could be brokend own, but seem to
represent a reviewable changeset since most of the change is boiler
plate.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c   |  4 ++-
 bsd-user/freebsd/target_os_thread.h  | 25 +
 bsd-user/i386/target_arch_elf.h  | 52 ++--
 bsd-user/i386/target_arch_thread.h   | 47 +
 bsd-user/netbsd/target_os_thread.h   | 25 +
 bsd-user/openbsd/target_os_thread.h  | 25 +
 bsd-user/x86_64/target_arch_elf.h| 38 ++--
 bsd-user/x86_64/target_arch_thread.h | 40 +
 8 files changed, 169 insertions(+), 87 deletions(-)
 create mode 100644 bsd-user/freebsd/target_os_thread.h
 create mode 100644 bsd-user/i386/target_arch_thread.h
 create mode 100644 bsd-user/netbsd/target_os_thread.h
 create mode 100644 bsd-user/openbsd/target_os_thread.h
 create mode 100644 bsd-user/x86_64/target_arch_thread.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 8a6a72bf05..70a0f81f3d 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -24,6 +24,7 @@
 #include "qemu/path.h"
 
 #include "target_arch_elf.h"
+#include "target_os_thread.h"
 
 /* this flag is uneffective under linux too, should be deleted */
 #ifndef MAP_DENYWRITE
@@ -1001,5 +1002,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
 {
-init_thread(regs, infop);
+
+target_thread_init(regs, infop);
 }
diff --git a/bsd-user/freebsd/target_os_thread.h 
b/bsd-user/freebsd/target_os_thread.h
new file mode 100644
index 00..77433acdff
--- /dev/null
+++ b/bsd-user/freebsd/target_os_thread.h
@@ -0,0 +1,25 @@
+/*
+ *  FreeBSD thread dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_THREAD_H_
+#define _TARGET_OS_THREAD_H_
+
+#include "target_arch_thread.h"
+
+#endif /* !_TARGET_OS_THREAD_H_ */
diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
index f322fc174b..7a9744140f 100644
--- a/bsd-user/i386/target_arch_elf.h
+++ b/bsd-user/i386/target_arch_elf.h
@@ -19,62 +19,14 @@
 #ifndef _TARGET_ARCH_ELF_H_
 #define _TARGET_ARCH_ELF_H_
 
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
-static char elf_platform[] = "i386";
-int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6) {
-family = 6;
-}
-if (family >= 3) {
-elf_platform[1] = '0' + family;
-}
-return elf_platform;
-}
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
-X86CPU *cpu = X86_CPU(thread_cpu);
-
-return cpu->env.features[FEAT_1_EDX];
-}
-
 #define ELF_START_MMAP 0x8000
+#define ELF_ET_DYN_LOAD_ADDR0x01001000
+#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
 
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
-
-/*
- * These are used to set parameters in the core dumps.
- */
 #define ELF_CLASS   ELFCLASS32
 #define ELF_DATAELFDATA2LSB
 #define ELF_ARCHEM_386
 
-static inline void init_thread(struct target_pt_regs *regs,
-   struct image_info *infop)
-{
-regs->esp = infop->start_stack;
-regs->eip = infop->entry;
-
-/*
- * SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
- * contains a pointer to a function which might be registered using
- * `atexit'.  This provides a mean for the dynamic linker to call 

[PATCH for 6.2 27/49] bsd-user: Add architecture specific signal tramp code

2021-08-07 Thread Warner Losh
From: Warner Losh 

Add a stubbed out version of setup_sigtramp. This is not yet used for
x86, but is used for other architectures. This will be connected in
future commits.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_sigtramp.h   | 29 ++
 bsd-user/x86_64/target_arch_sigtramp.h | 29 ++
 2 files changed, 58 insertions(+)
 create mode 100644 bsd-user/i386/target_arch_sigtramp.h
 create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h

diff --git a/bsd-user/i386/target_arch_sigtramp.h 
b/bsd-user/i386/target_arch_sigtramp.h
new file mode 100644
index 00..889bff7a54
--- /dev/null
+++ b/bsd-user/i386/target_arch_sigtramp.h
@@ -0,0 +1,29 @@
+/*
+ * Intel i386  sigcode for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+unsigned sys_sigreturn)
+{
+
+return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/x86_64/target_arch_sigtramp.h 
b/bsd-user/x86_64/target_arch_sigtramp.h
new file mode 100644
index 00..5629263a19
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_sigtramp.h
@@ -0,0 +1,29 @@
+/*
+ * Intel x86_64  sigcode for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+unsigned sys_sigreturn)
+{
+
+return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
-- 
2.32.0




[PATCH for 6.2 47/49] bsd-user: Implement interlock for atomic operations

2021-08-07 Thread Warner Losh
From: Warner Losh 

Implement the internlock in fork_start() and fork_end() to properly cope
with atomic operations and to safely keep state for parent and child
processes.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 7ba616a995..2b0716d245 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -85,15 +85,38 @@ unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial 
data size limit */
 unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
 unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
+/* Helper routines for implementing atomic operations. */
 
 void fork_start(void)
 {
+start_exclusive();
+cpu_list_lock();
+mmap_fork_start();
 }
 
 void fork_end(int child)
 {
 if (child) {
+CPUState *cpu, *next_cpu;
+/*
+ * Child processes created by fork() only have a single thread.
+ * Discard information about the parent threads.
+ */
+CPU_FOREACH_SAFE(cpu, next_cpu) {
+if (cpu != thread_cpu) {
+QTAILQ_REMOVE_RCU(, cpu, node);
+}
+}
+mmap_fork_end(child);
+/* qemu_init_cpu_list() takes care of reinitializing the
+ * exclusive state, so we don't need to end_exclusive() here.
+ */
+   qemu_init_cpu_list();
 gdbserver_fork(thread_cpu);
+} else {
+mmap_fork_end(child);
+   cpu_list_unlock();
+end_exclusive();
 }
 }
 
-- 
2.32.0




[PATCH for 6.2 28/49] bsd-user: Move stack initializtion into a per-os file.

2021-08-07 Thread Warner Losh
From: Warner Losh 

Move all of the stack initialization into target_os_stack.h. Each BSD
sets up processes a little differently.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/target_os_stack.h | 181 +
 bsd-user/netbsd/target_os_stack.h  |  56 +
 bsd-user/openbsd/target_os_stack.h |  56 +
 3 files changed, 293 insertions(+)
 create mode 100644 bsd-user/freebsd/target_os_stack.h
 create mode 100644 bsd-user/netbsd/target_os_stack.h
 create mode 100644 bsd-user/openbsd/target_os_stack.h

diff --git a/bsd-user/freebsd/target_os_stack.h 
b/bsd-user/freebsd/target_os_stack.h
new file mode 100644
index 00..410b2828ca
--- /dev/null
+++ b/bsd-user/freebsd/target_os_stack.h
@@ -0,0 +1,181 @@
+/*
+ *  FreeBSD setup_initial_stack() implementation.
+ *
+ *  Copyright (c) 2013-14 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_OS_STACK_H_
+#define _TARGET_OS_STACK_H_
+
+#include 
+#include "target_arch_sigtramp.h"
+
+/*
+ * The inital FreeBSD stack is as follows:
+ * (see kern/kern_exec.c exec_copyout_strings() )
+ *
+ *  Hi Address -> char **ps_argvstr  (struct ps_strings for ps, w, etc.)
+ *unsigned ps_nargvstr
+ *char **ps_envstr
+ *  PS_STRINGS -> unsigned ps_nenvstr
+ *
+ *machine dependent sigcode (sv_sigcode of size
+ *   sv_szsigcode)
+ *
+ *execpath  (absolute image path for rtld)
+ *
+ *SSP Canary(sizeof(long) * 8)
+ *
+ *page sizes array  (usually sizeof(u_long) )
+ *
+ *  "destp" ->argv, env strings (up to 262144 bytes)
+ */
+static inline int setup_initial_stack(struct bsd_binprm *bprm,
+abi_ulong *ret_addr, abi_ulong *stringp)
+{
+int i;
+abi_ulong stack_hi_addr;
+size_t execpath_len, stringspace;
+abi_ulong destp, argvp, envp, p;
+struct target_ps_strings ps_strs;
+char canary[sizeof(abi_long) * 8];
+
+stack_hi_addr = p = target_stkbas + target_stksiz;
+
+/* Save some space for ps_strings. */
+p -= sizeof(struct target_ps_strings);
+
+#ifdef TARGET_SZSIGCODE
+/* Add machine depedent sigcode. */
+p -= TARGET_SZSIGCODE;
+if (setup_sigtramp(p, (unsigned)offsetof(struct target_sigframe, sf_uc),
+TARGET_FREEBSD_NR_sigreturn)) {
+errno = EFAULT;
+return -1;
+}
+#endif
+if (bprm->fullpath) {
+execpath_len = strlen(bprm->fullpath) + 1;
+p -= roundup(execpath_len, sizeof(abi_ulong));
+if (memcpy_to_target(p, bprm->fullpath, execpath_len)) {
+errno = EFAULT;
+return -1;
+}
+}
+/* Add canary for SSP. */
+arc4random_buf(canary, sizeof(canary));
+p -= roundup(sizeof(canary), sizeof(abi_ulong));
+if (memcpy_to_target(p, canary, sizeof(canary))) {
+errno = EFAULT;
+return -1;
+}
+/* Add page sizes array. */
+p -= sizeof(abi_ulong);
+if (put_user_ual(TARGET_PAGE_SIZE, p)) {
+errno = EFAULT;
+return -1;
+}
+/*
+ * Deviate from FreeBSD stack layout: force stack to new page here
+ * so that signal trampoline is not sharing the page with user stack
+ * frames. This is actively harmful in qemu as it marks pages with
+ * code it translated as read-only, which is somewhat problematic
+ * for user trying to use the stack as intended.
+ */
+p = rounddown(p, TARGET_PAGE_SIZE);
+
+/* Calculate the string space needed */
+stringspace = 0;
+for (i = 0; i < bprm->argc; ++i) {
+stringspace += strlen(bprm->argv[i]) + 1;
+}
+for (i = 0; i < bprm->envc; ++i) {
+stringspace += strlen(bprm->envp[i]) + 1;
+}
+if (stringspace > TARGET_ARG_MAX) {
+   errno = ENOMEM;
+   return -1;
+}
+/* Make room for the argv and envp strings */
+destp = rounddown(p - stringspace, sizeof(abi_ulong));
+p = argvp = destp - (bprm->argc + bprm->envc + 2) * sizeof(abi_ulong);
+/* Remember the strings pointer */
+if (stringp)
+*stringp = destp;
+/*
+ * Add argv strings.  Note that the argv[] vectors are added by
+ * loader_build_argptr()
+ */
+/* XXX need to make room for auxargs */
+ps_strs.ps_argvstr = tswapl(argvp);
+

[PATCH for 6.2 26/49] bsd-user: Create target specific vmparam.h

2021-08-07 Thread Warner Losh
From: Warner Losh 

Target specific values for vm parameters and details.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/target_os_vmparam.h  | 38 ++
 bsd-user/i386/target_arch_vmparam.h   | 46 +++
 bsd-user/qemu.h   |  2 +-
 bsd-user/x86_64/target_arch_vmparam.h | 46 +++
 4 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 bsd-user/freebsd/target_os_vmparam.h
 create mode 100644 bsd-user/i386/target_arch_vmparam.h
 create mode 100644 bsd-user/x86_64/target_arch_vmparam.h

diff --git a/bsd-user/freebsd/target_os_vmparam.h 
b/bsd-user/freebsd/target_os_vmparam.h
new file mode 100644
index 00..d7ad149137
--- /dev/null
+++ b/bsd-user/freebsd/target_os_vmparam.h
@@ -0,0 +1,38 @@
+/*
+ *  FreeBSD VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_OS_VMPARAM_H_
+#define _TARGET_OS_VMPARAM_H_
+
+#include "target_arch_vmparam.h"
+
+/* Compare to sys/exec.h */
+struct target_ps_strings {
+abi_ulong ps_argvstr;
+uint32_t ps_nargvstr;
+abi_ulong ps_envstr;
+uint32_t ps_nenvstr;
+};
+
+extern abi_ulong target_stkbas;
+extern abi_ulong target_stksiz;
+
+#define TARGET_PS_STRINGS  ((target_stkbas + target_stksiz) - \
+   sizeof(struct target_ps_strings))
+
+#endif /* !TARGET_OS_VMPARAM_H_ */
diff --git a/bsd-user/i386/target_arch_vmparam.h 
b/bsd-user/i386/target_arch_vmparam.h
new file mode 100644
index 00..c42ec87d54
--- /dev/null
+++ b/bsd-user/i386/target_arch_vmparam.h
@@ -0,0 +1,46 @@
+/*
+ *  i386 VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to i386/include/vmparam.h */
+#define TARGET_MAXTSIZ  (128UL*1024*1024)   /* max text size */
+#define TARGET_DFLDSIZ  (128UL*1024*1024)   /* initial data size limit */
+#define TARGET_MAXDSIZ  (512UL*1024*1024)   /* max data size */
+#define TARGET_DFLSSIZ  (8UL*1024*1024) /* initial stack size limit */
+#define TARGET_MAXSSIZ  (64UL*1024*1024)/* max stack size */
+#define TARGET_SGROWSIZ (128UL*1024)/* amount to grow stack */
+
+#define TARGET_RESERVED_VA 0xf700
+
+#define TARGET_USRSTACK (0xbfc0)
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+return state->regs[R_ESP];
+}
+
+static inline void set_second_rval(CPUX86State *state, abi_ulong retval2)
+{
+state->regs[R_EDX] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 9322187891..c5414c7b4c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -44,7 +44,7 @@ extern enum BSDType bsd_type;
 #include "target_arch.h"
 #include "syscall_defs.h"
 #include "target_syscall.h"
-//#include "target_os_vmparam.h"
+#include "target_os_vmparam.h"
 //#include "target_os_signal.h"
 //#include "hostdep.h"
 #include "exec/gdbstub.h"
diff --git a/bsd-user/x86_64/target_arch_vmparam.h 
b/bsd-user/x86_64/target_arch_vmparam.h
new file mode 100644
index 00..addb68fa94
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_vmparam.h
@@ -0,0 +1,46 @@
+/*
+ *  Intel x86_64 VM parameters definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  

[PATCH for 6.2 21/49] bsd-user: start to move target CPU functions to target_arch*

2021-08-07 Thread Warner Losh
From: Warner Losh 

Move the CPU functons into target_arch_cpu.c that are unique to each
CPU. These are defined in target_arch.h.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch.h   | 31 +
 bsd-user/i386/target_arch_cpu.c   | 75 +++
 bsd-user/main.c   | 12 -
 bsd-user/x86_64/target_arch.h | 31 +
 bsd-user/x86_64/target_arch_cpu.c | 75 +++
 meson.build   |  8 +++-
 6 files changed, 218 insertions(+), 14 deletions(-)
 create mode 100644 bsd-user/i386/target_arch.h
 create mode 100644 bsd-user/i386/target_arch_cpu.c
 create mode 100644 bsd-user/x86_64/target_arch.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.c

diff --git a/bsd-user/i386/target_arch.h b/bsd-user/i386/target_arch.h
new file mode 100644
index 00..73e9a028fe
--- /dev/null
+++ b/bsd-user/i386/target_arch.h
@@ -0,0 +1,31 @@
+/*
+ * Intel x86 specific prototypes for bsd-user
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+/* target_arch_cpu.c */
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+int flags);
+void bsd_i386_set_idt(int n, unsigned int dpl);
+void bsd_i386_set_idt_base(uint64_t base);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* ! _TARGET_ARCH_H_ */
diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
new file mode 100644
index 00..7f2f755a11
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -0,0 +1,75 @@
+/*
+ *  i386 cpu related code
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#include 
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu.h"
+#include "qemu/timer.h"
+
+#include "target_arch.h"
+
+static uint64_t *idt_table;
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+return cpu_get_host_ticks();
+}
+
+int cpu_get_pic_interrupt(CPUX86State *env)
+{
+return -1;
+}
+
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+ int flags)
+{
+unsigned int e1, e2;
+uint32_t *p;
+e1 = (addr << 16) | (limit & 0x);
+e2 = ((addr >> 16) & 0xff) | (addr & 0xff00) | (limit & 0x000f);
+e2 |= flags;
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+ uint32_t addr, unsigned int sel)
+{
+uint32_t *p, e1, e2;
+e1 = (addr & 0x) | (sel << 16);
+e2 = (addr & 0x) | 0x8000 | (dpl << 13) | (type << 8);
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+/* only dpl matters as we do only user space emulation */
+void bsd_i386_set_idt(int n, unsigned int dpl)
+{
+set_gate(idt_table + n, 0, dpl, 0, 0);
+}
+
+void bsd_i386_set_idt_base(uint64_t base)
+{
+idt_table = g2h_untagged(base);
+}
+
diff --git a/bsd-user/main.c b/bsd-user/main.c
index c59edad155..ac435b216a 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -72,13 +72,6 @@ void gemu_log(const char *fmt, ...)
 va_end(ap);
 }
 
-#if defined(TARGET_I386)
-int cpu_get_pic_interrupt(CPUX86State *env)
-{
-return -1;
-}
-#endif
-
 void fork_start(void)
 {
 }
@@ -94,11 +87,6 @@ void fork_end(int child)
 /***/
 /* CPUX86 core interface */
 
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
-return cpu_get_host_ticks();
-}
-
 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
  int flags)
 {
diff --git a/bsd-user/x86_64/target_arch.h 

[PATCH for 6.2 24/49] bsd-user: Include more things in qemu.h

2021-08-07 Thread Warner Losh
From: Warner Losh 

Include more header files to match bsd-user fork.

Signed-off-by: Warner Losh 
---
 bsd-user/qemu.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 6c4ec61d76..02e6e8327a 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -18,11 +18,15 @@
 #define QEMU_H
 
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
+//#include "trace/trace-bsd_user.h"
 
 #undef DEBUG_REMAP
 #ifdef DEBUG_REMAP
+#include 
 #endif /* DEBUG_REMAP */
 
 #include "exec/user/abitypes.h"
@@ -36,8 +40,13 @@ enum BSDType {
 };
 extern enum BSDType bsd_type;
 
+#include "exec/user/thunk.h"
+#include "target_arch.h"
 #include "syscall_defs.h"
 #include "target_syscall.h"
+//#include "target_os_vmparam.h"
+//#include "target_os_signal.h"
+//#include "hostdep.h"
 #include "exec/gdbstub.h"
 
 /*
-- 
2.32.0




[PATCH for 6.2 43/49] bsd-user: elfload.c style catch up patch

2021-08-07 Thread Warner Losh
From: Warner Losh 

Various style fixes to elfload.c that were too painful to make earlier
in this series.

Signed-off-by: Warner Losh 

Sponsored by:   Netflix
---
 bsd-user/elfload.c | 212 ++---
 1 file changed, 105 insertions(+), 107 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 4390a88b07..bdf18f3dce 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -36,8 +36,6 @@ abi_ulong target_stksiz;
 abi_ulong target_stkbas;
 
 static int elf_core_dump(int signr, CPUArchState *env);
-static int load_elf_sections(const struct elfhdr *hdr, struct elf_phdr *phdr,
-int fd, abi_ulong rbase, abi_ulong *baddrp);
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
@@ -145,10 +143,12 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 exit(-1);
 }
 tmp1 = tmp;
-while (*tmp++);
+while (*tmp++) {
+continue;
+}
 len = tmp - tmp1;
 if (p < len) {  /* this shouldn't happen - 128kB */
-return 0;
+return 0;
 }
 while (len) {
 --p; --tmp; --len;
@@ -158,14 +158,14 @@ static abi_ulong copy_elf_strings(int argc, char **argv, 
void **page,
 if (!pag) {
 pag = g_try_malloc0(TARGET_PAGE_SIZE);
 page[p / TARGET_PAGE_SIZE] = pag;
-if (!pag)
+if (!pag) {
 return 0;
+}
 }
 }
 if (len == 0 || offset == 0) {
 *(pag + offset) = *tmp;
-}
-else {
+} else {
   int bytes_to_copy = (len > offset) ? offset : len;
   tmp -= bytes_to_copy;
   p -= bytes_to_copy;
@@ -184,16 +184,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, 
struct image_info *info,
 abi_ulong stack_base, size;
 abi_long addr;
 
-/* Create enough stack to hold everything.  If we don't use
- * it for args, we'll use it for something else...
+/*
+ * Create enough stack to hold everything.  If we don't use it for args,
+ * we'll use it for something else...
  */
 size = target_dflssiz;
 stack_base = TARGET_USRSTACK - size;
-addr = target_mmap(stack_base,
-size + qemu_host_page_size,
-PROT_READ | PROT_WRITE,
-MAP_PRIVATE | MAP_ANON,
--1, 0);
+addr = target_mmap(stack_base , size + qemu_host_page_size,
+PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 if (addr == -1) {
 perror("stk mmap");
 exit(-1);
@@ -212,55 +210,60 @@ static void setup_arg_pages(struct bsd_binprm *bprm, 
struct image_info *info,
 
 static void set_brk(abi_ulong start, abi_ulong end)
 {
-/* page-align the start and end addresses... */
-start = HOST_PAGE_ALIGN(start);
-end = HOST_PAGE_ALIGN(end);
-if (end <= start)
-return;
-if (target_mmap(start, end - start,
-   PROT_READ | PROT_WRITE | PROT_EXEC,
-   MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
-perror("cannot mmap brk");
-exit(-1);
-}
+/* page-align the start and end addresses... */
+start = HOST_PAGE_ALIGN(start);
+end = HOST_PAGE_ALIGN(end);
+if (end <= start) {
+return;
+}
+if (target_mmap(start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC,
+MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
+perror("cannot mmap brk");
+exit(-1);
+}
 }
 
 
-/* We need to explicitly zero any fractional pages after the data
-   section (i.e. bss).  This would contain the junk from the file that
-   should not be in memory. */
+/*
+ * We need to explicitly zero any fractional pages after the data
+ * section (i.e. bss).  This would contain the junk from the file that
+ * should not be in memory.
+ */
 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 {
-abi_ulong nbyte;
+abi_ulong nbyte;
 
-if (elf_bss >= last_bss)
-return;
+if (elf_bss >= last_bss) {
+return;
+}
 
-/* XXX: this is really a hack : if the real host page size is
-   smaller than the target page size, some pages after the end
-   of the file may not be mapped. A better fix would be to
-   patch target_mmap(), but it is more complicated as the file
-   size must be known */
-if (qemu_real_host_page_size < qemu_host_page_size) {
-abi_ulong end_addr, end_addr1;
-end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
-end_addr = HOST_PAGE_ALIGN(elf_bss);
-if (end_addr1 < end_addr) {
-mmap((void *)g2h_untagged(end_addr1), end_addr - 

[PATCH for 6.2 20/49] bsd-user: save the path the qemu emulator

2021-08-07 Thread Warner Losh
Save the path to the qemu emulator. This will be used later when we have
a more complete implementation of exec.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/main.c | 21 +
 bsd-user/qemu.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index d9965e6611..c59edad155 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -43,6 +43,8 @@
 
 #include "host-os.h"
 
+#include 
+
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -52,6 +54,7 @@ unsigned long reserved_va;
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
 enum BSDType bsd_type;
+char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */
 
 /*
  * XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
@@ -336,6 +339,22 @@ void init_task_state(TaskState *ts)
 ts->sigqueue_table[i].next = NULL;
 }
 
+static void save_proc_pathname(char *argv0)
+{
+int mib[4];
+size_t len;
+
+mib[0] = CTL_KERN;
+mib[1] = KERN_PROC;
+mib[2] = KERN_PROC_PATHNAME;
+mib[3] = -1;
+
+len = PATH_MAX;
+if (sysctl(mib, 4, qemu_proc_pathname, , NULL, 0)) {
+perror("sysctl");
+}
+}
+
 int main(int argc, char **argv)
 {
 const char *filename;
@@ -360,6 +379,8 @@ int main(int argc, char **argv)
 usage();
 }
 
+save_proc_pathname(argv[0]);
+
 error_init(argv[0]);
 module_call_init(MODULE_INIT_TRACE);
 qemu_init_cpu_list();
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index cf248ad3df..6c4ec61d76 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -207,6 +207,7 @@ void mmap_fork_start(void);
 void mmap_fork_end(int child);
 
 /* main.c */
+extern char qemu_proc_pathname[];
 extern unsigned long x86_stack_size;
 
 /* user access */
-- 
2.32.0




[PATCH for 6.2 25/49] bsd-user: define max args in terms of pages

2021-08-07 Thread Warner Losh
From: Warner Losh 

For 32-bit platforms, pass in up to 256k of args. For 64-bit, bump that
to 512k.

Signed-off-by: Kyle Evans 
Signed-off-by: Warner Losh 
---
 bsd-user/qemu.h | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 02e6e8327a..9322187891 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -107,11 +107,17 @@ extern const char *qemu_uname_release;
 extern unsigned long mmap_min_addr;
 
 /*
- * MAX_ARG_PAGES defines the number of pages allocated for arguments
- * and envelope for the new program. 32 should suffice, this gives
- * a maximum env+arg of 128kB w/4KB pages!
+ * TARGET_ARG_MAX defines the number of bytes allocated for arguments
+ * and envelope for the new program. 256k should suffice for a reasonable
+ * maxiumum env+arg in 32-bit environments, bump it up to 512k for !ILP32
+ * platforms.
  */
-#define MAX_ARG_PAGES 32
+#if TARGET_ABI_BITS > 32
+#define TARGET_ARG_MAX (512 * 1024)
+#else
+#define TARGET_ARG_MAX (256 * 1024)
+#endif
+#define MAX_ARG_PAGES (TARGET_ARG_MAX / TARGET_PAGE_SIZE)
 
 /*
  * This structure is used to hold the arguments that are
-- 
2.32.0




[PATCH for 6.2 19/49] bsd-user: Include host-os.h from main

2021-08-07 Thread Warner Losh
Include host-os.h from main.c to pick up the default OS to emulate.  Set
that default in main().

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/host-os.h | 2 ++
 bsd-user/main.c| 4 +++-
 bsd-user/netbsd/host-os.h  | 2 ++
 bsd-user/openbsd/host-os.h | 2 ++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/bsd-user/freebsd/host-os.h b/bsd-user/freebsd/host-os.h
index a799164324..ceb1543d06 100644
--- a/bsd-user/freebsd/host-os.h
+++ b/bsd-user/freebsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef __HOST_OS_H_
 #define __HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_freebsd
+
 #endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 9166049c5a..d9965e6611 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -41,6 +41,8 @@
 #include "exec/log.h"
 #include "trace/control.h"
 
+#include "host-os.h"
+
 int singlestep;
 unsigned long mmap_min_addr;
 uintptr_t guest_base;
@@ -352,7 +354,7 @@ int main(int argc, char **argv)
 const char *gdbstub = NULL;
 char **target_environ, **wrk;
 envlist_t *envlist = NULL;
-bsd_type = target_openbsd;
+bsd_type = HOST_DEFAULT_BSD_TYPE;
 
 if (argc <= 1) {
 usage();
diff --git a/bsd-user/netbsd/host-os.h b/bsd-user/netbsd/host-os.h
index b44cb7fdda..ccbea076e6 100644
--- a/bsd-user/netbsd/host-os.h
+++ b/bsd-user/netbsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef __HOST_OS_H_
 #define __HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_netbsd
+
 #endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/openbsd/host-os.h b/bsd-user/openbsd/host-os.h
index 9083555f26..79468073e4 100644
--- a/bsd-user/openbsd/host-os.h
+++ b/bsd-user/openbsd/host-os.h
@@ -20,4 +20,6 @@
 #ifndef __HOST_OS_H_
 #define __HOST_OS_H_
 
+#define HOST_DEFAULT_BSD_TYPE target_openbsd
+
 #endif /*!__HOST_OS_H_ */
-- 
2.32.0




[PATCH for 6.2 40/49] bsd-user: Add target_arch_reg to describe a target's register set

2021-08-07 Thread Warner Losh
From: Warner Losh 

target_reg_t is the normal register. target_fpreg_t is the floating
point registers. target_copy_regs copies the registers out of CPU
context for things like core dumps.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_reg.h   | 82 +++
 bsd-user/x86_64/target_arch_reg.h | 92 +++
 2 files changed, 174 insertions(+)
 create mode 100644 bsd-user/i386/target_arch_reg.h
 create mode 100644 bsd-user/x86_64/target_arch_reg.h

diff --git a/bsd-user/i386/target_arch_reg.h b/bsd-user/i386/target_arch_reg.h
new file mode 100644
index 00..1fce1daf01
--- /dev/null
+++ b/bsd-user/i386/target_arch_reg.h
@@ -0,0 +1,82 @@
+/*
+ *  FreeBSD i386 register structures
+ *
+ *  Copyright (c) 2015 Stacey Son
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_REG_H_
+#define _TARGET_ARCH_REG_H_
+
+/* See sys/i386/include/reg.h */
+typedef struct target_reg {
+uint32_tr_fs;
+uint32_tr_es;
+uint32_tr_ds;
+uint32_tr_edi;
+uint32_tr_esi;
+uint32_tr_ebp;
+uint32_tr_isp;
+uint32_tr_ebx;
+uint32_tr_edx;
+uint32_tr_ecx;
+uint32_tr_eax;
+uint32_tr_trapno;
+uint32_tr_err;
+uint32_tr_eip;
+uint32_tr_cs;
+uint32_tr_eflags;
+uint32_tr_esp;
+uint32_tr_ss;
+uint32_tr_gs;
+} target_reg_t;
+
+typedef struct target_fpreg {
+uint32_tfpr_env[7];
+uint8_t fpr_acc[8][10];
+uint32_tfpr_ex_sw;
+uint8_t fpr_pad[64];
+} target_fpreg_t;
+
+static inline void target_copy_regs(target_reg_t *regs, const CPUX86State *env)
+{
+
+regs->r_fs = env->segs[R_FS].selector & 0x;
+regs->r_es = env->segs[R_ES].selector & 0x;
+regs->r_ds = env->segs[R_DS].selector & 0x;
+
+regs->r_edi = env->regs[R_EDI];
+regs->r_esi = env->regs[R_ESI];
+regs->r_ebp = env->regs[R_EBP];
+/* regs->r_isp = env->regs[R_ISP]; XXX */
+regs->r_ebx = env->regs[R_EBX];
+regs->r_edx = env->regs[R_EDX];
+regs->r_ecx = env->regs[R_ECX];
+regs->r_eax = env->regs[R_EAX];
+/* regs->r_trapno = env->regs[R_TRAPNO]; XXX */
+regs->r_err = env->error_code;  /* XXX ? */
+regs->r_eip = env->eip;
+
+regs->r_cs = env->segs[R_CS].selector & 0x;
+
+regs->r_eflags = env->eflags;
+regs->r_esp = env->regs[R_ESP];
+
+regs->r_ss = env->segs[R_SS].selector & 0x;
+regs->r_gs = env->segs[R_GS].selector & 0x;
+}
+
+#endif /* !_TARGET_ARCH_REG_H_ */
diff --git a/bsd-user/x86_64/target_arch_reg.h 
b/bsd-user/x86_64/target_arch_reg.h
new file mode 100644
index 00..00e9624517
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_reg.h
@@ -0,0 +1,92 @@
+/*
+ *  FreeBSD amd64 register structures
+ *
+ *  Copyright (c) 2015 Stacey Son
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef _TARGET_ARCH_REG_H_
+#define _TARGET_ARCH_REG_H_
+
+/* See sys/amd64/include/reg.h */
+typedef struct target_reg {
+uint64_tr_r15;
+uint64_tr_r14;
+uint64_tr_r13;
+uint64_tr_r12;
+uint64_tr_r11;
+uint64_tr_r10;
+uint64_tr_r9;
+uint64_tr_r8;
+uint64_tr_rdi;
+uint64_tr_rsi;
+uint64_tr_rbp;
+uint64_tr_rbx;
+uint64_tr_rdx;
+uint64_tr_rcx;
+uint64_tr_rax;
+uint32_tr_trapno;
+uint16_tr_fs;
+uint16_tr_gs;
+uint32_tr_err;
+uint16_t 

[PATCH for 6.2 17/49] bsd-user: assume pthreads and support of __thread

2021-08-07 Thread Warner Losh
All compilers for some time have supported this. Follow linux-user and
eliminate the #define THREAD and unconditionally insert __thread where
needed.

Signed-off-by: Warner Losh 
---
 bsd-user/main.c |  2 +-
 bsd-user/qemu.h | 10 +-
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 65958729f1..9166049c5a 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -309,7 +309,7 @@ static void usage(void)
 exit(1);
 }
 
-THREAD CPUState *thread_cpu;
+__thread CPUState *thread_cpu;
 
 bool qemu_cpu_is_self(CPUState *cpu)
 {
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index d1ab58a8eb..cf248ad3df 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -40,12 +40,6 @@ extern enum BSDType bsd_type;
 #include "target_syscall.h"
 #include "exec/gdbstub.h"
 
-#if defined(CONFIG_USE_NPTL)
-#define THREAD __thread
-#else
-#define THREAD
-#endif
-
 /*
  * This struct is used to hold certain information about the image.  Basically,
  * it replicates in user space what would be certain task_struct fields in the
@@ -155,7 +149,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 abi_long arg2, abi_long arg3, abi_long arg4,
 abi_long arg5, abi_long arg6);
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-extern THREAD CPUState *thread_cpu;
+extern __thread CPUState *thread_cpu;
 void cpu_loop(CPUArchState *env);
 char *target_strerror(int err);
 int get_osversion(void);
@@ -422,8 +416,6 @@ static inline void *lock_user_string(abi_ulong guest_addr)
 #define unlock_user_struct(host_ptr, guest_addr, copy)  \
 unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
 
-#if defined(CONFIG_USE_NPTL)
 #include 
-#endif
 
 #endif /* QEMU_H */
-- 
2.32.0




[PATCH for 6.2 18/49] bsd-user: add host-os.h

2021-08-07 Thread Warner Losh
Host OS specific bits for this implementation go in this file.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/freebsd/host-os.h | 23 +++
 bsd-user/netbsd/host-os.h  | 23 +++
 bsd-user/openbsd/host-os.h | 23 +++
 3 files changed, 69 insertions(+)
 create mode 100644 bsd-user/freebsd/host-os.h
 create mode 100644 bsd-user/netbsd/host-os.h
 create mode 100644 bsd-user/openbsd/host-os.h

diff --git a/bsd-user/freebsd/host-os.h b/bsd-user/freebsd/host-os.h
new file mode 100644
index 00..a799164324
--- /dev/null
+++ b/bsd-user/freebsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  FreeBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef __HOST_OS_H_
+#define __HOST_OS_H_
+
+#endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/netbsd/host-os.h b/bsd-user/netbsd/host-os.h
new file mode 100644
index 00..b44cb7fdda
--- /dev/null
+++ b/bsd-user/netbsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  NetBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef __HOST_OS_H_
+#define __HOST_OS_H_
+
+#endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/openbsd/host-os.h b/bsd-user/openbsd/host-os.h
new file mode 100644
index 00..9083555f26
--- /dev/null
+++ b/bsd-user/openbsd/host-os.h
@@ -0,0 +1,23 @@
+/*
+ *  OpenBSD host dependent code and definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#ifndef __HOST_OS_H_
+#define __HOST_OS_H_
+
+#endif /*!__HOST_OS_H_ */
-- 
2.32.0




[PATCH for 6.2 16/49] bsd-user: elfload: simplify bswap a bit.

2021-08-07 Thread Warner Losh
Reduce the number of ifdefs by always calling the swapping routine, but
making them empty when swapping isn't needed.

Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 97 ++
 1 file changed, 47 insertions(+), 50 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 9c34e2ffcb..8a6a72bf05 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -67,13 +67,13 @@
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
-memcpy(to, from, n);
+memcpy(to, from, n);
 }
 
 #ifdef BSWAP_NEEDED
 static void bswap_ehdr(struct elfhdr *ehdr)
 {
-bswap16s(>e_type);/* Object file type */
+bswap16s(>e_type);/* Object file type */
 bswap16s(>e_machine); /* Architecture */
 bswap32s(>e_version); /* Object file version */
 bswaptls(>e_entry);   /* Entry point virtual address */
@@ -81,37 +81,45 @@ static void bswap_ehdr(struct elfhdr *ehdr)
 bswaptls(>e_shoff);   /* Section header table file offset */
 bswap32s(>e_flags);   /* Processor-specific flags */
 bswap16s(>e_ehsize);  /* ELF header size in bytes */
-bswap16s(>e_phentsize);   /* Program header table entry 
size */
+bswap16s(>e_phentsize);   /* Program header table entry size */
 bswap16s(>e_phnum);   /* Program header table entry count */
-bswap16s(>e_shentsize);   /* Section header table entry 
size */
+bswap16s(>e_shentsize);   /* Section header table entry size */
 bswap16s(>e_shnum);   /* Section header table entry count */
-bswap16s(>e_shstrndx);/* Section header string table 
index */
+bswap16s(>e_shstrndx);/* Section header string table index */
 }
 
-static void bswap_phdr(struct elf_phdr *phdr)
+static void bswap_phdr(struct elf_phdr *phdr, int phnum)
 {
-bswap32s(>p_type);/* Segment type */
-bswaptls(>p_offset);  /* Segment file offset */
-bswaptls(>p_vaddr);   /* Segment virtual address */
-bswaptls(>p_paddr);   /* Segment physical address */
-bswaptls(>p_filesz);  /* Segment size in file */
-bswaptls(>p_memsz);   /* Segment size in memory */
-bswap32s(>p_flags);   /* Segment flags */
-bswaptls(>p_align);   /* Segment alignment */
+int i;
+
+for (i = 0; i < phnum; i++, phdr++) {
+bswap32s(>p_type);/* Segment type */
+bswap32s(>p_flags);   /* Segment flags */
+bswaptls(>p_offset);  /* Segment file offset */
+bswaptls(>p_vaddr);   /* Segment virtual address */
+bswaptls(>p_paddr);   /* Segment physical address */
+bswaptls(>p_filesz);  /* Segment size in file */
+bswaptls(>p_memsz);   /* Segment size in memory */
+bswaptls(>p_align);   /* Segment alignment */
+}
 }
 
-static void bswap_shdr(struct elf_shdr *shdr)
+static void bswap_shdr(struct elf_shdr *shdr, int shnum)
 {
-bswap32s(>sh_name);
-bswap32s(>sh_type);
-bswaptls(>sh_flags);
-bswaptls(>sh_addr);
-bswaptls(>sh_offset);
-bswaptls(>sh_size);
-bswap32s(>sh_link);
-bswap32s(>sh_info);
-bswaptls(>sh_addralign);
-bswaptls(>sh_entsize);
+int i;
+
+for (i = 0; i < shnum; i++, shdr++) {
+bswap32s(>sh_name);
+bswap32s(>sh_type);
+bswaptls(>sh_flags);
+bswaptls(>sh_addr);
+bswaptls(>sh_offset);
+bswaptls(>sh_size);
+bswap32s(>sh_link);
+bswap32s(>sh_info);
+bswaptls(>sh_addralign);
+bswaptls(>sh_entsize);
+}
 }
 
 static void bswap_sym(struct elf_sym *sym)
@@ -121,7 +129,15 @@ static void bswap_sym(struct elf_sym *sym)
 bswaptls(>st_size);
 bswap16s(>st_shndx);
 }
-#endif
+
+#else /* ! BSWAP_NEEDED */
+
+static void bswap_ehdr(struct elfhdr *ehdr) { }
+static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
+static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
+static void bswap_sym(struct elf_sym *sym) { }
+
+#endif /* ! BSWAP_NEEDED */
 
 /*
  * 'copy_elf_strings()' copies argument/envelope strings from user
@@ -367,9 +383,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 last_bss = 0;
 error = 0;
 
-#ifdef BSWAP_NEEDED
 bswap_ehdr(interp_elf_ex);
-#endif
 /* First of all, some simple consistency checks */
 if ((interp_elf_ex->e_type != ET_EXEC &&
  interp_elf_ex->e_type != ET_DYN) ||
@@ -410,12 +424,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 free(elf_phdata);
 return retval;
 }
-#ifdef BSWAP_NEEDED
-eppnt = elf_phdata;
-for (i = 0; ie_phnum; i++, eppnt++) {
-bswap_phdr(eppnt);
-}
-#endif
+bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
 
 if (interp_elf_ex->e_type == ET_DYN) {
 /* in order 

[PATCH for 6.2 14/49] bsd-user: remove a.out support

2021-08-07 Thread Warner Losh
Remove still-born a.out support. The BSDs switched from a.out to ELF 20+ years
ago. It's out of scope for bsd-user, and what little support there was would
simply wind up at a not-implemented message. Simplify the whole mess by removing
it entirely. Should future support be required, it would be better to start from
scratch.

Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c |   9 +---
 bsd-user/elfload.c | 105 -
 bsd-user/qemu.h|   2 +-
 3 files changed, 21 insertions(+), 95 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index f8030d72bc..df81e36d88 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -98,7 +98,7 @@ static int prepare_binprm(struct bsd_binprm *bprm)
 
 /* Construct the envp and argv tables on the target stack.  */
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
-  abi_ulong stringp, int push_ptr)
+  abi_ulong stringp)
 {
 int n = sizeof(abi_ulong);
 abi_ulong envp;
@@ -108,13 +108,6 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 envp = sp;
 sp -= (argc + 1) * n;
 argv = sp;
-if (push_ptr) {
-/* FIXME - handle put_user() failures */
-sp -= n;
-put_user_ual(envp, sp);
-sp -= n;
-put_user_ual(argv, sp);
-}
 sp -= n;
 /* FIXME - handle put_user() failures */
 put_user_ual(argc, sp);
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index e950732978..9c34e2ffcb 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -52,25 +52,6 @@
 
 #include "elf.h"
 
-struct exec
-{
-  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
-  unsigned int a_text;   /* length of text, in bytes */
-  unsigned int a_data;   /* length of data, in bytes */
-  unsigned int a_bss;/* length of uninitialized data area, in bytes */
-  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
-  unsigned int a_entry;  /* start address */
-  unsigned int a_trsize; /* length of relocation info for text, in bytes */
-  unsigned int a_drsize; /* length of relocation info for data, in bytes */
-};
-
-
-#define N_MAGIC(exec) ((exec).a_info & 0x)
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define QMAGIC 0314
-
 /* max code+data+bss space allocated to elf interpreter */
 #define INTERP_MAP_SIZE (32 * 1024 * 1024)
 
@@ -82,10 +63,6 @@ struct exec
 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned 
long)(TARGET_ELF_EXEC_PAGESIZE - 1))
 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
 
-#define INTERPRETER_NONE 0
-#define INTERPRETER_AOUT 1
-#define INTERPRETER_ELF 2
-
 #define DLINFO_ITEMS 12
 
 static inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
@@ -93,8 +70,6 @@ static inline void memcpy_fromfs(void *to, const void *from, 
unsigned long n)
 memcpy(to, from, n);
 }
 
-static int load_aout_interp(void *exptr, int interp_fd);
-
 #ifdef BSWAP_NEEDED
 static void bswap_ehdr(struct elfhdr *ehdr)
 {
@@ -300,7 +275,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
struct elfhdr * exec,
abi_ulong load_addr,
abi_ulong load_bias,
-   abi_ulong interp_load_addr, int ibcs,
+   abi_ulong interp_load_addr,
struct image_info *info)
 {
 abi_ulong sp;
@@ -330,7 +305,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 size += DLINFO_ARCH_ITEMS * 2;
 #endif
 size += envc + argc + 2;
-size += (!ibcs ? 3 : 1);/* argc itself */
+size += 1;/* argc itself */
 size *= n;
 if (size & 15)
 sp -= 16 - (size & 15);
@@ -370,7 +345,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, 
int envc,
 #endif
 #undef NEW_AUX_ENT
 
-sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
+sp = loader_build_argptr(envc, argc, sp, p);
 return sp;
 }
 
@@ -432,7 +407,7 @@ static abi_ulong load_elf_interp(struct elfhdr 
*interp_elf_ex,
 if (retval < 0) {
 perror("load_elf_interp");
 exit(-1);
-free (elf_phdata);
+free(elf_phdata);
 return retval;
 }
 #ifdef BSWAP_NEEDED
@@ -685,11 +660,9 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 {
 struct elfhdr elf_ex;
 struct elfhdr interp_elf_ex;
-struct exec interp_ex;
 int interpreter_fd = -1; /* avoid warning */
 abi_ulong load_addr, load_bias;
 int load_addr_set = 0;
-unsigned int interpreter_type = INTERPRETER_NONE;
 int i;
 struct elf_phdr * elf_ppnt;
 struct elf_phdr *elf_phdata;
@@ -702,7 +675,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs 

[PATCH for 6.2 10/49] bsd-user: pass the bsd_param into loader_exec

2021-08-07 Thread Warner Losh
Pass the bsd_param into loader_exec, and adjust.

Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 37 +++--
 bsd-user/main.c|  7 ++-
 bsd-user/qemu.h|  3 ++-
 3 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index ec71c5e923..5282a7c4f2 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -140,35 +140,36 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 }
 
 int loader_exec(const char *filename, char **argv, char **envp,
-struct target_pt_regs *regs, struct image_info *infop)
+struct target_pt_regs *regs, struct image_info *infop,
+struct bsd_binprm *bprm)
 {
-struct bsd_binprm bprm;
 int retval;
 int i;
 
-bprm.p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
-for (i = 0 ; i < MAX_ARG_PAGES ; i++) { /* clear page-table */
-bprm.page[i] = NULL;
+bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
+for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
+bprm->page[i] = NULL;
 }
 retval = open(filename, O_RDONLY);
 if (retval < 0) {
 return retval;
 }
-bprm.fd = retval;
-bprm.filename = (char *)filename;
-bprm.argc = count(argv);
-bprm.argv = argv;
-bprm.envc = count(envp);
-bprm.envp = envp;
 
-retval = prepare_binprm();
+bprm->fd = retval;
+bprm->filename = (char *)filename;
+bprm->argc = count(argv);
+bprm->argv = argv;
+bprm->envc = count(envp);
+bprm->envp = envp;
+
+retval = prepare_binprm(bprm);
 
 if (retval >= 0) {
-if (bprm.buf[0] == 0x7f
-&& bprm.buf[1] == 'E'
-&& bprm.buf[2] == 'L'
-&& bprm.buf[3] == 'F') {
-retval = load_elf_binary(, regs, infop);
+if (bprm->buf[0] == 0x7f
+&& bprm->buf[1] == 'E'
+&& bprm->buf[2] == 'L'
+&& bprm->buf[3] == 'F') {
+retval = load_elf_binary(bprm, regs, infop);
 } else {
 fprintf(stderr, "Unknown binary format\n");
 return -1;
@@ -183,7 +184,7 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 
 /* Something went wrong, return the inode and free the argument pages*/
 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-g_free(bprm.page[i]);
+g_free(bprm->page[i]);
 }
 return retval;
 }
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 5c579d7c2c..65958729f1 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -343,6 +343,7 @@ int main(int argc, char **argv)
 const char *log_mask = NULL;
 struct target_pt_regs regs1, *regs = 
 struct image_info info1, *info = 
+struct bsd_binprm bprm;
 TaskState ts1, *ts = 
 CPUArchState *env;
 CPUState *cpu;
@@ -499,6 +500,9 @@ int main(int argc, char **argv)
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
+/* Zero bsd params */
+memset(, 0, sizeof(bprm));
+
 /* Zero out image_info */
 memset(info, 0, sizeof(struct image_info));
 
@@ -565,7 +569,8 @@ int main(int argc, char **argv)
 }
 }
 
-if (loader_exec(filename, argv + optind, target_environ, regs, info) != 0) 
{
+if (loader_exec(filename, argv+optind, target_environ, regs, info,
+) != 0) {
 printf("Error loading %s\n", filename);
 _exit(1);
 }
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index c02e8a5ca1..5237e35f9c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -131,7 +131,8 @@ void do_init_thread(struct target_pt_regs *regs, struct 
image_info *infop);
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
   abi_ulong stringp, int push_ptr);
 int loader_exec(const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop);
+struct target_pt_regs *regs, struct image_info *infop,
+struct bsd_binprm *bprm);
 
 int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 struct image_info *info);
-- 
2.32.0




[PATCH for 6.2 15/49] bsd-user: TARGET_NGROUPS unused in this file, remove

2021-08-07 Thread Warner Losh
Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index df81e36d88..006e19cf3f 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -19,8 +19,6 @@
 
 #include "qemu.h"
 
-#define TARGET_NGROUPS 32
-
 /* ??? This should really be somewhere else.  */
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
   unsigned long len)
-- 
2.32.0




[PATCH for 6.2 12/49] bsd-user: implement path searching

2021-08-07 Thread Warner Losh
Use the PATH to find the executable given a bare argument.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 73 +-
 bsd-user/qemu.h|  3 +-
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 379015c744..f8030d72bc 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -139,17 +139,88 @@ abi_ulong loader_build_argptr(int envc, int argc, 
abi_ulong sp,
 return sp;
 }
 
+static bool is_there(const char *candidate)
+{
+struct stat fin;
+
+/* XXX work around access(2) false positives for superuser */
+if (access(candidate, X_OK) == 0 && stat(candidate, ) == 0 &&
+S_ISREG(fin.st_mode) && (getuid() != 0 ||
+(fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) {
+return true;
+}
+
+return false;
+}
+
+static bool find_in_path(char *path, const char *filename, char *retpath,
+ size_t rpsize)
+{
+const char *d;
+
+while ((d = strsep(, ":")) != NULL) {
+if (*d == '\0') {
+d = ".";
+}
+if (snprintf(retpath, rpsize, "%s/%s", d, filename) >= (int)rpsize) {
+continue;
+}
+if (is_there((const char *)retpath)) {
+return true;
+}
+}
+return false;
+}
+
 int loader_exec(const char *filename, char **argv, char **envp,
 struct target_pt_regs *regs, struct image_info *infop,
 struct bsd_binprm *bprm)
 {
+char *p, *path = NULL, fullpath[PATH_MAX];
 int retval, i;
 
 bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
 for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
 bprm->page[i] = NULL;
 }
-retval = open(filename, O_RDONLY);
+
+if (strchr(filename, '/') != NULL) {
+path = realpath(filename, fullpath);
+if (path == NULL) {
+/* Failed to resolve. */
+return -1;
+}
+if (!is_there(path)) {
+return -1;
+}
+retval = open(path, O_RDONLY);
+bprm->fullpath = g_strdup(path);
+} else {
+p = getenv("PATH");
+if (p == NULL) {
+return -1;
+}
+
+path = g_strdup(p);
+if (path == NULL) {
+fprintf(stderr, "Out of memory\n");
+return -1;
+}
+
+if (!find_in_path(path, filename, fullpath, sizeof(fullpath))) {
+return -1;
+}
+retval = open(fullpath, O_RDONLY);
+bprm->fullpath = g_strdup(fullpath);
+
+g_free(path);
+}
+
+/* bprm->fullpath must be populated. */
+if (bprm->fullpath == NULL) {
+fprintf(stderr, "Out of memory\n");
+return -1;
+}
 if (retval < 0) {
 return retval;
 }
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5237e35f9c..6b601ce4b5 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -124,7 +124,8 @@ struct bsd_binprm {
 int argc, envc;
 char **argv;
 char **envp;
-char *filename; /* Name of binary */
+char *filename; /* (Given) Name of binary */
+char *fullpath; /* Full path of binary */
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
-- 
2.32.0




[PATCH for 6.2 13/49] bsd-user: Eliminate elf personality

2021-08-07 Thread Warner Losh
The linux kernel supports a number of different ELF binaries. The Linux userland
emulator inheritted some of that. And we inheritted it from there. However, for
BSD there's only one kind of ELF file supported per platform, so there's no need
to cope with historical quirks. Simply the code as a result.

Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 87 --
 bsd-user/qemu.h|  1 -
 2 files changed, 88 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 639673f5b7..e950732978 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -25,66 +25,6 @@
 
 #include "target_arch_elf.h"
 
-/* from personality.h */
-
-/*
- * Flags for bug emulation.
- *
- * These occupy the top three bytes.
- */
-enum {
-ADDR_NO_RANDOMIZE = 0x004,  /* disable randomization of VA 
space */
-FDPIC_FUNCPTRS =0x008,  /* userspace function ptrs 
point to descriptors
- * (signal handling)
- */
-MMAP_PAGE_ZERO =0x010,
-ADDR_COMPAT_LAYOUT =0x020,
-READ_IMPLIES_EXEC = 0x040,
-ADDR_LIMIT_32BIT =  0x080,
-SHORT_INODE =   0x100,
-WHOLE_SECONDS = 0x200,
-STICKY_TIMEOUTS =   0x400,
-ADDR_LIMIT_3GB =0x800,
-};
-
-/*
- * Personality types.
- *
- * These go in the low byte.  Avoid using the top bit, it will
- * conflict with error returns.
- */
-enum {
-PER_LINUX = 0x,
-PER_LINUX_32BIT =   0x | ADDR_LIMIT_32BIT,
-PER_LINUX_FDPIC =   0x | FDPIC_FUNCPTRS,
-PER_SVR4 =  0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
-PER_SVR3 =  0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_SCOSVR3 =   0x0003 | STICKY_TIMEOUTS |
- WHOLE_SECONDS | SHORT_INODE,
-PER_OSR5 =  0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
-PER_WYSEV386 =  0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
-PER_BSD =   0x0006,
-PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
-PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
-PER_LINUX32 =   0x0008,
-PER_LINUX32_3GB =   0x0008 | ADDR_LIMIT_3GB,
-PER_IRIX32 =0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
-PER_IRIXN32 =   0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
-PER_IRIX64 =0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
-PER_RISCOS =0x000c,
-PER_SOLARIS =   0x000d | STICKY_TIMEOUTS,
-PER_UW7 =   0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
-PER_OSF4 =  0x000f,  /* OSF/1 v4 */
-PER_HPUX =  0x0010,
-PER_MASK =  0x00ff,
-};
-
-/*
- * Return the base personality without flags.
- */
-#define personality(pers)   (pers & PER_MASK)
-
 /* this flag is uneffective under linux too, should be deleted */
 #ifndef MAP_DENYWRITE
 #define MAP_DENYWRITE 0
@@ -750,7 +690,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 abi_ulong load_addr, load_bias;
 int load_addr_set = 0;
 unsigned int interpreter_type = INTERPRETER_NONE;
-unsigned char ibcs2_interpreter;
 int i;
 struct elf_phdr * elf_ppnt;
 struct elf_phdr *elf_phdata;
@@ -765,7 +704,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 #endif
 char passed_fileno[6];
 
-ibcs2_interpreter = 0;
 load_addr = 0;
 load_bias = 0;
 elf_ex = *((struct elfhdr *) bprm->buf);  /* exec-header */
@@ -856,20 +794,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 exit(-1);
 }
 
-/* If the program interpreter is one of these two,
-   then assume an iBCS2 image. Otherwise assume
-   a native linux image. */
-
-/* JRP - Need to add X86 lib dir stuff here... */
-
-if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0 ||
-strcmp(elf_interpreter, "/usr/lib/ld.so.1") == 0) {
-  ibcs2_interpreter = 1;
-}
-
-#if 0
-printf("Using ELF interpreter %s\n", path(elf_interpreter));
-#endif
 if (retval >= 0) {
 retval = open(path(elf_interpreter), O_RDONLY);
 if (retval >= 0) {
@@ -1099,7 +1023,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct 
target_pt_regs *regs,
 load_symbols(_ex, bprm->fd);
 
 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
-info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
 
 #ifdef LOW_ELF_STACK
 

[PATCH for 6.2 04/49] bsd-user: Remove all non-x86 code from elfload.c

2021-08-07 Thread Warner Losh
bsd-user only builds x86 at the moment. Remove all non x86 code from
elfload.c. We'll move the x86 code to {i386,x86_64}/target_arch_elf.h
and bring it that support code from the forked bsd-user when the time
comes.

Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 347 +
 1 file changed, 2 insertions(+), 345 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index ae62f3aab3..fffa24f041 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,15 +23,6 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
-#ifdef _ARCH_PPC64
-#undef ARCH_DLINFO
-#undef ELF_PLATFORM
-#undef ELF_HWCAP
-#undef ELF_CLASS
-#undef ELF_DATA
-#undef ELF_ARCH
-#endif
-
 /* from personality.h */
 
 /*
@@ -144,7 +135,7 @@ static inline void init_thread(struct target_pt_regs *regs, 
struct image_info *i
 }
 }
 
-#else
+#else /* !TARGET_X86_64 */
 
 #define ELF_START_MMAP 0x8000
 
@@ -174,343 +165,13 @@ static inline void init_thread(struct target_pt_regs 
*regs, struct image_info *i
A value of 0 tells we have no such handler.  */
 regs->edx = 0;
 }
-#endif
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-#endif
-
-#ifdef TARGET_ARM
-
-#define ELF_START_MMAP 0x8000
-
-#define elf_check_arch(x) ((x) == EM_ARM)
-
-#define ELF_CLASS   ELFCLASS32
-#ifdef TARGET_WORDS_BIGENDIAN
-#define ELF_DATAELFDATA2MSB
-#else
-#define ELF_DATAELFDATA2LSB
-#endif
-#define ELF_ARCHEM_ARM
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-abi_long stack = infop->start_stack;
-memset(regs, 0, sizeof(*regs));
-regs->ARM_cpsr = 0x10;
-if (infop->entry & 1)
-regs->ARM_cpsr |= CPSR_T;
-regs->ARM_pc = infop->entry & 0xfffe;
-regs->ARM_sp = infop->start_stack;
-/* FIXME - what to for failure of get_user()? */
-get_user_ual(regs->ARM_r2, stack + 8); /* envp */
-get_user_ual(regs->ARM_r1, stack + 4); /* envp */
-/* XXX: it seems that r0 is zeroed after ! */
-regs->ARM_r0 = 0;
-/* For uClinux PIC binaries.  */
-/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
-regs->ARM_r10 = infop->start_data;
-}
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-enum
-{
-  ARM_HWCAP_ARM_SWP   = 1 << 0,
-  ARM_HWCAP_ARM_HALF  = 1 << 1,
-  ARM_HWCAP_ARM_THUMB = 1 << 2,
-  ARM_HWCAP_ARM_26BIT = 1 << 3,
-  ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
-  ARM_HWCAP_ARM_FPA   = 1 << 5,
-  ARM_HWCAP_ARM_VFP   = 1 << 6,
-  ARM_HWCAP_ARM_EDSP  = 1 << 7,
-};
-
-#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF  \
-| ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
-| ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
-
-#endif
-
-#ifdef TARGET_SPARC
-#ifdef TARGET_SPARC64
-
-#define ELF_START_MMAP 0x8000
-
-#ifndef TARGET_ABI32
-#define elf_check_arch(x) ((x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS)
-#else
-#define elf_check_arch(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
-#endif
-
-#define ELF_CLASS   ELFCLASS64
-#define ELF_DATAELFDATA2MSB
-#define ELF_ARCHEM_SPARCV9
-
-#define STACK_BIAS  2047
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-#ifndef TARGET_ABI32
-regs->tstate = 0;
-#endif
-regs->pc = infop->entry;
-regs->npc = regs->pc + 4;
-regs->y = 0;
-#ifdef TARGET_ABI32
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-#else
-if (personality(infop->personality) == PER_LINUX32)
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-else {
-regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
-if (bsd_type == target_freebsd) {
-regs->u_regs[8] = infop->start_stack;
-regs->u_regs[11] = infop->start_stack;
-}
-}
-#endif
-}
-
-#else
-#define ELF_START_MMAP 0x8000
-
-#define elf_check_arch(x) ((x) == EM_SPARC)
-
-#define ELF_CLASS   ELFCLASS32
-#define ELF_DATAELFDATA2MSB
-#define ELF_ARCHEM_SPARC
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->psr = 0;
-regs->pc = infop->entry;
-regs->npc = regs->pc + 4;
-regs->y = 0;
-regs->u_regs[14] = infop->start_stack - 16 * 4;
-}
-
-#endif
-#endif
-
-#ifdef TARGET_PPC
-
-#define ELF_START_MMAP 0x8000
-
-#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
-
-#define elf_check_arch(x) ((x) == EM_PPC64)
-
-#define ELF_CLASS   ELFCLASS64
-
-#else
-
-#define elf_check_arch(x) ((x) == EM_PPC)
-
-#define ELF_CLASS   ELFCLASS32
-
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
-#define ELF_DATAELFDATA2MSB
-#else
-#define ELF_DATAELFDATA2LSB
-#endif
-#define ELF_ARCHEM_PPC
-
-/*
- * We need to put in some extra aux table entries to tell glibc what
- * the cache block size is, so it can use the dcbz instruction safely.
- */
-#define 

[PATCH for 6.2 06/49] bsd-user: merge comments and guards from bsd-user fork

2021-08-07 Thread Warner Losh
Diff reduction against bsd-user fork: bring in the copyright/license
comments, and guard ifdefs.

Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_elf.h   | 22 ++
 bsd-user/x86_64/target_arch_elf.h | 23 +++
 2 files changed, 45 insertions(+)

diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
index 084c9a7814..20ef0ccbdb 100644
--- a/bsd-user/i386/target_arch_elf.h
+++ b/bsd-user/i386/target_arch_elf.h
@@ -1,3 +1,23 @@
+/*
+ *  i386 ELF definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_ARCH_ELF_H_
+#define _TARGET_ARCH_ELF_H_
 
 #define ELF_PLATFORM get_elf_platform()
 
@@ -52,3 +72,5 @@ static inline void init_thread(struct target_pt_regs *regs, 
struct image_info *i
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE   4096
+
+#endif /* _TARGET_ARCH_ELF_H_ */
diff --git a/bsd-user/x86_64/target_arch_elf.h 
b/bsd-user/x86_64/target_arch_elf.h
index 08a86da1a5..d3c139c7a9 100644
--- a/bsd-user/x86_64/target_arch_elf.h
+++ b/bsd-user/x86_64/target_arch_elf.h
@@ -1,3 +1,24 @@
+/*
+ *  x86_64 ELF definitions
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+#ifndef _TARGET_ARCH_ELF_H_
+#define _TARGET_ARCH_ELF_H_
+
 #define ELF_PLATFORM get_elf_platform()
 
 static const char *get_elf_platform(void)
@@ -39,3 +60,5 @@ static inline void init_thread(struct target_pt_regs *regs, 
struct image_info *i
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE   4096
+
+#endif /* _TARGET_ARCH_ELF_H_ */
-- 
2.32.0




[PATCH for 6.2 11/49] bsd-user: Fix calculation of size to allocate

2021-08-07 Thread Warner Losh
It was incorrect to subtract off the size of an unsigned int here.  In
bsd-user fork, this change was made when moving the arch specific items
to specific files.  The size in BSD that's available for the arguments
does not need a return address subtracted from it.

Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 5282a7c4f2..379015c744 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -143,10 +143,9 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 struct target_pt_regs *regs, struct image_info *infop,
 struct bsd_binprm *bprm)
 {
-int retval;
-int i;
+int retval, i;
 
-bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
+bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES;
 for (i = 0; i < MAX_ARG_PAGES; i++) {   /* clear page-table */
 bprm->page[i] = NULL;
 }
-- 
2.32.0




[PATCH for 6.2 05/49] bsd-user: move arch specific defines out of elfload.c

2021-08-07 Thread Warner Losh
Move the arcitecture specific defines to target_arch_elf.h and delete them from
elfload.c. unifdef as appropriate for i386 vs x86_64 versions.

Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c| 81 +--
 bsd-user/i386/target_arch_elf.h   | 54 +
 bsd-user/x86_64/target_arch_elf.h | 41 
 3 files changed, 97 insertions(+), 79 deletions(-)
 create mode 100644 bsd-user/i386/target_arch_elf.h
 create mode 100644 bsd-user/x86_64/target_arch_elf.h

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index fffa24f041..639673f5b7 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -23,6 +23,8 @@
 #include "disas/disas.h"
 #include "qemu/path.h"
 
+#include "target_arch_elf.h"
+
 /* from personality.h */
 
 /*
@@ -93,85 +95,6 @@ enum {
 #define ELIBBAD 80
 #endif
 
-#ifdef TARGET_I386
-
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
-static char elf_platform[] = "i386";
-int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6)
-family = 6;
-if (family >= 3)
-elf_platform[1] = '0' + family;
-return elf_platform;
-}
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
-X86CPU *cpu = X86_CPU(thread_cpu);
-
-return cpu->env.features[FEAT_1_EDX];
-}
-
-#ifdef TARGET_X86_64
-#define ELF_START_MMAP 0x2ab000ULL
-#define elf_check_arch(x) (((x) == ELF_ARCH))
-
-#define ELF_CLASS  ELFCLASS64
-#define ELF_DATA   ELFDATA2LSB
-#define ELF_ARCH   EM_X86_64
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->rax = 0;
-regs->rsp = infop->start_stack;
-regs->rip = infop->entry;
-if (bsd_type == target_freebsd) {
-regs->rdi = infop->start_stack;
-}
-}
-
-#else /* !TARGET_X86_64 */
-
-#define ELF_START_MMAP 0x8000
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS   ELFCLASS32
-#define ELF_DATAELFDATA2LSB
-#define ELF_ARCHEM_386
-
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
-{
-regs->esp = infop->start_stack;
-regs->eip = infop->entry;
-
-/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
-   starts %edx contains a pointer to a function which might be
-   registered using `atexit'.  This provides a mean for the
-   dynamic linker to call DT_FINI functions for shared libraries
-   that have been loaded before the code runs.
-
-   A value of 0 tells we have no such handler.  */
-regs->edx = 0;
-}
-#endif /* !TARGET_X86_64 */
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE   4096
-
-#endif
-
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
new file mode 100644
index 00..084c9a7814
--- /dev/null
+++ b/bsd-user/i386/target_arch_elf.h
@@ -0,0 +1,54 @@
+
+#define ELF_PLATFORM get_elf_platform()
+
+static const char *get_elf_platform(void)
+{
+static char elf_platform[] = "i386";
+int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
+if (family > 6)
+family = 6;
+if (family >= 3)
+elf_platform[1] = '0' + family;
+return elf_platform;
+}
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+X86CPU *cpu = X86_CPU(thread_cpu);
+
+return cpu->env.features[FEAT_1_EDX];
+}
+
+#define ELF_START_MMAP 0x8000
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS   ELFCLASS32
+#define ELF_DATAELFDATA2LSB
+#define ELF_ARCHEM_386
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+{
+regs->esp = infop->start_stack;
+regs->eip = infop->entry;
+
+/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
+   starts %edx contains a pointer to a function which might be
+   registered using `atexit'.  This provides a mean for the
+   dynamic linker to call DT_FINI functions for shared libraries
+   that have been loaded before the code runs.
+
+   A value of 0 tells we have no such handler.  */
+regs->edx = 0;
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE   4096
diff --git a/bsd-user/x86_64/target_arch_elf.h 
b/bsd-user/x86_64/target_arch_elf.h
new file mode 100644
index 00..08a86da1a5
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_elf.h
@@ -0,0 +1,41 @@
+#define ELF_PLATFORM get_elf_platform()
+
+static const char 

[PATCH for 6.2 09/49] bsd-user: add license

2021-08-07 Thread Warner Losh
Pull in the license statement at the top of the bsdload.c file
from the bsd-user fork version of this file. No functional changes.

Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 39098170d5..ec71c5e923 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -1,4 +1,19 @@
-/* Code for loading BSD executables.  Mostly linux kernel code.  */
+/*
+ *  Load BSD executables.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
 
 #include "qemu/osdep.h"
 
-- 
2.32.0




[PATCH for 6.2 08/49] bsd-user: style nits: fix whitespace issues to be qemu standard

2021-08-07 Thread Warner Losh
Signed-off-by: Warner Losh 
---
 bsd-user/bsdload.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 8d83f21eda..39098170d5 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -125,7 +125,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong 
sp,
 }
 
 int loader_exec(const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop)
+struct target_pt_regs *regs, struct image_info *infop)
 {
 struct bsd_binprm bprm;
 int retval;
@@ -133,7 +133,7 @@ int loader_exec(const char *filename, char **argv, char 
**envp,
 
 bprm.p = TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(unsigned int);
 for (i = 0 ; i < MAX_ARG_PAGES ; i++) { /* clear page-table */
-bprm.page[i] = NULL;
+bprm.page[i] = NULL;
 }
 retval = open(filename, O_RDONLY);
 if (retval < 0) {
-- 
2.32.0




[PATCH for 6.2 03/49] bsd-user: Add Stacey's copyright to main.c

2021-08-07 Thread Warner Losh
From: Warner Losh 

Add Stacey's updated copyright to main.c

Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 

Sponsored by:   Netflix
---
 bsd-user/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 8e1ac5d042..5c579d7c2c 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1,7 +1,8 @@
 /*
- *  qemu user main
+ *  qemu bsd user main
  *
  *  Copyright (c) 2003-2008 Fabrice Bellard
+ *  Copyright (c) 2013-14 Stacey Son
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
-- 
2.32.0




[PATCH for 6.2 07/49] bsd-user: style nits: apply qemu style to these files

2021-08-07 Thread Warner Losh
Fix style wrt {} placement, spaces around () and line lengths.

Signed-off-by: Warner Losh 
---
 bsd-user/i386/target_arch_elf.h   | 27 ---
 bsd-user/x86_64/target_arch_elf.h | 11 +++
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h
index 20ef0ccbdb..f322fc174b 100644
--- a/bsd-user/i386/target_arch_elf.h
+++ b/bsd-user/i386/target_arch_elf.h
@@ -25,10 +25,12 @@ static const char *get_elf_platform(void)
 {
 static char elf_platform[] = "i386";
 int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6)
+if (family > 6) {
 family = 6;
-if (family >= 3)
+}
+if (family >= 3) {
 elf_platform[1] = '0' + family;
+}
 return elf_platform;
 }
 
@@ -46,7 +48,7 @@ static uint32_t get_elf_hwcap(void)
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
-#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
+#define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
 
 /*
  * These are used to set parameters in the core dumps.
@@ -55,18 +57,21 @@ static uint32_t get_elf_hwcap(void)
 #define ELF_DATAELFDATA2LSB
 #define ELF_ARCHEM_386
 
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
 {
 regs->esp = infop->start_stack;
 regs->eip = infop->entry;
 
-/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
-   starts %edx contains a pointer to a function which might be
-   registered using `atexit'.  This provides a mean for the
-   dynamic linker to call DT_FINI functions for shared libraries
-   that have been loaded before the code runs.
-
-   A value of 0 tells we have no such handler.  */
+/*
+ * SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
+ * contains a pointer to a function which might be registered using
+ * `atexit'.  This provides a mean for the dynamic linker to call DT_FINI
+ * functions for shared libraries that have been loaded before the code
+ * runs.
+ *
+ * A value of 0 tells we have no such handler.
+ */
 regs->edx = 0;
 }
 
diff --git a/bsd-user/x86_64/target_arch_elf.h 
b/bsd-user/x86_64/target_arch_elf.h
index d3c139c7a9..e7c8aa2755 100644
--- a/bsd-user/x86_64/target_arch_elf.h
+++ b/bsd-user/x86_64/target_arch_elf.h
@@ -25,10 +25,12 @@ static const char *get_elf_platform(void)
 {
 static char elf_platform[] = "i386";
 int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
-if (family > 6)
+if (family > 6) {
 family = 6;
-if (family >= 3)
+}
+if (family >= 3) {
 elf_platform[1] = '0' + family;
+}
 return elf_platform;
 }
 
@@ -42,13 +44,14 @@ static uint32_t get_elf_hwcap(void)
 }
 
 #define ELF_START_MMAP 0x2ab000ULL
-#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
+#define elf_check_arch(x) (((x) == ELF_ARCH))
 
 #define ELF_CLASS  ELFCLASS64
 #define ELF_DATA   ELFDATA2LSB
 #define ELF_ARCH   EM_X86_64
 
-static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
 {
 regs->rax = 0;
 regs->rsp = infop->start_stack;
-- 
2.32.0




[PATCH for 6.2 00/49] bsd-user updates to run hello world

2021-08-07 Thread Warner Losh
This series of patches gets me to the point that I can run "Hello World" on i386
and x86_64. This is for static binaries only, that are relatively small, but
it's better than the 100% instant mmap failre that is the current state of all
things bsd-user in upstream qemu. Future patch sets will refine this, add
the missing system calls, fix bugs preventing more sophisticated programms
from running and add a bunch of new architecture support.

There's three large themes in these patches, though the changes that
represent them are interrelated making it hard to separate out further.
1. Reorganization to support multiple OS and architectures (though I've only
   tested FreeBSD, other BSDs might not even compile yet).
2. Diff reduction with the bsd-user fork for several files. These diffs include
   changes that borrowed from linux-user as well as changes to make things work
   on FreeBSD. The records keeping when this was done, however, was poor at
   best, so many of the specific borrowings are going unacknowledged here, apart
   from this general ack. These diffs also include some minor code shuffling.
   Some of the changes are done specifically to make it easier to rebase
   the bsd-user fork's changes when these land in the tree (a number of changes
   have been pushed there to make this more possible).
3. Filling in the missing pieces to make things work. There's many changes to
   elfload to make it load things in the right places, to find the interpreter
   better, etc. There's changes to mmap.c to make the mappings work better and
   there's changes to main.c that were inspired, at least, by now-ancient 
changes
   to linux-user's main.c.

I ran checkpatch.pl on this, and there's 350-odd errors it identifies (the vast
majoirty come from BSD's fetish for tabs), so there will need to be a V2 to fix
this at the very least. In addition, the change set is big (about +~4.5k/-~2.5k
lines), so I anticipate some iteration as well just based on its sheer
size. I've tried to keep each set small to make it easy to review in isolation,
but I've also allowed some interrelated ones to get a little bigger than I'd
normally like. I've not done the customary documentation of the expected
checkpatch.pl output because it is large, and because I wanted to get review
of the other parts rolling to get this project unstuck. Future versions of the
patch will document the expected output.

In addition, I noticed a number of places where I could modernize to make the
code match things like linux-user better. I've resisted the urge to do these at
this time, since it would complicate merging the other ~30k lines of diff that
remains after this batch. Future batches should generally be smaller once this
one has landed since they are, by and large, either a bunch of new files to
support armv7, aarch64, riscv64, mips, mipsel, mips64, ppc, ppc64 and ppc64le,
or are adding system calls, which can be done individually or small groups. I've
removed sparc and sparc64 support as they've been removed from FreeBSD and
have been near totally busted for years.

Stacey Son did the bulk of this work originally, but since I had to move things
around so much and/or retool that work in non-trivial ways, I've kept myself as
author, and added his signed-off-by line. I'm unsure of the qemu standard
practice for this, but am happy to learn if this is too far outside its current
mainstream. For a while Sean Bruno did the merges from upstream, and he's
credited using his signed-off-by in appropriate places, though for this patch
set there's only a few. I've tried to ensure that others who have work in
individual patches that I've aggregated together also are reflected in their
signed-off-by. Given the chaotic stat of the upstream repo for its early
history, this may be the best that can be reconstructed at this late date. Most
of these files are 'foundational' so have existed from the earliest days when
record keeping wasn't quite what I'd wish for in hindsight. There was only
really one change that I could easily cherry-pick (Colin's), so I did that.

Colin Percival (1):
  bsd-user: Add '-0 argv0' option to bsd-user/main.c

Warner Losh (48):
  bsd-user: remove sparc and sparc64
  bsd-user: add copyright header to elfload.c
  bsd-user: Add Stacey's copyright to main.c
  bsd-user: Remove all non-x86 code from elfload.c
  bsd-user: move arch specific defines out of elfload.c
  bsd-user: merge comments and guards from bsd-user fork
  bsd-user: style nits: apply qemu style to these files
  bsd-user: style nits: fix whitespace issues to be qemu standard
  bsd-user: add license
  bsd-user: pass the bsd_param into loader_exec
  bsd-user: Fix calculation of size to allocate
  bsd-user: implement path searching
  bsd-user: Eliminate elf personality
  bsd-user: remove a.out support
  bsd-user: TARGET_NGROUPS unused in this file, remove
  bsd-user: elfload: simplify bswap a bit.
  bsd-user: assume pthreads and support of __thread
  bsd-user: add host-os.h
  

[PATCH for 6.2 02/49] bsd-user: add copyright header to elfload.c

2021-08-07 Thread Warner Losh
From: Warner Losh 

Add Stacey's copyright to elfload.c

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/elfload.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 6edceb3ea6..ae62f3aab3 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -1,4 +1,21 @@
-/* This is the Linux kernel elf-loading code, ported into user space */
+/*
+ *  ELF loading code
+ *
+ *  Copyright (c) 2013 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
 
 #include "qemu/osdep.h"
 
-- 
2.32.0




[PATCH for 6.2 01/49] bsd-user: remove sparc and sparc64

2021-08-07 Thread Warner Losh
From: Warner Losh 

These are broken here and in the bsd-user fork. They won't be fixed as
FreeBSD has dropped support for sparc. If people wish to support this in
other BSDs, you're better off starting over than starting from these
files.

Signed-off-by: Warner Losh 
---
 bsd-user/main.c| 290 -
 bsd-user/sparc/target_arch_sysarch.h   |  52 -
 bsd-user/sparc/target_syscall.h|  36 ---
 bsd-user/sparc64/target_arch_sysarch.h |  52 -
 bsd-user/sparc64/target_syscall.h  |  37 
 bsd-user/syscall.c |  11 -
 6 files changed, 478 deletions(-)
 delete mode 100644 bsd-user/sparc/target_arch_sysarch.h
 delete mode 100644 bsd-user/sparc/target_syscall.h
 delete mode 100644 bsd-user/sparc64/target_arch_sysarch.h
 delete mode 100644 bsd-user/sparc64/target_syscall.h

diff --git a/bsd-user/main.c b/bsd-user/main.c
index fe66204b6b..8e1ac5d042 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -261,274 +261,6 @@ void cpu_loop(CPUX86State *env)
 }
 #endif
 
-#ifdef TARGET_SPARC
-#define SPARC64_STACK_BIAS 2047
-
-/* #define DEBUG_WIN */
-/*
- * WARNING: dealing with register windows _is_ complicated. More info
- * can be found at http://www.sics.se/~psm/sparcstack.html
- */
-static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
-{
-index = (index + cwp * 16) % (16 * env->nwindows);
-/*
- * wrap handling : if cwp is on the last window, then we use the
- * registers 'after' the end
- */
-if (index < 8 && env->cwp == env->nwindows - 1) {
-index += 16 * env->nwindows;
-}
-return index;
-}
-
-/* save the register window 'cwp1' */
-static inline void save_window_offset(CPUSPARCState *env, int cwp1)
-{
-unsigned int i;
-abi_ulong sp_ptr;
-
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3) {
-sp_ptr += SPARC64_STACK_BIAS;
-}
-#endif
-#if defined(DEBUG_WIN)
-printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for (i = 0; i < 16; i++) {
-/* FIXME - what to do if put_user() fails? */
-put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-}
-
-static void save_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-env->wim = new_wim;
-#else
-/*
- * cansave is zero if the spill trap handler is triggered by `save` and
- * nonzero if triggered by a `flushw`
- */
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
-env->cansave++;
-env->canrestore--;
-#endif
-}
-
-static void restore_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-#endif
-unsigned int i, cwp1;
-abi_ulong sp_ptr;
-
-#ifndef TARGET_SPARC64
-new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-#endif
-
-/* restore the invalid window */
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3) {
-sp_ptr += SPARC64_STACK_BIAS;
-}
-#endif
-#if defined(DEBUG_WIN)
-printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for (i = 0; i < 16; i++) {
-/* FIXME - what to do if get_user() fails? */
-get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-#ifdef TARGET_SPARC64
-env->canrestore++;
-if (env->cleanwin < env->nwindows - 1) {
-env->cleanwin++;
-}
-env->cansave--;
-#else
-env->wim = new_wim;
-#endif
-}
-
-static void flush_windows(CPUSPARCState *env)
-{
-int offset, cwp1;
-
-offset = 1;
-for (;;) {
-/* if restore would invoke restore_window(), then we can stop */
-cwp1 = cpu_cwp_inc(env, env->cwp + offset);
-#ifndef TARGET_SPARC64
-if (env->wim & (1 << cwp1)) {
-break;
-}
-#else
-if (env->canrestore == 0) {
-break;
-}
-env->cansave++;
-env->canrestore--;
-#endif
-save_window_offset(env, cwp1);
-offset++;
-}
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-#ifndef TARGET_SPARC64
-/* set wim so that restore will reload the registers */
-env->wim = 1 << cwp1;
-#endif
-#if defined(DEBUG_WIN)
-printf("flush_windows: nb=%d\n", offset - 1);
-#endif
-}
-
-void cpu_loop(CPUSPARCState *env)
-{
-CPUState *cs = env_cpu(env);
-int trapnr, ret, syscall_nr;
-/* target_siginfo_t info; */
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-  

Re: [PATCH] vmxnet3: add stub for encapsulation offload

2021-08-07 Thread Alexander Bulekov
On 210807 1019, Philippe Mathieu-Daudé wrote:
> On 8/7/21 12:23 AM, Alexander Bulekov wrote:
> > Encapsulation offload (offload mode 1) is a valid mode present in the
> > kernel that isn't implemented in QEMU, yet.
> > 
> > https://lore.kernel.org/lkml/20200528015426.8285-4-dos...@vmware.com/
> > 
> > Add a stub for this mode, to avoid the guest-triggerable assertion.
> > 
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/517
> > Signed-off-by: Alexander Bulekov 
> > ---
> >  hw/net/vmxnet3.c | 5 +
> >  hw/net/vmxnet3.h | 1 +
> >  2 files changed, 6 insertions(+)
> > 
> > diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
> > index 41f796a247..62e11d0e3e 100644
> > --- a/hw/net/vmxnet3.c
> > +++ b/hw/net/vmxnet3.c
> > @@ -443,6 +443,11 @@ vmxnet3_setup_tx_offloads(VMXNET3State *s)
> >  net_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
> >  break;
> >  
> > +case VMXNET3_OM_ENCAP:
> > +VMW_PKPRN("Encapsulation offload requested, but not available\n");
> > +return false;
> > +break;
> 
> No need to break if you returned (unreachable).

I included it in case the feature ends up being added, so there is one
less thing to worry about, but I can remove it. There are a couple of
places in QEMU where this occurs, so I wasn't sure about the best
practice.

-Alex

> 
> > +
> >  case VMXNET3_OM_CSUM:
> >  net_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
> >  VMW_PKPRN("L4 CSO requested\n");
> > diff --git a/hw/net/vmxnet3.h b/hw/net/vmxnet3.h
> > index 5b3b76ba7a..36a17b82aa 100644
> > --- a/hw/net/vmxnet3.h
> > +++ b/hw/net/vmxnet3.h
> > @@ -273,6 +273,7 @@ struct Vmxnet3_TxDesc {
> >  
> >  /* TxDesc.OM values */
> >  #define VMXNET3_OM_NONE0
> > +#define VMXNET3_OM_ENCAP   1
> >  #define VMXNET3_OM_CSUM2
> >  #define VMXNET3_OM_TSO3
> >  
> > 
> 



[PATCH] monitor/hmp: schedule qemu_chr_fe_accept_input() after read

2021-08-07 Thread Volker Rümelin
Since commit 584af1f1d9 (ui/gtk: add a keyboard fifo to the VTE
consoles) a GTK VTE console chardev backend relies on the
connected chardev frontend to call qemu_chr_fe_accept_input()
whenever it can receive new characters. The HMP monitor doesn't
do this. It only schedules a call to qemu_chr_fe_accept_input()
after it handled a HMP command in monitor_command_cb().

This is a problem if you paste a few characters into the GTK
monitor console. Even entering a UTF-8 multibyte character leads
to the same problem.

Schedule a call to qemu_chr_fe_accept_input() after handling the
received bytes to fix the HMP monitor.

Signed-off-by: Volker Rümelin 
---
 monitor/hmp.c  |  1 +
 monitor/monitor-internal.h |  1 +
 monitor/monitor.c  | 19 +--
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/monitor/hmp.c b/monitor/hmp.c
index d50c3124e1..470f56a71d 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1349,6 +1349,7 @@ static void monitor_read(void *opaque, const uint8_t 
*buf, int size)
 for (i = 0; i < size; i++) {
 readline_handle_byte(mon->rs, buf[i]);
 }
+monitor_accept_input(>common);
 } else {
 if (size == 0 || buf[size - 1] != 0) {
 monitor_printf(>common, "corrupted command\n");
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index 9c3a09cb01..af33c3c617 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -170,6 +170,7 @@ int monitor_puts(Monitor *mon, const char *str);
 void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
bool use_io_thread);
 void monitor_data_destroy(Monitor *mon);
+void monitor_accept_input(Monitor *mon);
 int monitor_can_read(void *opaque);
 void monitor_list_append(Monitor *mon);
 void monitor_fdsets_cleanup(void);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 46a171bca6..8e3cf4ad98 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -519,13 +519,28 @@ int monitor_suspend(Monitor *mon)
 return 0;
 }
 
-static void monitor_accept_input(void *opaque)
+static void monitor_accept_input_bh(void *opaque)
 {
 Monitor *mon = opaque;
 
 qemu_chr_fe_accept_input(>chr);
 }
 
+void monitor_accept_input(Monitor *mon)
+{
+if (!qatomic_mb_read(>suspend_cnt)) {
+AioContext *ctx;
+
+if (mon->use_io_thread) {
+ctx = iothread_get_aio_context(mon_iothread);
+} else {
+ctx = qemu_get_aio_context();
+}
+
+aio_bh_schedule_oneshot(ctx, monitor_accept_input_bh, mon);
+}
+}
+
 void monitor_resume(Monitor *mon)
 {
 if (monitor_is_hmp_non_interactive(mon)) {
@@ -547,7 +562,7 @@ void monitor_resume(Monitor *mon)
 readline_show_prompt(hmp_mon->rs);
 }
 
-aio_bh_schedule_oneshot(ctx, monitor_accept_input, mon);
+aio_bh_schedule_oneshot(ctx, monitor_accept_input_bh, mon);
 }
 
 trace_monitor_suspend(mon, -1);
-- 
2.26.2




[PATCH for 6.1 0/1] Fix chardev frontend bug in HMP

2021-08-07 Thread Volker Rümelin

Since commit 584af1f1d9 (ui/gtk: add a keyboard fifo to the VTE
consoles) a GTK VTE console chardev backend relies on the
connected chardev frontend to call qemu_chr_fe_accept_input()
whenever it can receive new characters. The HMP monitor doesn't
do this. It only schedules a call to qemu_chr_fe_accept_input()
after it handled a HMP command in monitor_command_cb().

To see the problem copy and paste the word help into the GTK VTE
monitor console. You will only see the letter h. Now press the
enter key several times. Each key press will add another letter
to the word help.

I think I need help with this patch. This is the first time I
had a closer look at the monitor code so it's quite possible my
patch is completely wrong.

Volker Rümelin (1):
  monitor/hmp: schedule qemu_chr_fe_accept_input() after read

 monitor/hmp.c  |  1 +
 monitor/monitor-internal.h |  1 +
 monitor/monitor.c  | 19 +--
 3 files changed, 19 insertions(+), 2 deletions(-)

--
2.26.2



[PATCH-for-6.1? 0/3] ps2: Fix issue #501 and #502

2021-08-07 Thread Philippe Mathieu-Daudé
On 8/7/21 2:10 PM, Volker Rümelin wrote:
> Since commit ff6e1624b3 (pckbd: don't update OBF flags if
> KBD_STAT_OBF is set) the OSes Minoca OS and Visopsys no longer
> have a working PS/2 keyboard and mouse. This is caused by a
> PS/2 queue stall due to a lost interrupt in the guest OS. This
> already happened before commit ff6e1624b3, but no one noticed
> because up to that point QEMU sent gratuitous keyboard and mouse
> interrupts and the queue restarted with keyboard input or mouse
> movement.
> 
> The lost interrupt is a guest bug. The fact that it's always
> lost is due to an inexact PS/2 keyboard emulation. The way in
> which the two operating systems e.g. set the keyboard LEDs,
> leaves a keyboard ACK reply in the keyboard queue that is
> unexpected for the guests.
> 
> This patch series improves the PS/2 keyboard emulation.
> 
> There's a workaround for issue #501 and #502 so I don't think
> this is rc3 material. But that decision is up to the maintainers.

Meanwhile, what about reverting ff6e1624b3 for 6.1?

> To verify patch 2/3 I plugged in an additional PS/2 keyboard
> into the host and started Linux with the command line option
> initcall_blacklist=i8042_init. Here is an example of the sequence
> to set the keyboard LEDs.
> 
> # #regular sequence to set the keyboard LEDs
> # inb --hex 0x64
> 1c
> # #PS/2 queue is empty
> # outb 0x60 0xed
> # inb --hex 0x64
> 15
> # inb --hex 0x60
> fa
> # inb --hex 0x64
> 14
> # outb 0x60 0x01
> # inb --hex 0x64
> 15
> # inb --hex 0x60
> fa
> # inb --hex 0x64
> 14
> 
> # #alternative sequence to set the keyboard LEDs
> # inb --hex 0x64
> 14
> # outb 0x60 0xed
> # outb 0x60 0x01
> # inb --hex 0x64
> 15
> # inb --hex 0x60
> fa
> # inb --hex 0x64
> 14
> 
> Volker Rümelin (3):
>   ps2: use the whole ps2 buffer but keep queue size
>   ps2: use a separate keyboard command reply queue
>   ps2: migration support for command reply queue
> 
>  hw/input/ps2.c | 214 ++---
>  1 file changed, 133 insertions(+), 81 deletions(-)
> 




Re: [PATCH v12] qapi: introduce 'query-x86-cpuid' QMP command.

2021-08-07 Thread Markus Armbruster
I'm afraid this needs a rebase now.  Reviewing anyway.

Valeriy Vdovin  writes:

> Introducing new QMP command 'query-x86-cpuid'. This command can be used to
> get virtualized cpu model info generated by QEMU during VM initialization in
> the form of cpuid representation.
>
> Diving into more details about virtual CPU generation: QEMU first parses 
> '-cpu'
> command line option. From there it takes the name of the model as the basis 
> for
> feature set of the new virtual CPU. After that it uses trailing '-cpu' 
> options,
> that state if additional cpu features should be present on the virtual CPU or
> excluded from it (tokens '+'/'-' or '=on'/'=off').
> After that QEMU checks if the host's cpu can actually support the derived
> feature set and applies host limitations to it.
> After this initialization procedure, virtual CPU has it's model and
> vendor names, and a working feature set and is ready for identification
> instructions such as CPUID.
>
> To learn exactly how virtual CPU is presented to the guest machine via CPUID
> instruction, new QMP command can be used. By calling 'query-x86-cpuid'
> command, one can get a full listing of all CPUID leaves with subleaves which 
> are
> supported by the initialized virtual CPU.
>
> Other than debug, the command is useful in cases when we would like to
> utilize QEMU's virtual CPU initialization routines and put the retrieved
> values into kernel CPUID overriding mechanics for more precise control
> over how various processes perceive its underlying hardware with
> container processes as a good example.
>
> The command is specific to x86. It is currenly only implemented for KVM 
> acceleator.
>
> Output format:
> The output is a plain list of leaf/subleaf argument combinations, that
> return 4 words in registers EAX, EBX, ECX, EDX.
>
> Use example:
> qmp_request: {
>   "execute": "query-x86-cpuid"
> }
>
> qmp_response: {
>   "return": [
> {
>   "eax": 1073741825,
>   "edx": 77,
>   "in-eax": 1073741824,
>   "ecx": 1447775574,
>   "ebx": 1263359563
> },
> {
>   "eax": 16777339,
>   "edx": 0,
>   "in-eax": 1073741825,
>   "ecx": 0,
>   "ebx": 0
> },
> {
>   "eax": 13,
>   "edx": 1231384169,
>   "in-eax": 0,
>   "ecx": 1818588270,
>   "ebx": 1970169159
> },
> {
>   "eax": 198354,
>   "edx": 126614527,
>   "in-eax": 1,
>   "ecx": 2176328193,
>   "ebx": 2048
> },
> 
> {
>   "eax": 12328,
>   "edx": 0,
>   "in-eax": 2147483656,
>   "ecx": 0,
>   "ebx": 0
> }
>   ]
> }
>
> Signed-off-by: Valeriy Vdovin 
> ---

[...]

> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index e7811654b7..db906c9240 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -329,3 +329,47 @@
>  ##
>  { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
>'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) 
> || defined(TARGET_S390X) || defined(TARGET_MIPS)' }
> +
> +##
> +# @CpuidEntry:
> +#
> +# A single entry of a CPUID response.
> +#
> +# One entry holds full set of information (leaf) returned to the guest
> +# in response to it calling a CPUID instruction with eax, ecx used as
> +# the agruments to that instruction. ecx is an optional argument as

Typo: arguments

> +# not all of the leaves support it.
> +#
> +# @in-eax: CPUID argument in eax
> +# @in-ecx: CPUID argument in ecx
> +# @eax: CPUID result in eax
> +# @ebx: CPUID result in ebx
> +# @ecx: CPUID result in ecx
> +# @edx: CPUID result in edx
> +#
> +# Since: 6.1
> +##
> +{ 'struct': 'CpuidEntry',
> +  'data': { 'in-eax' : 'uint32',
> +'*in-ecx' : 'uint32',
> +'eax' : 'uint32',
> +'ebx' : 'uint32',
> +'ecx' : 'uint32',
> +'edx' : 'uint32'
> +  },
> +  'if': 'defined(TARGET_I386)' }
> +
> +##
> +# @query-x86-cpuid:
> +#
> +# Returns raw data from the emulated CPUID table for the first VCPU.
> +# The emulated CPUID table defines the response to the CPUID
> +# instruction when executed by the guest operating system.
> +#
> +# Returns: a list of CpuidEntry
> +#
> +# Since: 6.1
> +##
> +{ 'command': 'query-x86-cpuid',
> +  'returns': ['CpuidEntry'],
> +  'if': 'defined(TARGET_I386)' }

I understand this fails when the acceleator isn't KVM.  I think that's
worth documenting.

Is this intended to be a stable interface?  Interfaces intended just for
debugging usually aren't.

Eduardo, what's your take on this version?




[PATCH] target/riscv: Correct a comment in riscv_csrrw()

2021-08-07 Thread Bin Meng
When privilege check fails, RISCV_EXCP_ILLEGAL_INST is returned,
not -1 (RISCV_EXCP_NONE).

Signed-off-by: Bin Meng 
---

 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9a4ed18ac5..e747fbe0e9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1423,7 +1423,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
 target_ulong old_value;
 RISCVCPU *cpu = env_archcpu(env);
 
-/* check privileges and return -1 if check fails */
+/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
 #if !defined(CONFIG_USER_ONLY)
 int effective_priv = env->priv;
 int read_only = get_field(csrno, 0xC00) == 3;
-- 
2.25.1




Re: [PATCH for-6.2 v6 7/7] memory_hotplug.c: send DEVICE_UNPLUG_ERROR in acpi_memory_hotplug_write()

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> MEM_UNPLUG_ERROR is deprecated since the introduction of
> DEVICE_UNPLUG_ERROR. Keep emitting both while the deprecation of
> MEM_UNPLUG_ERROR is pending.
>
> CC: Michael S. Tsirkin 
> CC: Igor Mammedov 
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/acpi/memory_hotplug.c | 10 ++
>  1 file changed, 10 insertions(+)
>
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index e37acb0367..a0772fe083 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -8,6 +8,7 @@
>  #include "qapi/error.h"
>  #include "qapi/qapi-events-acpi.h"
>  #include "qapi/qapi-events-machine.h"
> +#include "qapi/qapi-events-qdev.h"
>  
>  #define MEMORY_SLOTS_NUMBER  "MDNR"
>  #define MEMORY_HOTPLUG_IO_REGION "HPMR"
> @@ -181,10 +182,19 @@ static void acpi_memory_hotplug_write(void *opaque, 
> hwaddr addr, uint64_t data,
>  
>  trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);
>  
> +/*
> + * Send both MEM_UNPLUG_ERROR and DEVICE_UNPLUG_ERROR
> + * while the deprecation of MEM_UNPLUG_ERROR is
> + * pending.
> + */
>  if (dev->id) {
>  qapi_event_send_mem_unplug_error(dev->id, error_pretty);
>  }
>  
> +qapi_event_send_device_unplug_error(!!dev->id, dev->id,
> +dev->canonical_path,
> +true, error_pretty);
> +
>  error_free(local_err);
>  break;
>  }

Unlike the previous patch, "msg" is present even when !dev->id.  Makes
me doubt the previous patch's conditional passing of "msg" some more.

Reviewed-by: Markus Armbruster 




Re: [PATCH for-6.2 v6 6/7] spapr: use DEVICE_UNPLUG_ERROR to report unplug errors

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> Linux Kernel 5.12 is now unisolating CPU DRCs in the device_removal
> error path, signalling that the hotunplug process wasn't successful.
> This allow us to send a DEVICE_UNPLUG_ERROR in drc_unisolate_logical()
> to signal this error to the management layer.
>
> We also have another error path in spapr_memory_unplug_rollback() for
> configured LMB DRCs. Kernels older than 5.13 will not unisolate the LMBs
> in the hotunplug error path, but it will reconfigure them. Let's send
> the DEVICE_UNPLUG_ERROR event in that code path as well to cover the
> case of older kernels.
>
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/ppc/spapr.c |  9 -
>  hw/ppc/spapr_drc.c | 18 --
>  2 files changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 1611d7ab05..5459f9a7e9 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -29,6 +29,7 @@
>  #include "qemu/datadir.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-events-machine.h"
> +#include "qapi/qapi-events-qdev.h"
>  #include "qapi/visitor.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/hostmem.h"
> @@ -3686,13 +3687,19 @@ void spapr_memory_unplug_rollback(SpaprMachineState 
> *spapr, DeviceState *dev)
>  
>  /*
>   * Tell QAPI that something happened and the memory
> - * hotunplug wasn't successful.
> + * hotunplug wasn't successful. Keep sending
> + * MEM_UNPLUG_ERROR even while sending DEVICE_UNPLUG_ERROR
> + * until the deprecation MEM_UNPLUG_ERROR is due.
>   */
>  if (dev->id) {
>  qapi_error = g_strdup_printf("Memory hotunplug rejected by the guest 
> "
>   "for device %s", dev->id);
>  qapi_event_send_mem_unplug_error(dev->id, qapi_error);
>  }
> +
> +qapi_event_send_device_unplug_error(!!dev->id, dev->id,
> +dev->canonical_path,
> +qapi_error != NULL, qapi_error);
>  }
>  

When dev->id is null, we send something like

{"event": "DEVICE_UNPLUG_ERROR",
 "data": {"path": "/machine/..."},
 "timestamp": ...}

Unless I'm missing something, this is all the information the management
application really needs.

When dev->id is non-null, we add to "data":

  "device": "dev123",
  "msg": "Memory hotunplug rejected by the guest for device dev123",

I'm fine with emitting the device ID when we have it.

What's the intended use of "msg"?

Could DEVICE_UNPLUG_ERROR ever be emitted for this device with a
different "msg"?

If "msg" is useful when dev->id is non-null, then it's likely useful
when dev->id is null.  Why not

  "msg": "Memory hotunplug rejected by the guest",

always?

If we do that here, we'll likely do it everywhere, and then member @msg
isn't actually optional.

>  /* Callback to be called during DRC release. */
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index a4d9496f76..8f0479631f 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -17,6 +17,8 @@
>  #include "hw/ppc/spapr_drc.h"
>  #include "qom/object.h"
>  #include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qapi/qapi-events-qdev.h"
>  #include "qapi/visitor.h"
>  #include "qemu/error-report.h"
>  #include "hw/ppc/spapr.h" /* for RTAS return codes */
> @@ -160,6 +162,11 @@ static uint32_t drc_unisolate_logical(SpaprDrc *drc)
>   * means that the kernel is refusing the removal.
>   */
>  if (drc->unplug_requested && drc->dev) {
> +const char qapi_error_fmt[] = \

Drop the superfluous \

> +"Device hotunplug rejected by the guest for device %s";

Unusual indentation.

> +
> +g_autofree char *qapi_error = NULL;
> +
>  if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
>  spapr = SPAPR_MACHINE(qdev_get_machine());
>  
> @@ -169,14 +176,13 @@ static uint32_t drc_unisolate_logical(SpaprDrc *drc)
>  drc->unplug_requested = false;
>  
>  if (drc->dev->id) {
> -error_report("Device hotunplug rejected by the guest "
> - "for device %s", drc->dev->id);
> +qapi_error = g_strdup_printf(qapi_error_fmt, drc->dev->id);
> +error_report(qapi_error_fmt, drc->dev->id);

Simpler:

   qapi_error = ...
   error_report("%s", qapi_error);

Matter of taste.  Maintainer decides.

>  }
>  
> -/*
> - * TODO: send a QAPI DEVICE_UNPLUG_ERROR event when
> - * it is implemented.
> - */
> +qapi_event_send_device_unplug_error(!!drc->dev->id, drc->dev->id,
> +drc->dev->canonical_path,
> +qapi_error != NULL, 
> qapi_error);

My questions on "msg" apply.

> 

Re: [PATCH for-6.2 v6 5/7] qapi/qdev.json: add DEVICE_UNPLUG_ERROR QAPI event

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> At this moment we only provide one event to report a hotunplug error,
> MEM_UNPLUG_ERROR. As of Linux kernel 5.12 and QEMU 6.0.0, the pseries
> machine is now able to report unplug errors for other device types, such
> as CPUs.
>
> Instead of creating a (device_type)_UNPLUG_ERROR for each new device,
> create a generic DEVICE_UNPLUG_ERROR event that can be used by all
> unplug errors in the future. This event has a similar API as the
> existing DEVICE_DELETED event, with an extra optional 'msg' parameter
> that can be used to explain the reason for the error.
>
> With this new generic event, MEM_UNPLUG_ERROR is now marked as deprecated.
>
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  docs/about/deprecated.rst | 10 ++
>  qapi/machine.json |  6 +-
>  qapi/qdev.json| 30 +-
>  stubs/qdev.c  |  7 +++
>  4 files changed, 51 insertions(+), 2 deletions(-)
>
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 6d438f1c8d..c0c3431ada 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -204,6 +204,16 @@ The ``I7200`` guest CPU relies on the nanoMIPS ISA, 
> which is deprecated
>  (the ISA has never been upstreamed to a compiler toolchain). Therefore
>  this CPU is also deprecated.
>  
> +
> +QEMU API (QAPI) events
> +--
> +
> +``MEM_UNPLUG_ERROR`` (since 6.2)
> +
> +
> +Use the more generic event ``DEVICE_UNPLUG_ERROR`` instead.
> +
> +
>  System emulator machines
>  
>  
> diff --git a/qapi/machine.json b/qapi/machine.json
> index c3210ee1fb..a595c753d2 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1271,6 +1271,9 @@
>  #
>  # @msg: Informative message
>  #
> +# Features:
> +# @deprecated: This event is deprecated. Use @DEVICE_UNPLUG_ERROR instead.
> +#
>  # Since: 2.4
>  #
>  # Example:
> @@ -1283,7 +1286,8 @@
>  #
>  ##
>  { 'event': 'MEM_UNPLUG_ERROR',
> -  'data': { 'device': 'str', 'msg': 'str' } }
> +  'data': { 'device': 'str', 'msg': 'str' },
> +  'features': ['deprecated'] }
>  
>  ##
>  # @SMPConfiguration:
> diff --git a/qapi/qdev.json b/qapi/qdev.json
> index d1d3681a50..52c36c7b9c 100644
> --- a/qapi/qdev.json
> +++ b/qapi/qdev.json
> @@ -84,7 +84,9 @@
>  #This command merely requests that the guest begin the hot removal
>  #process.  Completion of the device removal process is signaled with 
> a
>  #DEVICE_DELETED event. Guest reset will automatically complete 
> removal
> -#for all devices.
> +#for all devices.  If an error in the hot removal process is 
> detected,
> +#the device will not be removed and a DEVICE_UNPLUG_ERROR event is
> +#sent.  Some errors cannot be detected.
>  #
>  # Since: 0.14
>  #
> @@ -124,3 +126,29 @@
>  ##
>  { 'event': 'DEVICE_DELETED',
>'data': { '*device': 'str', 'path': 'str' } }
> +
> +##
> +# @DEVICE_UNPLUG_ERROR:
> +#
> +# Emitted when a device hot unplug error occurs.
> +#
> +# @device: the device's ID if it has one
> +#
> +# @path: the device's path within the object model

Recommend "the device's QOM path".

> +#
> +# @msg: optional informative message

Is this useful?  I guess the remaining patches will tell.

> +#
> +# Since: 6.2
> +#
> +# Example:
> +#
> +# <- { "event": "DEVICE_UNPLUG_ERROR"
> +#  "data": { "device": "core1",
> +#"msg": "Device hotunplug rejected by the guest for device 
> core1",
> +#"path": "/machine/peripheral/core1" },
> +#  },
> +#  "timestamp": { "seconds": 1615570772, "microseconds": 202844 } }
> +#
> +##
> +{ 'event': 'DEVICE_UNPLUG_ERROR',
> +  'data': { '*device': 'str', 'path': 'str' , '*msg': 'str' } }
> diff --git a/stubs/qdev.c b/stubs/qdev.c
> index 92e6143134..ffa8f7b59e 100644
> --- a/stubs/qdev.c
> +++ b/stubs/qdev.c
> @@ -21,3 +21,10 @@ void qapi_event_send_device_deleted(bool has_device,
>  {
>  /* Nothing to do. */
>  }
> +
> +void qapi_event_send_device_unplug_error(bool has_device, const char *device,
> + const char *path,
> + bool has_msg, const char *msg)
> +{
> +/* Nothing to do. */
> +}

I'm reserving judgement on member @msg.  Other than that:
Reviewed-by: Markus Armbruster 




Re: [PATCH for-6.2 v6 1/7] hw/acpi/memory_hotplug.c: avoid sending MEM_UNPLUG_ERROR if dev->id is NULL

2021-08-07 Thread Markus Armbruster
I apologize for the not reviewing this promptly.

Daniel Henrique Barboza  writes:

> qapi_event_send_mem_unplug_error() deals with @device being NULL by
> replacing it with an empty string ("") when emitting the event. Aside
> from the fact that this is a side effect that can be patched someday,

I guess by "side effect" you allude to the output visitor's misfeature
to map null pointer to "".

> there's also the lack of utility that the event brings to listeners,
> e.g.  "a memory unplug error happened somewhere".

True.

> We're better of not emitting the event if dev->id is NULL.

On a green field, yes.  But is it worth an incompatible change now?  I
doubt it.

>Next patches
> will introduce a new device unplug error event that is better suited to
> deal with dev->id NULL scenarios. MEM_UNPLUG_ERROR will continue to be
> emitted to avoid breaking existing APIs, but it'll be deprecated and
> removed in the future.
>
> Suggested-by: Markus Armbruster 
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/acpi/memory_hotplug.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index af37889423..e37acb0367 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -177,9 +177,14 @@ static void acpi_memory_hotplug_write(void *opaque, 
> hwaddr addr, uint64_t data,
>  /* call pc-dimm unplug cb */
>  hotplug_handler_unplug(hotplug_ctrl, dev, _err);
>  if (local_err) {
> +const char *error_pretty = error_get_pretty(local_err);
> +
>  trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);
> -qapi_event_send_mem_unplug_error(dev->id,
> - 
> error_get_pretty(local_err));
> +
> +if (dev->id) {
> +qapi_event_send_mem_unplug_error(dev->id, error_pretty);
> +}
> +
>  error_free(local_err);
>  break;
>  }

Three options:

1. Make the incompatible change.  Keep this patch.  Needs a release
   note.

2. Continue to rely on the output visitor's misfeature.  Drop this
   patch.

   Relying on the misfeature is best avoided, at least in new code.

3. Make the mapping explicit here, and avoid relying on the misfeature.
   Something like the appended patch.

I don't like 1.  I think the choice between 2. and 3. depends on how it
fits with the remainder of this series.


diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index af37889423..89c411dd5c 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -178,7 +178,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr 
addr, uint64_t data,
 hotplug_handler_unplug(hotplug_ctrl, dev, _err);
 if (local_err) {
 trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);
-qapi_event_send_mem_unplug_error(dev->id,
+qapi_event_send_mem_unplug_error(dev->id ?: "",
  error_get_pretty(local_err));
 error_free(local_err);
 break;




Re: [PATCH for-6.2 v6 4/7] qapi/qdev.json: fix DEVICE_DELETED parameters doc

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> Clarify that @device is optional and that 'path' is the device
> path from QOM.
>
> This change follows Markus' suggestion verbatim, provided in full
> context here:
>
> https://lists.gnu.org/archive/html/qemu-devel/2021-07/msg01891.html
>
> Suggested-by: Markus Armbruster 
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  qapi/qdev.json | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/qapi/qdev.json b/qapi/qdev.json
> index b83178220b..d1d3681a50 100644
> --- a/qapi/qdev.json
> +++ b/qapi/qdev.json
> @@ -108,9 +108,9 @@
>  # At this point, it's safe to reuse the specified device ID. Device removal 
> can
>  # be initiated by the guest or by HMP/QMP commands.
>  #
> -# @device: device name
> +# @device: the device's ID if it has one
>  #
> -# @path: device path
> +# @path: the device's path within the object model

Recommend "the device's QOM path".

>  #
>  # Since: 1.5
>  #

Reviewed-by: Markus Armbruster 




Re: [PATCH for-6.2 v6 3/7] spapr_drc.c: do not error_report() when drc->dev->id == NULL

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> The error_report() call in drc_unisolate_logical() is not considering
> that drc->dev->id can be NULL, and the underlying functions error_report()
> calls to do its job (vprintf(), g_strdup_printf() ...) has undefined
> behavior when trying to handle "%s" with NULL arguments.
>
> Besides, there is no utility into reporting that an unknown device was
> rejected by the guest.
>
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/ppc/spapr_drc.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index a2f2634601..a4d9496f76 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -167,8 +167,11 @@ static uint32_t drc_unisolate_logical(SpaprDrc *drc)
>  }
>  
>  drc->unplug_requested = false;
> -error_report("Device hotunplug rejected by the guest "
> - "for device %s", drc->dev->id);
> +
> +if (drc->dev->id) {
> +error_report("Device hotunplug rejected by the guest "
> + "for device %s", drc->dev->id);
> +}
>  
>  /*
>   * TODO: send a QAPI DEVICE_UNPLUG_ERROR event when

This differs from PATCH 1 and 2 in that it actually fixes a crash bug.

The alternative is something like

   error_report("Device hotunplug rejected by the guest "
"for device %s", drc->dev->id ?: "");

If the maintainer is okay with dropping the message when the device has
no ID, then so am I:
Reviewed-by: Markus Armbruster 




Re: [PATCH for-6.2 v6 2/7] spapr.c: avoid sending MEM_UNPLUG_ERROR if dev->id is NULL

2021-08-07 Thread Markus Armbruster
Daniel Henrique Barboza  writes:

> As done in hw/acpi/memory_hotplug.c, avoid sending
> qapi_event_send_mem_unplug_error() if dev->id is NULL.
>
> Suggested-by: Markus Armbruster 
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/ppc/spapr.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 81699d4f8b..1611d7ab05 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3688,9 +3688,11 @@ void spapr_memory_unplug_rollback(SpaprMachineState 
> *spapr, DeviceState *dev)
>   * Tell QAPI that something happened and the memory
>   * hotunplug wasn't successful.
>   */
> -qapi_error = g_strdup_printf("Memory hotunplug rejected by the guest "
> - "for device %s", dev->id);
> -qapi_event_send_mem_unplug_error(dev->id, qapi_error);
> +if (dev->id) {
> +qapi_error = g_strdup_printf("Memory hotunplug rejected by the guest 
> "
> + "for device %s", dev->id);
> +qapi_event_send_mem_unplug_error(dev->id, qapi_error);
> +}
>  }
>  
>  /* Callback to be called during DRC release. */

My review of PATCH 1 applies.




[no subject]

2021-08-07 Thread Daniel Page
Is it possible to increase and decrease ram, cpu and also limit
bandwidth speed without shut down the guest?



Re: [PATCH 5/5] qmp: Added qemu-ebpf-rss-path command.

2021-08-07 Thread Markus Armbruster
Andrew Melnychenko  writes:

> New qmp command to query ebpf helper.
> It's crucial that qemu and helper are in sync and in touch.
> Technically helper should pass eBPF fds that qemu may accept.
> And different qemu's builds may have different eBPF programs and helpers.
> Qemu returns helper that should "fit" to virtio-net.
>
> Signed-off-by: Andrew Melnychenko 

[...]

> diff --git a/qapi/misc.json b/qapi/misc.json
> index 156f98203e..9aaf8fbcca 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -519,3 +519,36 @@
>   'data': { '*option': 'str' },
>   'returns': ['CommandLineOptionInfo'],
>   'allow-preconfig': true }
> +
> +##
> +# @HelperPath:
> +#
> +# Name of the helper and binary location.
> +##
> +{ 'struct': 'HelperPath',
> +  'data': {'name': 'str', 'path': 'str'} }
> +
> +##
> +# @query-helper-paths:
> +#
> +# Query helper paths. Initially, this command was added for
> +# qemu-ebpf-rss-helper. The qemu would check "the stamp" and
> +# returns proper helper.
> +#
> +# Returns: list of object that contains name and path for helper.
> +#
> +# Since: 6.1
> +#
> +# Example:
> +#
> +# -> { "execute": "query-helper-paths" }
> +# <- { "return": [
> +#{
> +#  "name": "qemu-ebpf-rss-helper",
> +#  "path": "/usr/local/libexec/qemu-ebpf-rss-helper"
> +#}
> +#  ]
> +#}
> +#
> +##
> +{ 'command': 'query-helper-paths', 'returns': ['HelperPath'] }


Hmm.

I understand the desire to help management applications to use the right
helper.  But I'm not sure this command is actually useful.  The helper
may or may not be installed at the path compiled into QEMU.

What happens when you use the wrong helper?

Even if we conclude this is the right approach for this helper, we still
need to review the other helpers to see which of them we should have
query-helper-paths cover.




Re: [PATCH v6 4/6] qmp: add QMP command x-debug-virtio-queue-status

2021-08-07 Thread Markus Armbruster
Jonah Palmer  writes:

> From: Laurent Vivier 
>
> This new command shows internal status of a VirtQueue.
> (vrings and indexes).
>
> Signed-off-by: Laurent Vivier 
> Signed-off-by: Jonah Palmer 

[...]

> diff --git a/qapi/virtio.json b/qapi/virtio.json
> index 78873cd..7007e0c 100644
> --- a/qapi/virtio.json
> +++ b/qapi/virtio.json
> @@ -406,3 +406,105 @@
>'data': { 'path': 'str' },
>'returns': 'VirtioStatus'
>  }
> +
> +##
> +# @VirtQueueStatus:
> +#
> +# Status of a VirtQueue
> +#
> +# @device-type: VirtIO device type
> +#
> +# @queue-index: VirtQueue queue_index
> +#
> +# @inuse: VirtQueue inuse
> +#
> +# @vring-num: VirtQueue vring.num
> +#
> +# @vring-num-default: VirtQueue vring.num_default
> +#
> +# @vring-align: VirtQueue vring.align
> +#
> +# @vring-desc: VirtQueue vring.desc
> +#
> +# @vring-avail: VirtQueue vring.avail
> +#
> +# @vring-used: VirtQueue vring.used
> +#
> +# @last-avail-idx: VirtQueue last_avail_idx
> +#
> +# @shadow-avail-idx: VirtQueue shadow_avail_idx
> +#
> +# @used-idx: VirtQueue used_idx
> +#
> +# @signalled-used: VirtQueue signalled_used
> +#
> +# @signalled-used-valid: VirtQueue signalled_used_valid
> +#
> +# Since: 6.1
> +#
> +##
> +
> +{ 'struct': 'VirtQueueStatus',
> +  'data': {
> +'device-type': 'VirtioType',
> +'queue-index': 'uint16',
> +'inuse': 'uint32',
> +'vring-num': 'int',
> +'vring-num-default': 'int',
> +'vring-align': 'int',
> +'vring-desc': 'uint64',
> +'vring-avail': 'uint64',
> +'vring-used': 'uint64',
> +'last-avail-idx': 'uint16',
> +'shadow-avail-idx': 'uint16',
> +'used-idx': 'uint16',
> +'signalled-used': 'uint16',
> +'signalled-used-valid': 'uint16'
> +  }
> +}

I can't check the member types like I did for VirtioStatus in PATCH 2
right now.  Please double-check them.

> +
> +##
> +# @x-debug-virtio-queue-status:
> +#
> +# Return the status of a given VirtQueue
> +#
> +# @path: QOBject path of the VirtIODevice
> +#
> +# @queue: queue number to examine
> +#
> +# Returns: Status of the VirtQueue
> +#
> +# Since: 6.1
> +#
> +# Example:
> +#
> +# -> { "execute": "x-debug-virtio-queue-status",
> +#  "arguments": {
> +#  "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> +#  "queue": 0
> +#  }
> +#   }
> +# <- { "return": {
> +#  "signalled-used": 373,
> +#  "inuse": 0,
> +#  "vring-align": 4096,
> +#  "vring-desc": 864411648,
> +#  "signalled-used-valid": 0,
> +#  "vring-num-default": 256,
> +#  "vring-avail": 864415744,
> +#  "queue-index": 0,
> +#  "last-avail-idx": 373,
> +#  "vring-used": 864416320,
> +#  "used-idx": 373,
> +#  "device-type": "virtio-net",
> +#  "shadow-avail-idx": 619,
> +#  "vring-num": 256
> +#  }
> +#}
> +#
> +##
> +
> +{ 'command': 'x-debug-virtio-queue-status',
> +  'data': { 'path': 'str', 'queue': 'uint16' },
> +  'returns': 'VirtQueueStatus'
> +}




Re: [PATCH v6 2/6] qmp: add QMP command x-debug-virtio-status

2021-08-07 Thread Markus Armbruster
Jonah Palmer  writes:

> From: Laurent Vivier 
>
> This new command shows the status of a VirtIODevice
> (features, endianness and number of virtqueues)
>
> Next patch will improve output by decoding feature bits.
>
> Signed-off-by: Laurent Vivier 
> Signed-off-by: Jonah Palmer 

[...]

> diff --git a/qapi/virtio.json b/qapi/virtio.json
> index 804adbe..4bd09c9 100644
> --- a/qapi/virtio.json
> +++ b/qapi/virtio.json
> @@ -70,3 +70,79 @@
>  ##
>  
>  { 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }
> +
> +##
> +# @VirtioStatusEndianness:
> +#
> +# Enumeration of endianness for VirtioDevice
> +#
> +# Since: 6.1

6.2 now, here, below, and in the remainder of this series.

> +##
> +{ 'enum': 'VirtioStatusEndianness',
> +  'data': [ 'unknown', 'little', 'big' ]
> +}
> +
> +##
> +# @VirtioStatus:
> +#
> +# @device-id: VirtIODevice status

"status"?  Really?

> +#
> +# @device-endian: VirtIODevice device_endian
> +#
> +# @guest-features: VirtIODevice guest_features
> +#
> +# @host-features: VirtIODevice host_features
> +#
> +# @backend-features: VirtIODevice backend_features
> +#
> +# @num-vqs: number of VirtIODevice queues
> +#
> +# Since: 6.1
> +#
> +##
> +
> +{ 'struct': 'VirtioStatus',
> +  'data': {
> +'device-id': 'int',

VirtIODevice member @device_id is uint64_t.  Should this be 'uint16'?

> +'device-endian': 'VirtioStatusEndianness',
> +'guest-features': 'uint64',
> +'host-features': 'uint64',
> +'backend-features': 'uint64',
> +'num-vqs': 'uint16'

virtio_get_num_queues() returns int.  Sure 'uint16' is the right type?

> +  }
> +}
> +
> +##
> +# @x-debug-virtio-status:
> +#
> +# Return the status of virtio device

"of a virtio device"

> +#
> +# @path: QOBject path of the VirtIODevice

"QOM path", please.

> +#
> +# Returns: status of the VirtIODevice
> +#
> +# Since: 6.1
> +#
> +# Example:
> +#
> +# -> { "execute": "x-debug-virtio-status",
> +#  "arguments": {
> +#  "path": "/machine/peripheral-anon/device[3]/virtio-backend"
> +#  }
> +#   }
> +# <- { "return": {
> +#  "backend-features": 0,
> +#  "guest-features": 5111807911,
> +#  "num-vqs": 3,
> +#  "host-features": 6337593319,
> +#  "device-endian": "little",
> +#  "device-id": 1
> +#  }
> +#}
> +#
> +##
> +
> +{ 'command': 'x-debug-virtio-status',
> +  'data': { 'path': 'str' },
> +  'returns': 'VirtioStatus'
> +}




[CXL Volatile MEM]: How to change the CXL persistent memory device to a volatile memory

2021-08-07 Thread Samarth Saxena
Hi All,

I am trying to modify the CXL persistent memory device, given at:
   hw/mem/cxl_type3.c
to a volatile memory device.

I tried the following:

  *   In hw/cxl/cxl-mailbox-utils.c:
 *   changed the IDENTIFY_MEMORY_DEVICE mailbox handler to return 
persistent capacity as 0, and expose entire memory as volatile.
 *   changed the IDENTIFY_MEMORY_DEVICE mailbox handler to indicate the 
lba_size as 0 in  the payload.
  *   In hw/mem/cxl_type3.c
 *   Changed function get_lsa_size to return 0.
 *   Changed function get_lsa to return 0.
 *   In the ct3_class_init function, changed the ps->class_id from 
PCI_CLASS_STORAGE_EXPRESS to PCI_CLASS_MEMORY_RAM
 *   In the ct3_class_init function, 
set_bit(DEVICE_CLASS_STORGE,dc->categories) was commented
 *   In the setup_cxl_memory function, ensured that the non-volatile flag 
is false.

Still, when I boot this setup with Kernel 5.14, I see that the device shows up 
as a persistent memory in /proc/iomem.

What else needs to be changed in the Qemu device and CXL model to support 
volatile memory?
Is volatile memory Type 3 cxl device not supported in Qemu?

I use the following command:
../build/qemu-system-x86_64 -M q35,accel=kvm,nvdimm=on -m 
8192M,slots=4,maxmem=40964M -smp 8,sockets=2,cores=2,threads=2 -hda 
/lan/dscratch/singhabh/shradha/ubuntu-20.10-64_with_orig_driver_backup.qcow2 
-enable-kvm -usbdevice tablet -L $VB_ROOT/etc/vm/common/ -object 
memory-backend-file,id=cxl-mem1,share=on,mem-path=$PWD/cxl_type_mem,size=512M 
-object 
memory-backend-file,id=cxl-lsa,share=on,mem-path=$PWD/cxl_lsa_mem,size=2M 
-device 
"pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52,uid=0,len-window-base=1,window-base[0]=0x5c000,memdev[0]=cxl-mem1"
 -device cxl-rp,id=rp0,bus=cxl.0,addr=0.0,chassis=0,slot=0 -device 
cxl-type3,bus=rp0,memdev=cxl-mem1,id=cxl-pmem0,size=256M,lsa=cxl-lsa

Regards,
[CadenceLogoRed185Regcopy1583174817new51584636989.png]
Samarth Saxena
Sr Principal Software Engineer
T: +911204308300
[UIcorrectsize1583179003.png]
[16066EmailSignatureFortune100Best2021White92x1271617625037.png]






Re: [PATCH v6 1/6] qmp: add QMP command x-debug-query-virtio

2021-08-07 Thread Markus Armbruster
QAPI schema review only.

Jonah Palmer  writes:

> From: Laurent Vivier 
>
> This new command lists all the instances of VirtIODevice with
> their path and virtio type.
>
> Signed-off-by: Laurent Vivier 
> Reviewed-by: Eric Blake 
> Signed-off-by: Jonah Palmer 

[...]

> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
> index 4912b97..0c89789 100644
> --- a/qapi/qapi-schema.json
> +++ b/qapi/qapi-schema.json
> @@ -91,5 +91,6 @@
>  { 'include': 'misc.json' }
>  { 'include': 'misc-target.json' }
>  { 'include': 'audio.json' }
> +{ 'include': 'virtio.json' }
>  { 'include': 'acpi.json' }
>  { 'include': 'pci.json' }
> diff --git a/qapi/virtio.json b/qapi/virtio.json
> new file mode 100644
> index 000..804adbe
> --- /dev/null
> +++ b/qapi/virtio.json
> @@ -0,0 +1,72 @@

Please insert at the beginning

   # -*- Mode: Python -*-
   # vim: filetype=python
   #

> +##
> +# = Virtio devices
> +##
> +
> +##
> +# @VirtioType:
> +#
> +# An enumeration of Virtio device types.
> +#
> +# Since: 6.1

6.2 now, here and below.

> +##
> +{ 'enum': 'VirtioType',
> +  'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console',
> +'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg',
> +'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan',
> +'virtio-serial', 'virtio-caif', 'virtio-memory-balloon',
> +'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock',
> +'virtio-input', 'vhost-vsock', 'virtio-crypto', 
> 'virtio-signal-dist',
> +'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25',
> +'vhost-user-fs', 'virtio-pmem', 'unknown-28', 
> 'virtio-mac80211-hwsim' ]

Please limit line length to approximately 70 characters.

> +}
> +
> +##
> +# @VirtioInfo:
> +#
> +# Information about a given VirtIODevice
> +#
> +# @path: VirtIO device canonical path.

Peeking ahead at the example, I conclude this is a QOM path.  Please
spell that out, e.g. "@path: the device's canonical QOM path".

> +#
> +# @type: VirtIO device type.
> +#
> +# Since: 6.1
> +#
> +##
> +{ 'struct': 'VirtioInfo',
> +  'data': {
> +'path': 'str',
> +'type': 'VirtioType'
> +  }
> +}
> +
> +##
> +# @x-debug-query-virtio:
> +#
> +# Return the list of all VirtIO devices
> +#
> +# Returns: list of @VirtioInfo
> +#
> +# Since: 6.1
> +#
> +# Example:
> +#
> +# -> { "execute": "x-debug-query-virtio" }
> +# <- { "return": [
> +#{
> +#"path": "/machine/peripheral-anon/device[3]/virtio-backend",
> +#"type": "virtio-net"
> +#},
> +#{
> +#"path": "/machine/peripheral-anon/device[1]/virtio-backend",
> +#"type": "virtio-serial"
> +#},
> +#{
> +#"path": "/machine/peripheral-anon/device[0]/virtio-backend",
> +#"type": "virtio-blk"
> +#}
> +#  ]
> +#}
> +#
> +##
> +
> +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] }

[...]




Re: [PATCH v3] net/macos: implement vmnet-based netdev

2021-08-07 Thread Markus Armbruster
Jason, did this fall through the cracks?

My review is for the QAPI schema only.

Akihiko Odaki  writes:

> From: Phillip Tennen 
>
> This patch implements a new netdev device, reachable via -netdev
> vmnet-macos, that’s backed by macOS’s vmnet framework.
>
> The vmnet framework provides native bridging support, and its usage in
> this patch is intended as a replacement for attempts to use a tap device
> via the tuntaposx kernel extension. Notably, the tap/tuntaposx approach
> never would have worked in the first place, as QEMU interacts with the
> tap device via poll(), and macOS does not support polling device files.
>
> vmnet requires either a special entitlement, granted via a provisioning
> profile, or root access. Otherwise attempts to create the virtual
> interface will fail with a “generic error” status code. QEMU may not
> currently be signed with an entitlement granted in a provisioning
> profile, as this would necessitate pre-signed binary build distribution,
> rather than source-code distribution. As such, using this netdev
> currently requires that qemu be run with root access. I’ve opened a
> feedback report with Apple to allow the use of the relevant entitlement
> with this use case:
> https://openradar.appspot.com/radar?id=5007417364447232
>
> vmnet offers three operating modes, all of which are supported by this
> patch via the “mode=host|shared|bridge” option:
>
> * "Host" mode: Allows the vmnet interface to communicate with other
> * vmnet
> interfaces that are in host mode and also with the native host.
> * "Shared" mode: Allows traffic originating from the vmnet interface to
> reach the Internet through a NAT. The vmnet interface can also
> communicate with the native host.
> * "Bridged" mode: Bridges the vmnet interface with a physical network
> interface.
>
> Each of these modes also provide some extra configuration that’s
> supported by this patch:
>
> * "Bridged" mode: The user may specify the physical interface to bridge
> with. Defaults to en0.
> * "Host" mode / "Shared" mode: The user may specify the DHCP range and
> subnet. Allocated by vmnet if not provided.
>
> vmnet also offers some extra configuration options that are not
> supported by this patch:
>
> * Enable isolation from other VMs using vmnet
> * Port forwarding rules
> * Enabling TCP segmentation offload
> * Only applicable in "shared" mode: specifying the NAT IPv6 prefix
> * Only available in "host" mode: specifying the IP address for the VM
> within an isolated network
>
> Note that this patch requires macOS 10.15 as a minimum, as this is when
> bridging support was implemented in vmnet.framework.
>
> Rebased to commit 9aef0954195cc592e86846dbbe7f3c2c5603690a by Akihiko
> Odaki.
>
> Signed-off-by: Phillip Tennen 
> Signed-off-by: Akihiko Odaki 
> Message-Id: <20210315103209.20870-1-akihiko.od...@gmail.com>

[...]

> diff --git a/qapi/net.json b/qapi/net.json
> index 7fab2e7cd8a..e3b67f174fc 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -452,6 +452,115 @@
>  '*vhostdev': 'str',
>  '*queues':   'int' } }
>  
> +##
> +# @VmnetOperatingMode:
> +#
> +# The operating modes in which a vmnet netdev can run
> +# Only available on macOS

Generated qemu-qmp-ref.7 and .html show this as

The operating modes in which a vmnet netdev can run Only available
on macOS

Please end your sentences with periods :)

More of the same below.  Proof-reading the generated documentation is
always a good idea, and often forgotten (I've been guilty of that, too).

> +#
> +# @host: the guest may communicate with the host
> +#and other guest network interfaces
> +#
> +# @shared: the guest may reach the Internet through a NAT,

Scratch "a"?

> +#  and may communicate with the host and other guest
> +#  network interfaces
> +#
> +# @bridged: the guest's traffic is bridged with a
> +#   physical network interface of the host

"bridged width" or "bridged to"?  I'm not a networking guy...

> +#
> +# Since: 6.0

6.2

> +##
> +{ 'enum': 'VmnetOperatingMode',
> +  'data': [ 'host', 'shared', 'bridged' ],
> +  'if': 'defined(CONFIG_VMNET)' }

I suspect we want 'defined(CONFIG_VMNET) && defined(CONFIG_DARWIN)',
here and below.

> +
> +##
> +# @NetdevVmnetModeOptionsBridged:
> +#
> +# Options for the vmnet-macos netdev
> +# that are only available in 'bridged' mode
> +# Only available on macOS
> +#
> +# @ifname: the physical network interface to bridge with
> +#  (defaults to en0 if not specified)

Scratch " if not specified".

> +#
> +# Since: 6.0
> +##
> +{ 'struct': 'NetdevVmnetModeOptionsBridged',
> +  'data': { '*ifname':  'str' },
> +  'if': 'defined(CONFIG_VMNET)' }
> +
> +##
> +# @NetdevVmnetModeOptionsHostOrShared:
> +#
> +# Options for the vmnet-macos netdev
> +# that are only available in 'host' or 'shared' mode
> +# Only available on macOS
> +#
> +# @dhcp-start-address: the gateway address to use for the interface.
> +#  The range to dhcp_end_address is 

ps2: Fix issue #501 and #502

2021-08-07 Thread Volker Rümelin

Since commit ff6e1624b3 (pckbd: don't update OBF flags if
KBD_STAT_OBF is set) the OSes Minoca OS and Visopsys no longer
have a working PS/2 keyboard and mouse. This is caused by a
PS/2 queue stall due to a lost interrupt in the guest OS. This
already happened before commit ff6e1624b3, but no one noticed
because up to that point QEMU sent gratuitous keyboard and mouse
interrupts and the queue restarted with keyboard input or mouse
movement.

The lost interrupt is a guest bug. The fact that it's always
lost is due to an inexact PS/2 keyboard emulation. The way in
which the two operating systems e.g. set the keyboard LEDs,
leaves a keyboard ACK reply in the keyboard queue that is
unexpected for the guests.

This patch series improves the PS/2 keyboard emulation.

There's a workaround for issue #501 and #502 so I don't think
this is rc3 material. But that decision is up to the maintainers.

To verify patch 2/3 I plugged in an additional PS/2 keyboard
into the host and started Linux with the command line option
initcall_blacklist=i8042_init. Here is an example of the sequence
to set the keyboard LEDs.

# #regular sequence to set the keyboard LEDs
# inb --hex 0x64
1c
# #PS/2 queue is empty
# outb 0x60 0xed
# inb --hex 0x64
15
# inb --hex 0x60
fa
# inb --hex 0x64
14
# outb 0x60 0x01
# inb --hex 0x64
15
# inb --hex 0x60
fa
# inb --hex 0x64
14

# #alternative sequence to set the keyboard LEDs
# inb --hex 0x64
14
# outb 0x60 0xed
# outb 0x60 0x01
# inb --hex 0x64
15
# inb --hex 0x60
fa
# inb --hex 0x64
14

Volker Rümelin (3):
  ps2: use the whole ps2 buffer but keep queue size
  ps2: use a separate keyboard command reply queue
  ps2: migration support for command reply queue

 hw/input/ps2.c | 214 ++---
 1 file changed, 133 insertions(+), 81 deletions(-)

--
2.26.2



[PATCH 1/3] ps2: use the whole ps2 buffer but keep queue size

2021-08-07 Thread Volker Rümelin
Extend the used ps2 buffer size to the available buffer size but
keep the maximum ps2 queue size.

The next patch needs a few bytes of the larger buffer size.

Signed-off-by: Volker Rümelin 
---
 hw/input/ps2.c | 69 +++---
 1 file changed, 20 insertions(+), 49 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 8dd482c1f6..23e7befee5 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -74,7 +74,12 @@
 #define MOUSE_STATUS_ENABLED0x20
 #define MOUSE_STATUS_SCALE210x10
 
-#define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
+/*
+ * PS/2 buffer size. Keep 256 bytes for compatibility with
+ * older QEMU versions.
+ */
+#define PS2_BUFFER_SIZE 256
+#define PS2_QUEUE_SIZE  16  /* Queue size required by PS/2 protocol */
 
 /* Bits for 'modifiers' field in PS2KbdState */
 #define MOD_CTRL_L  (1 << 0)
@@ -85,9 +90,7 @@
 #define MOD_ALT_R   (1 << 5)
 
 typedef struct {
-/* Keep the data array 256 bytes long, which compatibility
- with older qemu versions. */
-uint8_t data[256];
+uint8_t data[PS2_BUFFER_SIZE];
 int rptr, wptr, count;
 } PS2Queue;
 
@@ -200,8 +203,9 @@ void ps2_queue_noirq(PS2State *s, int b)
 }
 
 q->data[q->wptr] = b;
-if (++q->wptr == PS2_QUEUE_SIZE)
+if (++q->wptr == PS2_BUFFER_SIZE) {
 q->wptr = 0;
+}
 q->count++;
 }
 
@@ -509,13 +513,15 @@ uint32_t ps2_read_data(PS2State *s)
(needed for EMM386) */
 /* XXX: need a timer to do things correctly */
 index = q->rptr - 1;
-if (index < 0)
-index = PS2_QUEUE_SIZE - 1;
+if (index < 0) {
+index = PS2_BUFFER_SIZE - 1;
+}
 val = q->data[index];
 } else {
 val = q->data[q->rptr];
-if (++q->rptr == PS2_QUEUE_SIZE)
+if (++q->rptr == PS2_BUFFER_SIZE) {
 q->rptr = 0;
+}
 q->count--;
 /* reading deasserts IRQ */
 s->update_irq(s->update_arg, 0);
@@ -926,30 +932,17 @@ static void ps2_common_reset(PS2State *s)
 static void ps2_common_post_load(PS2State *s)
 {
 PS2Queue *q = >queue;
-uint8_t i, size;
-uint8_t tmp_data[PS2_QUEUE_SIZE];
 
-/* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
-size = q->count;
+/* set the useful data buffer queue size <= PS2_QUEUE_SIZE */
 if (q->count < 0) {
-size = 0;
+q->count = 0;
 } else if (q->count > PS2_QUEUE_SIZE) {
-size = PS2_QUEUE_SIZE;
-}
-
-/* move the queue elements to the start of data array */
-for (i = 0; i < size; i++) {
-if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
-q->rptr = 0;
-}
-tmp_data[i] = q->data[q->rptr++];
+q->count = PS2_QUEUE_SIZE;
 }
-memcpy(q->data, tmp_data, size);
 
-/* reset rptr/wptr/count */
-q->rptr = 0;
-q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
-q->count = size;
+/* sanitize rptr and recalculate wptr */
+q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
+q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
 }
 
 static void ps2_kbd_reset(void *opaque)
@@ -1053,22 +1046,11 @@ static int ps2_kbd_post_load(void* opaque, int 
version_id)
 return 0;
 }
 
-static int ps2_kbd_pre_save(void *opaque)
-{
-PS2KbdState *s = (PS2KbdState *)opaque;
-PS2State *ps2 = >common;
-
-ps2_common_post_load(ps2);
-
-return 0;
-}
-
 static const VMStateDescription vmstate_ps2_keyboard = {
 .name = "ps2kbd",
 .version_id = 3,
 .minimum_version_id = 2,
 .post_load = ps2_kbd_post_load,
-.pre_save = ps2_kbd_pre_save,
 .fields = (VMStateField[]) {
 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
 VMSTATE_INT32(scan_enabled, PS2KbdState),
@@ -1093,22 +1075,11 @@ static int ps2_mouse_post_load(void *opaque, int 
version_id)
 return 0;
 }
 
-static int ps2_mouse_pre_save(void *opaque)
-{
-PS2MouseState *s = (PS2MouseState *)opaque;
-PS2State *ps2 = >common;
-
-ps2_common_post_load(ps2);
-
-return 0;
-}
-
 static const VMStateDescription vmstate_ps2_mouse = {
 .name = "ps2mouse",
 .version_id = 2,
 .minimum_version_id = 2,
 .post_load = ps2_mouse_post_load,
-.pre_save = ps2_mouse_pre_save,
 .fields = (VMStateField[]) {
 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
 VMSTATE_UINT8(mouse_status, PS2MouseState),
-- 
2.26.2




[PATCH 2/3] ps2: use a separate keyboard command reply queue

2021-08-07 Thread Volker Rümelin
A PS/2 keyboard has a separate command reply queue that is
independant of the key queue. This prevents that command replies
and keyboard input mix. Keyboard command replies take precedence
over queued keystrokes. A new keyboard command removes any
remaining command replies from the command reply queue.

Implement a separate keyboard command reply queue and clear the
command reply queue before command execution. This brings the
PS/2 keyboard emulation much closer to a real PS/2 keyboard.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/501
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/502
Signed-off-by: Volker Rümelin 
---
 hw/input/ps2.c | 115 -
 1 file changed, 84 insertions(+), 31 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 23e7befee5..8c06fd7fb4 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -91,7 +91,7 @@
 
 typedef struct {
 uint8_t data[PS2_BUFFER_SIZE];
-int rptr, wptr, count;
+int rptr, wptr, cwptr, count;
 } PS2Queue;
 
 struct PS2State {
@@ -186,6 +186,7 @@ static void ps2_reset_queue(PS2State *s)
 
 q->rptr = 0;
 q->wptr = 0;
+q->cwptr = -1;
 q->count = 0;
 }
 
@@ -198,7 +199,7 @@ void ps2_queue_noirq(PS2State *s, int b)
 {
 PS2Queue *q = >queue;
 
-if (q->count == PS2_QUEUE_SIZE) {
+if (q->count >= PS2_QUEUE_SIZE) {
 return;
 }
 
@@ -260,6 +261,63 @@ void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int 
b4)
 ps2_raise_irq(s);
 }
 
+static void ps2_cqueue_data(PS2Queue *q, int b)
+{
+q->data[q->cwptr] = b;
+if (++q->cwptr >= PS2_BUFFER_SIZE) {
+q->cwptr = 0;
+}
+q->count++;
+}
+
+static void ps2_cqueue_1(PS2State *s, int b1)
+{
+PS2Queue *q = >queue;
+
+q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
+q->cwptr = q->rptr;
+ps2_cqueue_data(q, b1);
+ps2_raise_irq(s);
+}
+
+static void ps2_cqueue_2(PS2State *s, int b1, int b2)
+{
+PS2Queue *q = >queue;
+
+q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
+q->cwptr = q->rptr;
+ps2_cqueue_data(q, b1);
+ps2_cqueue_data(q, b2);
+ps2_raise_irq(s);
+}
+
+static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
+{
+PS2Queue *q = >queue;
+
+q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
+q->cwptr = q->rptr;
+ps2_cqueue_data(q, b1);
+ps2_cqueue_data(q, b2);
+ps2_cqueue_data(q, b3);
+ps2_raise_irq(s);
+}
+
+static void ps2_cqueue_reset(PS2State *s)
+{
+PS2Queue *q = >queue;
+int ccount;
+
+if (q->cwptr == -1) {
+return;
+}
+
+ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
+q->count -= ccount;
+q->rptr = q->cwptr;
+q->cwptr = -1;
+}
+
 /* keycode is the untranslated scancode in the current scancode set. */
 static void ps2_put_keycode(void *opaque, int keycode)
 {
@@ -523,6 +581,10 @@ uint32_t ps2_read_data(PS2State *s)
 q->rptr = 0;
 }
 q->count--;
+if (q->rptr == q->cwptr) {
+/* command reply queue is empty */
+q->cwptr = -1;
+}
 /* reading deasserts IRQ */
 s->update_irq(s->update_arg, 0);
 /* reassert IRQs if data left */
@@ -554,92 +616,83 @@ void ps2_write_keyboard(void *opaque, int val)
 PS2KbdState *s = (PS2KbdState *)opaque;
 
 trace_ps2_write_keyboard(opaque, val);
+ps2_cqueue_reset(>common);
 switch(s->common.write_cmd) {
 default:
 case -1:
 switch(val) {
 case 0x00:
-ps2_queue(>common, KBD_REPLY_ACK);
+ps2_cqueue_1(>common, KBD_REPLY_ACK);
 break;
 case 0x05:
-ps2_queue(>common, KBD_REPLY_RESEND);
+ps2_cqueue_1(>common, KBD_REPLY_RESEND);
 break;
 case KBD_CMD_GET_ID:
 /* We emulate a MF2 AT keyboard here */
-if (s->translate)
-ps2_queue_3(>common,
-KBD_REPLY_ACK,
-KBD_REPLY_ID,
-0x41);
-else
-ps2_queue_3(>common,
-KBD_REPLY_ACK,
-KBD_REPLY_ID,
-0x83);
+ps2_cqueue_3(>common, KBD_REPLY_ACK, KBD_REPLY_ID,
+s->translate ? 0x41 : 0x83);
 break;
 case KBD_CMD_ECHO:
-ps2_queue(>common, KBD_CMD_ECHO);
+ps2_cqueue_1(>common, KBD_CMD_ECHO);
 break;
 case KBD_CMD_ENABLE:
 s->scan_enabled = 1;
-ps2_queue(>common, KBD_REPLY_ACK);
+ps2_cqueue_1(>common, KBD_REPLY_ACK);
 break;
 case KBD_CMD_SCANCODE:
 case KBD_CMD_SET_LEDS:
 case KBD_CMD_SET_RATE:
 case KBD_CMD_SET_MAKE_BREAK:
 s->common.write_cmd = val;
-ps2_queue(>common, KBD_REPLY_ACK);
+ps2_cqueue_1(>common, KBD_REPLY_ACK);
 break;
 case KBD_CMD_RESET_DISABLE:
 

[PATCH 3/3] ps2: migration support for command reply queue

2021-08-07 Thread Volker Rümelin
Add migration support for the PS/2 keyboard command reply queue.

Signed-off-by: Volker Rümelin 
---
 hw/input/ps2.c | 40 ++--
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 8c06fd7fb4..9376a8f4ce 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -80,6 +80,7 @@
  */
 #define PS2_BUFFER_SIZE 256
 #define PS2_QUEUE_SIZE  16  /* Queue size required by PS/2 protocol */
+#define PS2_QUEUE_HEADROOM  8   /* Queue size for keyboard command replies */
 
 /* Bits for 'modifiers' field in PS2KbdState */
 #define MOD_CTRL_L  (1 << 0)
@@ -985,17 +986,27 @@ static void ps2_common_reset(PS2State *s)
 static void ps2_common_post_load(PS2State *s)
 {
 PS2Queue *q = >queue;
+int ccount = 0;
 
-/* set the useful data buffer queue size <= PS2_QUEUE_SIZE */
-if (q->count < 0) {
-q->count = 0;
-} else if (q->count > PS2_QUEUE_SIZE) {
-q->count = PS2_QUEUE_SIZE;
+/* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
+if (q->cwptr != -1) {
+ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
+if (ccount > PS2_QUEUE_HEADROOM) {
+ccount = PS2_QUEUE_HEADROOM;
+}
+}
+
+/* limit the scancode queue size to PS2_QUEUE_SIZE */
+if (q->count < ccount) {
+q->count = ccount;
+} else if (q->count > ccount + PS2_QUEUE_SIZE) {
+q->count = ccount + PS2_QUEUE_SIZE;
 }
 
-/* sanitize rptr and recalculate wptr */
+/* sanitize rptr and recalculate wptr and cwptr */
 q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
 q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
+q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
 }
 
 static void ps2_kbd_reset(void *opaque)
@@ -1086,6 +1097,22 @@ static const VMStateDescription 
vmstate_ps2_keyboard_need_high_bit = {
 }
 };
 
+static bool ps2_keyboard_cqueue_needed(void *opaque)
+{
+PS2KbdState *s = opaque;
+
+return s->common.queue.cwptr != -1; /* the queue is mostly empty */
+}
+
+static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
+.name = "ps2kbd/command_reply_queue",
+.needed = ps2_keyboard_cqueue_needed,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(common.queue.cwptr, PS2KbdState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static int ps2_kbd_post_load(void* opaque, int version_id)
 {
 PS2KbdState *s = (PS2KbdState*)opaque;
@@ -1114,6 +1141,7 @@ static const VMStateDescription vmstate_ps2_keyboard = {
 .subsections = (const VMStateDescription*[]) {
 _ps2_keyboard_ledstate,
 _ps2_keyboard_need_high_bit,
+_ps2_keyboard_cqueue,
 NULL
 }
 };
-- 
2.26.2




Re: [PULL V3 for 6.2 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough

2021-08-07 Thread Markus Armbruster
Markus Armbruster  writes:

> I see Jason queued this while I was failing at keeping up with review.
> I apologize for dropping the ball.
>
> There still are a few unresolved issues I raised in prior review.  The
> documentation is not ready, and there is no consensus on the design of
> passthrough-filter-del.
>
> If we merge this as is for 6.2, then I want my review to be addressed on
> top.

One more thing...

> Zhang Chen  writes:
>
>> Since the real user scenario does not need to monitor all traffic.
>> Add passthrough-filter-add and passthrough-filter-del to maintain
>> a network passthrough list in object with network packet processing
>> function. Add IPFlowSpec struct for all QMP commands.
>> Most the fields of IPFlowSpec are optional,except object-name.
>>
>> Signed-off-by: Zhang Chen 
>> ---
>
> [...]
>
>> diff --git a/qapi/net.json b/qapi/net.json
>> index 7fab2e7cd8..bfe38faab5 100644
>> --- a/qapi/net.json
>> +++ b/qapi/net.json
>> @@ -7,6 +7,7 @@
>>  ##
>>  
>>  { 'include': 'common.json' }
>> +{ 'include': 'sockets.json' }
>>  
>>  ##
>>  # @set_link:
>> @@ -696,3 +697,80 @@
>>  ##
>>  { 'event': 'FAILOVER_NEGOTIATED',
>>'data': {'device-id': 'str'} }
>> +
>> +##
>> +# @IPFlowSpec:
>> +#
>> +# IP flow specification.
>> +#
>> +# @protocol: Transport layer protocol like TCP/UDP, etc. The protocol is the
>> +#string instead of enum, because it can be passed to 
>> getprotobyname(3)
>> +#and avoid duplication with /etc/protocols.
>
> In review of v8, I wrote:
>
> The rationale is good, but it doesn't really belong into the interface
> documentation.  Suggest:
>
># @protocol: Transport layer protocol like TCP/UDP, etc.  This will be
>#passed to getprotobyname(3).
>
> to which you replied "OK."  Please apply the change.
>
>> +#
>> +# @object-name: The @object-name means a qemu object with network packet
>> +#   processing function, for example colo-compare, 
>> filtr-redirector
>> +#   filtr-mirror, etc. VM can running with multi network packet
>
> s/qemu/QEMU/
>
> s/filtr/filter/ two times here, and more below.
>
> s/VM/The VM/
>
> s/multi/multiple/
>
> Also, limit doc comment line length to 70 characters or so.
>
>> +#   processing function objects. They can control different 
>> network
>> +#   data paths from netdev or chardev. So it needs the 
>> object-name
>> +#   to set the effective module.
>
> Again, this is rationale, which doesn't really belong here.
>
> What does belong here, but isn't: meaning of @object-name, i.e. how it
> is resolved to a "qemu object with network packet processing function",
> whatever that is.
>
> I'm *guessing* it's the QOM path of a QOM object that provides a certain
> interface.  Correct?
>
> If yes, which interface exactly?  Is it a QOM interface?
>
> The comment could then look like
>
>   # QOM path to a QOM object that implements the MUMBLE interface.
>
> with the details corrected / fleshed out.
>
>> +#
>> +# @source: Source address and port.
>> +#
>> +# @destination: Destination address and port.
>> +#
>> +# Since: 6.1

6.2 now.  More of the same below.

[...]




  1   2   >