Re: [PATCH] qemu-thread: avoid false positive in pthread_cleanup_push

2021-09-07 Thread Paolo Bonzini

On 07/09/21 16:20, Richard Henderson wrote:

On 9/7/21 2:51 PM, Paolo Bonzini wrote:

+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
  pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
+#pragma GCC diagnostic pop


I had a patch for this that didn't quite get applied for 6.1.
You can't leave the pragma unprotected for clang, unfortunately.

https://patchew.org/QEMU/20210803211907.150525-1-richard.hender...@linaro.org/ 


Thanks!  I queued your patch instead of mine.

Paolo




Re: [PATCH v2 3/3] target/riscv: Set mtval and stval support

2021-09-07 Thread Bin Meng
On Wed, Sep 8, 2021 at 12:55 PM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/cpu.h | 1 +
>  target/riscv/cpu.c | 6 +-
>  2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d11db1f031..5b0bbf2fca 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -309,6 +309,7 @@ struct RISCVCPU {
>  bool mmu;
>  bool pmp;
>  bool epmp;
> +bool mtval_inst;
>  uint64_t resetvec;
>  } cfg;
>  };
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1a2b03d579..537f2af341 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -437,6 +437,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  }
>  }
>
> +if (cpu->cfg.mtval_inst) {
> +set_feature(env, RISCV_FEATURE_MTVAL_INST);
> +}
> +
>  set_resetvec(env, cpu->cfg.resetvec);
>
>  /* If only XLEN is set for misa, then set misa from properties */
> @@ -600,7 +604,7 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
>  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
>  DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
> -
> +DEFINE_PROP_BOOL("tval-inst", RISCVCPU, cfg.mtval_inst, true),

Should we tweak such on a per-CPU basis instead of globally enabling
it, e.g.: update sifive_u54 per the real hardware implementation?

>  DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>

Regards,
Bin



Re: [PATCH v2 2/3] target/riscv: Implement the stval/mtval illegal instruction

2021-09-07 Thread Bin Meng
On Wed, Sep 8, 2021 at 12:54 PM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> The stval and mtval registers can optionally contain the faulting
> instruction on an illegal instruction exception. This patch adds support
> for setting the stval and mtval registers based on the CPU feature.
>
> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/cpu.h|  5 -
>  target/riscv/cpu_helper.c | 10 ++
>  target/riscv/translate.c  | 31 +--
>  3 files changed, 31 insertions(+), 15 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH] fuzz: fix unbound variable in build.sh

2021-09-07 Thread Thomas Huth

On 07/09/2021 14.51, Alexander Bulekov wrote:

On 210907 1432, Thomas Huth wrote:

On 07/09/2021 13.08, Alexander Bulekov wrote:

/src/build.sh: line 76: GITLAB_CI: unbound variable
Fix that.

Signed-off-by: Alexander Bulekov 
---

This change is in preparation to revert:
7602748c ("qemu: manually build glib (#5919)") on OSS-Fuzz.
Reverting as-is produces an unbound variable complaint when we try to
build the fuzzers in the OSS-Fuzz container.

   scripts/oss-fuzz/build.sh | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/oss-fuzz/build.sh b/scripts/oss-fuzz/build.sh
index 98b56e0521..5ddc769c9c 100755
--- a/scripts/oss-fuzz/build.sh
+++ b/scripts/oss-fuzz/build.sh
@@ -73,7 +73,7 @@ if ! make "-j$(nproc)" qemu-fuzz-i386; then
 "\nFor example: CC=clang CXX=clang++ $0"
   fi
-if [ "$GITLAB_CI" != "true" ]; then
+if [ -z ${GITLAB_CI+x} ]; then


My bash-foo is really not the best, but shouldn't there be a colon in there,
i.e. ${GITLAB_CI:+x} ?


I think the difference is that GITLAB_CI+x only checks if GITLAB_CI is
set, while GITLAB_CI:+x checks that it is set and non-null.
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

I don't think that makes much of a difference here.


TIL, and I agree that it does not make a difference here (and if it would, 
your variant is certainly better).


Reviewed-by: Thomas Huth 




Re: [PATCH] meson: look up cp and dtrace with find_program()

2021-09-07 Thread Paolo Bonzini

On 07/09/21 21:06, Marc-André Lureau wrote:

Hi

On Tue, Sep 7, 2021 at 9:27 PM Paolo Bonzini > wrote:


Avoid that meson prints a "Program xyz found" test once per
custom_target.

Signed-off-by: Paolo Bonzini mailto:pbonz...@redhat.com>>


Reviewed-by: Marc-André Lureau 

Is there a meson bug already?


I don't think it's a bug.  It also prints the message a lot if the 
program is a Python installation however, and that is a bug that I'll 
look into later today.


Paolo




Re: [PATCH] fw_cfg: add etc/msr_feature_control

2021-09-07 Thread Paolo Bonzini

On 07/09/21 20:19, Philippe Mathieu-Daudé wrote:

Fixes: 217f1b4a721 ("target-i386: Publish advised value of
MSR_IA32_FEATURE_CONTROL via fw_cfg")


Yes, thanks.

Paolo




Re: [PATCH] ebpf: only include in system emulators

2021-09-07 Thread Paolo Bonzini

On 08/09/21 05:08, Jason Wang wrote:


在 2021/9/7 下午6:45, Paolo Bonzini 写道:

eBPF files are being included in system emulators, which is useless



I think it should work since it's an independent feature. The current 
use case is to offload the RSS from Qemu to kernel TAP.


Sorry, I meant "user emulators".  That should make more sense, they 
don't have TAP at all.


Paolo




Re: [PATCH v2 1/3] target/riscv: Set the opcode in DisasContext

2021-09-07 Thread Bin Meng
On Wed, Sep 8, 2021 at 12:54 PM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/translate.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v10 15/16] target/riscv: Remove RVB (replaced by Zb[abcs])

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:53 AM Philipp Tomsich  wrote:
>
> With everything classified as Zb[abcs] and pre-0.93 draft-B
> instructions that are not part of Zb[abcs] removed, we can remove the
> remaining support code for RVB.
>
> Note that RVB has been retired for good and misa.B will neither mean
> 'some' or 'all of' Zb*:
>   https://lists.riscv.org/g/tech-bitmanip/message/532
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Removing RVB moved into a separate commit at the tail-end of the series.
>
>  target/riscv/cpu.c | 26 --
>  target/riscv/cpu.h |  3 ---
>  target/riscv/insn32.decode |  4 
>  3 files changed, 33 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v10 12/16] target/riscv: Add a REQUIRE_32BIT macro

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:47 AM Philipp Tomsich  wrote:
>
> With the changes to Zb[abcs], there's some encodings that are
> different in RV64 and RV32 (e.g., for rev8 and zext.h). For these,
> we'll need a helper macro allowing us to select on RV32, as well.
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Moved the REQUIRE_32BIT macro into a separate commit.
>
>  target/riscv/translate.c | 6 ++
>  1 file changed, 6 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH v10 10/16] target/riscv: Reassign instructions to the Zbb-extension

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:38 AM Philipp Tomsich  wrote:
>
> This reassigns the instructions that are part of Zbb into it, with the
> notable exceptions of the instructions (rev8, zext.w and orc.b) that
> changed due to gorci, grevi and pack not being part of Zb[abcs].
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - The changes to the Zbb instructions (i.e. use the REQUIRE_ZBB macro)
>   are now in a separate commit.
>
>  target/riscv/insn32.decode  | 40 ++-
>  target/riscv/insn_trans/trans_rvb.c.inc | 51 ++---
>  2 files changed, 50 insertions(+), 41 deletions(-)
>

Acked-by: Bin Meng 



Re: [PATCH v10 05/16] target/riscv: Reassign instructions to the Zba-extension

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:38 AM Philipp Tomsich  wrote:
>
> The following instructions are part of Zba:
>  - add.uw (RV64 only)
>  - sh[123]add (RV32 and RV64)
>  - sh[123]add.uw (RV64-only)
>  - slli.uw (RV64-only)
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> Changes in v10:
> - Split off gen_add_uw() fix into a separate patch, as requested.
>
> Changes in v9:
> - Rebased to 8880cc4362.
> - Update gen_add_uw() to use a temporary instead of messing with
>   arg1 (fixes a regression after rebase on CF3 and SPEC2017).
>
> Changes in v3:
> - The changes to the Zba instructions (i.e. the REQUIRE_ZBA macro
>   and its use for qualifying the Zba instructions) are moved into
>   a separate commit.
>
>  target/riscv/insn32.decode  | 20 
>  target/riscv/insn_trans/trans_rvb.c.inc | 16 +++-
>  2 files changed, 23 insertions(+), 13 deletions(-)
>

Acked-by: Bin Meng 



Re: [PATCH v10 08/16] target/riscv: Reassign instructions to the Zbs-extension

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:43 AM Philipp Tomsich  wrote:
>
> The following instructions are part of Zbs:
>  - b{set,clr,ext,inv}
>  - b{set,clr,ext,inv}i
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - The changes to the Zbs instructions (i.e. the REQUIRE_ZBS macro) and
>   its use for qualifying the Zba instructions) are moved into a
>   separate commit.
>
>  target/riscv/insn32.decode  | 17 +
>  target/riscv/insn_trans/trans_rvb.c.inc | 25 +++--
>  2 files changed, 24 insertions(+), 18 deletions(-)
>

Acked-by: Bin Meng 



Re: [PATCH v10 07/16] target/riscv: Remove shift-one instructions (proposed Zbo in pre-0.93 draft-B)

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:40 AM Philipp Tomsich  wrote:
>
> The Zb[abcs] ratification package does not include the proposed
> shift-one instructions. There currently is no clear plan to whether
> these (or variants of them) will be ratified as Zbo (or a different
> extension) or what the timeframe for such a decision could be.
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Remove shift-one instructions in a separate commit.
>
>  target/riscv/insn32.decode  |  8 ---
>  target/riscv/insn_trans/trans_rvb.c.inc | 70 -
>  2 files changed, 78 deletions(-)
>

Acked-by: Bin Meng 



Re: [PATCH v10 06/16] target/riscv: Remove the W-form instructions from Zbs

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:49 AM Philipp Tomsich  wrote:
>
> Zbs 1.0.0 (just as the 0.93 draft-B before) does no provide for W-form

does not

> instructions for Zbs (single-bit instructions).  Remove them.
>
> Note that these instructions had already been removed for the 0.93
> version of the draft-B extenstion and have not been present in the

extension

> binutils patches circulating in January 2021.
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Remove the W-form instructions from Zbs in a separate commit.
>
>  target/riscv/insn32.decode  |  7 
>  target/riscv/insn_trans/trans_rvb.c.inc | 56 -
>  2 files changed, 63 deletions(-)
>

Otherwise,
Acked-by: Bin Meng 



Re: [PATCH v10 04/16] target/riscv: Add x-zba, x-zbb, x-zbc and x-zbs properties

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:35 AM Philipp Tomsich  wrote:
>
> The bitmanipulation ISA extensions will be ratified as individual
> small extension packages instead of a large B-extension.  The first
> new instructions through the door (these have completed public review)
> are Zb[abcs].
>
> This adds new 'x-zba', 'x-zbb', 'x-zbc' and 'x-zbs' properties for
> these in target/riscv/cpu.[ch].
>
> Signed-off-by: Philipp Tomsich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: Alistair Francis 
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Split off removal of 'x-b' property and 'ext_b' field into a separate
>   patch to ensure bisectability.
>
>  target/riscv/cpu.c | 4 
>  target/riscv/cpu.h | 4 
>  2 files changed, 8 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH v10 02/16] target/riscv: fix clzw implementation to operate on arg1

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:35 AM Philipp Tomsich  wrote:
>
> The refactored gen_clzw() uses ret as its argument, instead of arg1.
> Fix it.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
> Changes in v10:
> - New patch, fixing regressions discovered with x264_r.
>
>  target/riscv/insn_trans/trans_rvb.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v10 01/16] target/riscv: Introduce temporary in gen_add_uw()

2021-09-07 Thread Bin Meng
On Sun, Sep 5, 2021 at 4:40 AM Philipp Tomsich  wrote:
>
> Following the recent changes in translate.c, gen_add_uw() causes
> failures on CF3 and SPEC2017 due to the reuse of arg1.  Fix these
> regressions by introducing a temporary.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
> Changes in v10:
> - new patch
>
>  target/riscv/insn_trans/trans_rvb.c.inc | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>

Reviewed-by: Bin Meng 



[PATCH v2 2/3] target/riscv: Implement the stval/mtval illegal instruction

2021-09-07 Thread Alistair Francis
From: Alistair Francis 

The stval and mtval registers can optionally contain the faulting
instruction on an illegal instruction exception. This patch adds support
for setting the stval and mtval registers based on the CPU feature.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  5 -
 target/riscv/cpu_helper.c | 10 ++
 target/riscv/translate.c  | 31 +--
 3 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bf1c899c00..d11db1f031 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -77,7 +77,8 @@ enum {
 RISCV_FEATURE_MMU,
 RISCV_FEATURE_PMP,
 RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA
+RISCV_FEATURE_MISA,
+RISCV_FEATURE_MTVAL_INST,
 };
 
 #define PRIV_VERSION_1_10_0 0x00011000
@@ -130,6 +131,8 @@ struct CPURISCVState {
 target_ulong frm;
 
 target_ulong badaddr;
+uint32_t bins;
+
 target_ulong guest_phys_fault_addr;
 
 target_ulong priv_ver;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 968cb8046f..65832967e1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -967,6 +967,16 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 write_tval  = true;
 tval = env->badaddr;
 break;
+case RISCV_EXCP_ILLEGAL_INST:
+if (riscv_feature(env, RISCV_FEATURE_MTVAL_INST)) {
+/*
+ * The stval/mtval register can optionally also be used to
+ * return the faulting instruction bits on an illegal
+ * instruction exception.
+ */
+tval = env->bins;
+}
+break;
 default:
 break;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 25670be435..99810db57d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -173,8 +173,25 @@ static void lookup_and_goto_ptr(DisasContext *ctx)
 }
 }
 
+/*
+ * Wrappers for getting reg values.
+ *
+ * The $zero register does not have cpu_gpr[0] allocated -- we supply the
+ * constant zero as a source, and an uninitialized sink as destination.
+ *
+ * Further, we may provide an extension for word operations.
+ */
+static TCGv temp_new(DisasContext *ctx)
+{
+assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
+return ctx->temp[ctx->ntemp++] = tcg_temp_new();
+}
+
 static void gen_exception_illegal(DisasContext *ctx)
 {
+tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
+   offsetof(CPURISCVState, bins));
+
 generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
 }
 
@@ -195,20 +212,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 }
 }
 
-/*
- * Wrappers for getting reg values.
- *
- * The $zero register does not have cpu_gpr[0] allocated -- we supply the
- * constant zero as a source, and an uninitialized sink as destination.
- *
- * Further, we may provide an extension for word operations.
- */
-static TCGv temp_new(DisasContext *ctx)
-{
-assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
-return ctx->temp[ctx->ntemp++] = tcg_temp_new();
-}
-
 static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
 {
 TCGv t;
-- 
2.31.1




[PATCH v2 3/3] target/riscv: Set mtval and stval support

2021-09-07 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 +
 target/riscv/cpu.c | 6 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d11db1f031..5b0bbf2fca 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -309,6 +309,7 @@ struct RISCVCPU {
 bool mmu;
 bool pmp;
 bool epmp;
+bool mtval_inst;
 uint64_t resetvec;
 } cfg;
 };
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1a2b03d579..537f2af341 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -437,6 +437,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.mtval_inst) {
+set_feature(env, RISCV_FEATURE_MTVAL_INST);
+}
+
 set_resetvec(env, cpu->cfg.resetvec);
 
 /* If only XLEN is set for misa, then set misa from properties */
@@ -600,7 +604,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-
+DEFINE_PROP_BOOL("tval-inst", RISCVCPU, cfg.mtval_inst, true),
 DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.31.1




[PATCH 0/5] qapi: Another round of minor fixes and cleanups

2021-09-07 Thread Markus Armbruster
Markus Armbruster (5):
  qapi: Fix a botched type annotation
  qapi: Drop Indentation.__bool__()
  qapi: Bury some unused code in class Indentation
  tests/qapi-schema: Cover 'not' condition with empty argument
  qapi: Fix bogus error for 'if': { 'not': '' }

 scripts/qapi/common.py| 19 ++-
 scripts/qapi/expr.py  | 21 +
 tests/qapi-schema/bad-if-not.err  |  2 ++
 tests/qapi-schema/bad-if-not.json |  3 +++
 tests/qapi-schema/bad-if-not.out  |  0
 tests/qapi-schema/meson.build |  1 +
 6 files changed, 25 insertions(+), 21 deletions(-)
 create mode 100644 tests/qapi-schema/bad-if-not.err
 create mode 100644 tests/qapi-schema/bad-if-not.json
 create mode 100644 tests/qapi-schema/bad-if-not.out

-- 
2.31.1




[PATCH v2 1/3] target/riscv: Set the opcode in DisasContext

2021-09-07 Thread Alistair Francis
From: Alistair Francis 

Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e356fc6c46..25670be435 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -485,20 +485,20 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 /* Include the auto-generated decoder for 16 bit insn */
 #include "decode-insn16.c.inc"
 
-static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
+static void decode_opc(CPURISCVState *env, DisasContext *ctx)
 {
 /* check for compressed insn */
-if (extract16(opcode, 0, 2) != 3) {
+if (extract16(ctx->opcode, 0, 2) != 3) {
 if (!has_ext(ctx, RVC)) {
 gen_exception_illegal(ctx);
 } else {
 ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (!decode_insn16(ctx, opcode)) {
+if (!decode_insn16(ctx, ctx->opcode)) {
 gen_exception_illegal(ctx);
 }
 }
 } else {
-uint32_t opcode32 = opcode;
+uint32_t opcode32 = ctx->opcode;
 opcode32 = deposit32(opcode32, 16, 16,
  translator_lduw(env, ctx->base.pc_next + 2));
 ctx->pc_succ_insn = ctx->base.pc_next + 4;
@@ -561,9 +561,9 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 {
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPURISCVState *env = cpu->env_ptr;
-uint16_t opcode16 = translator_lduw(env, ctx->base.pc_next);
+ctx->opcode = translator_lduw(env, ctx->base.pc_next);
 
-decode_opc(env, ctx, opcode16);
+decode_opc(env, ctx);
 ctx->base.pc_next = ctx->pc_succ_insn;
 ctx->w = false;
 
-- 
2.31.1




[PATCH 1/5] qapi: Fix a botched type annotation

2021-09-07 Thread Markus Armbruster
Mypy is unhappy:

$ mypy --config-file=scripts/qapi/mypy.ini `git-ls-files scripts/qapi/\*py`
scripts/qapi/common.py:208: error: Function is missing a return type 
annotation
scripts/qapi/common.py:227: error: Returning Any from function declared to 
return "str"

Messed up in commit ccea6a8637 "qapi: Factor common recursion out of
cgen_ifcond(), docgen_ifcond()".  Tidy up.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/common.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 5f8f76e5b2..c4d11b9637 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -205,7 +205,8 @@ def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]],
cond_fmt: str, not_fmt: str,
all_operator: str, any_operator: str) -> str:
 
-def do_gen(ifcond: Union[str, Dict[str, Any]], need_parens: bool):
+def do_gen(ifcond: Union[str, Dict[str, Any]],
+   need_parens: bool) -> str:
 if isinstance(ifcond, str):
 return cond_fmt % ifcond
 assert isinstance(ifcond, dict) and len(ifcond) == 1
-- 
2.31.1




[PATCH 2/5] qapi: Drop Indentation.__bool__()

2021-09-07 Thread Markus Armbruster
Intentation.__bool__() is not worth its keep: it has just one user,
which can just as well check .__str__() instead.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/common.py | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index c4d11b9637..1d62c27fb7 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -142,10 +142,6 @@ def __str__(self) -> str:
 """Return the current indentation as a string of spaces."""
 return ' ' * self._level
 
-def __bool__(self) -> bool:
-"""True when there is a non-zero indentation."""
-return bool(self._level)
-
 def increase(self, amount: int = 4) -> None:
 """Increase the indentation level by ``amount``, default 4."""
 self._level += amount
@@ -169,8 +165,9 @@ def cgen(code: str, **kwds: object) -> str:
 Obey `indent`, and strip `EATSPACE`.
 """
 raw = code % kwds
-if indent:
-raw = re.sub(r'^(?!(#|$))', str(indent), raw, flags=re.MULTILINE)
+pfx = str(indent)
+if pfx:
+raw = re.sub(r'^(?!(#|$))', pfx, raw, flags=re.MULTILINE)
 return re.sub(re.escape(EATSPACE) + r' *', '', raw)
 
 
-- 
2.31.1




[PATCH 5/5] qapi: Fix bogus error for 'if': { 'not': '' }

2021-09-07 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 scripts/qapi/expr.py | 21 +
 tests/qapi-schema/bad-if-not.err |  2 +-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index b62f0a3640..ad3732c7f0 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -293,17 +293,22 @@ def _check_if(cond: Union[str, object]) -> None:
 info,
 "'if' condition of %s has conflicting keys" % source)
 
-oper, operands = next(iter(cond.items()))
+if 'not' in cond:
+_check_if(cond['not'])
+elif 'all' in cond:
+_check_infix('all', cond['all'])
+else:
+_check_infix('any', cond['any'])
+
+def _check_infix(operator: str, operands: object):
+if not isinstance(operands, list):
+raise QAPISemError(
+info,
+"'%s' condition of %s must be an array"
+% (operator, source))
 if not operands:
 raise QAPISemError(
 info, "'if' condition [] of %s is useless" % source)
-
-if oper == "not":
-_check_if(operands)
-return
-if oper in ("all", "any") and not isinstance(operands, list):
-raise QAPISemError(
-info, "'%s' condition of %s must be an array" % (oper, source))
 for operand in operands:
 _check_if(operand)
 
diff --git a/tests/qapi-schema/bad-if-not.err b/tests/qapi-schema/bad-if-not.err
index b3acdd679a..b33f5e16b8 100644
--- a/tests/qapi-schema/bad-if-not.err
+++ b/tests/qapi-schema/bad-if-not.err
@@ -1,2 +1,2 @@
 bad-if-not.json: In struct 'TestIfStruct':
-bad-if-not.json:2: 'if' condition [] of struct is useless
+bad-if-not.json:2: 'if' condition '' of struct is not a valid identifier
-- 
2.31.1




[PATCH v2 0/3] RISC-V: Populate mtval and stval

2021-09-07 Thread Alistair Francis
From: Alistair Francis 


Populate mtval and stval when taking an illegal instruction exception if
the features are set for the CPU.



Alistair Francis (3):
  target/riscv: Set the opcode in DisasContext
  target/riscv: Implement the stval/mtval illegal instruction
  target/riscv: Set mtval and stval support

 target/riscv/cpu.h|  6 +-
 target/riscv/cpu.c|  6 +-
 target/riscv/cpu_helper.c | 10 +
 target/riscv/translate.c  | 43 +--
 4 files changed, 43 insertions(+), 22 deletions(-)

-- 
2.31.1




[PATCH 4/5] tests/qapi-schema: Cover 'not' condition with empty argument

2021-09-07 Thread Markus Armbruster
We flag this, but the error message is bogus:

bad-if-not.json:2: 'if' condition [] of struct is useless

The next commit will fix it.

Signed-off-by: Markus Armbruster 
---
 tests/qapi-schema/bad-if-not.err  | 2 ++
 tests/qapi-schema/bad-if-not.json | 3 +++
 tests/qapi-schema/bad-if-not.out  | 0
 tests/qapi-schema/meson.build | 1 +
 4 files changed, 6 insertions(+)
 create mode 100644 tests/qapi-schema/bad-if-not.err
 create mode 100644 tests/qapi-schema/bad-if-not.json
 create mode 100644 tests/qapi-schema/bad-if-not.out

diff --git a/tests/qapi-schema/bad-if-not.err b/tests/qapi-schema/bad-if-not.err
new file mode 100644
index 00..b3acdd679a
--- /dev/null
+++ b/tests/qapi-schema/bad-if-not.err
@@ -0,0 +1,2 @@
+bad-if-not.json: In struct 'TestIfStruct':
+bad-if-not.json:2: 'if' condition [] of struct is useless
diff --git a/tests/qapi-schema/bad-if-not.json 
b/tests/qapi-schema/bad-if-not.json
new file mode 100644
index 00..9fdaacc47b
--- /dev/null
+++ b/tests/qapi-schema/bad-if-not.json
@@ -0,0 +1,3 @@
+# check 'if not' with empy argument
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+  'if': { 'not': '' } }
diff --git a/tests/qapi-schema/bad-if-not.out b/tests/qapi-schema/bad-if-not.out
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index 4697c070bc..6b2a4ce41a 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -43,6 +43,7 @@ schemas = [
   'bad-if-key.json',
   'bad-if-keys.json',
   'bad-if-list.json',
+  'bad-if-not.json',
   'bad-type-bool.json',
   'bad-type-dict.json',
   'bad-type-int.json',
-- 
2.31.1




[PATCH 3/5] qapi: Bury some unused code in class Indentation

2021-09-07 Thread Markus Armbruster
.__int__() has never been used.  Drop it.

.decrease() raises ArithmeticError when asked to decrease indentation
level below zero.  Nothing catches it.  It's a programming error.
Dumb down to assert.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/common.py | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 1d62c27fb7..489273574a 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -132,9 +132,6 @@ class Indentation:
 def __init__(self, initial: int = 0) -> None:
 self._level = initial
 
-def __int__(self) -> int:
-return self._level
-
 def __repr__(self) -> str:
 return "{}({:d})".format(type(self).__name__, self._level)
 
@@ -148,9 +145,7 @@ def increase(self, amount: int = 4) -> None:
 
 def decrease(self, amount: int = 4) -> None:
 """Decrease the indentation level by ``amount``, default 4."""
-if self._level < amount:
-raise ArithmeticError(
-f"Can't remove {amount:d} spaces from {self!r}")
+assert amount <= self._level
 self._level -= amount
 
 
-- 
2.31.1




Re: [PATCH] hw/i386/acpi-build: adjust q35 IO addr range for acpi pci hotplug

2021-09-07 Thread Ani Sinha



On Wed, 8 Sep 2021, Ani Sinha wrote:

> Change caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
> Q35")
> selects an IO address range for acpi based PCI hotplug for q35 arbitrarily. It
> starts at address 0x0cc4 and ends at 0x0cdb. It was assumed that this address
> range was free and available. However, upon more testing, it seems this 
> address
> range to be not available for some latest versions of windows. Hence, this
> change modifies the IO address range so that windows can allocate the address
> range without any conflict. The new address range would start at 0x0dd4 and 
> end
> at address 0x0deb.
>
> This change has been tested using a Windows Server 2019 guest VM.
>

I realize that this breaks bios-tables-test.c which I will correct if we
are ok with this fix.

--- /tmp/asl-0FVI90.dsl 2021-09-08 10:05:59.260579343 +0530
+++ /tmp/asl-7TYI90.dsl 2021-09-08 10:05:59.252579221 +0530
@@ -1,30 +1,30 @@
 /*
  * Intel ACPI Component Architecture
  * AML/ASL+ Disassembler version 20190509 (64-bit version)
  * Copyright (c) 2000 - 2019 Intel Corporation
  *
  * Disassembling to symbolic ASL+ operators
  *
- * Disassembly of tests/data/acpi/q35/DSDT, Wed Sep  8 10:05:59 2021
+ * Disassembly of /tmp/aml-QVYI90, Wed Sep  8 10:05:59 2021
  *
  * Original Table Header:
  * Signature"DSDT"
  * Length   0x2061 (8289)
  * Revision 0x01  32-bit table (V1), no 64-bit math
support
- * Checksum 0xE5
+ * Checksum 0x90
  * OEM ID   "BOCHS "
  * OEM Table ID "BXPC"
  * OEM Revision 0x0001 (1)
  * Compiler ID  "BXPC"
  * Compiler Version 0x0001 (1)
  */
 DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC", 0x0001)
 {
 Scope (\)
 {
 OperationRegion (DBG, SystemIO, 0x0402, One)
 Field (DBG, ByteAcc, NoLock, Preserve)
 {
 DBGB,   8
 }

@@ -226,46 +226,46 @@
 Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource
Settings
 {
 IO (Decode16,
 0x0070, // Range Minimum
 0x0070, // Range Maximum
 0x01,   // Alignment
 0x08,   // Length
 )
 IRQNoFlags ()
 {8}
 })
 }
 }

 Scope (_SB.PCI0)
 {
-OperationRegion (PCST, SystemIO, 0x0CC4, 0x08)
+OperationRegion (PCST, SystemIO, 0x0DD4, 0x08)
 Field (PCST, DWordAcc, NoLock, WriteAsZeros)
 {
 PCIU,   32,
 PCID,   32
 }

-OperationRegion (SEJ, SystemIO, 0x0CCC, 0x04)
+OperationRegion (SEJ, SystemIO, 0x0DDC, 0x04)
 Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
 {
 B0EJ,   32
 }

-OperationRegion (BNMR, SystemIO, 0x0CD4, 0x08)
+OperationRegion (BNMR, SystemIO, 0x0DE4, 0x08)
 Field (BNMR, DWordAcc, NoLock, WriteAsZeros)
 {
 BNUM,   32,
 PIDX,   32
 }

 Mutex (BLCK, 0x00)
 Method (PCEJ, 2, NotSerialized)
 {
 Acquire (BLCK, 0x)
 BNUM = Arg0
 B0EJ = (One << Arg1)
 Release (BLCK)
 Return (Zero)
 }

@@ -3185,34 +3185,34 @@
 0x0620, // Range Minimum
 0x0620, // Range Maximum
 0x01,   // Alignment
 0x10,   // Length
 )
 })
 }

 Device (PHPR)
 {
 Name (_HID, "PNP0A06" /* Generic Container Device */)  //
_HID: Hardware ID
 Name (_UID, "PCI Hotplug resources")  // _UID: Unique ID
 Name (_STA, 0x0B)  // _STA: Status
 Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource
Settings
 {
 IO (Decode16,
-0x0CC4, // Range Minimum
-0x0CC4, // Range Maximum
+0x0DD4, // Range Minimum
+0x0DD4, // Range Maximum
 0x01,   // Alignment
 0x18,   // Length
 )
 })
 }
 }

 Scope (\)
 {
 Name (_S3, Package (0x04)  // _S3_: S3 System State
 {
 One,
 One,
 Zero,
 Zero
 })


> Fixes: caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
> Q35")
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/561
>
> Signed-off-by: Ani Sinha 
> ---
>  include/hw/acpi/ich9.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> index a329ce43ab..b68c5a2174 100644

[PATCH] hw/i386/acpi-build: adjust q35 IO addr range for acpi pci hotplug

2021-09-07 Thread Ani Sinha
Change caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
Q35")
selects an IO address range for acpi based PCI hotplug for q35 arbitrarily. It
starts at address 0x0cc4 and ends at 0x0cdb. It was assumed that this address
range was free and available. However, upon more testing, it seems this address
range to be not available for some latest versions of windows. Hence, this
change modifies the IO address range so that windows can allocate the address
range without any conflict. The new address range would start at 0x0dd4 and end
at address 0x0deb.

This change has been tested using a Windows Server 2019 guest VM.

Fixes: caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
Q35")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/561

Signed-off-by: Ani Sinha 
---
 include/hw/acpi/ich9.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index a329ce43ab..b68c5a2174 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -29,7 +29,7 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
 
-#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
+#define ACPI_PCIHP_ADDR_ICH9 0x0dd4
 
 typedef struct ICH9LPCPMRegs {
 /*
-- 
2.25.1




Re: [PATCH 4/5] ebpf_rss_helper: Added helper for eBPF RSS.

2021-09-07 Thread Jason Wang
On Tue, Sep 7, 2021 at 6:40 PM Yuri Benditovich
 wrote:
>
> On Wed, Sep 1, 2021 at 9:42 AM Jason Wang  wrote:
> >
> >
> > 在 2021/8/31 上午1:07, Yuri Benditovich 写道:
> > > On Fri, Aug 20, 2021 at 6:41 AM Jason Wang  wrote:
> > >>
> > >> 在 2021/7/13 下午11:37, Andrew Melnychenko 写道:
> > >>> Helper program. Loads eBPF RSS program and maps and passes them through 
> > >>> unix socket.
> > >>> Libvirt may launch this helper and pass eBPF fds to qemu virtio-net.
> > >>
> > >> I wonder if this can be done as helper for TAP/bridge.
> > >>
> > >> E.g it's the qemu to launch those helper with set-uid.
> > >>
> > >> Then libvirt won't even need to care about that?
> > >>
> > > There are pros and cons for such a solution with set-uid.
> > >  From my point of view one of the cons is that set-uid is efficient
> > > only at install time so the coexistence of different qemu builds (and
> > > different helpers for each one) is kind of problematic.
> > > With the current solution this does not present any problem: the
> > > developer can have several different builds, each one automatically
> > > has its own helper and there is no conflict between these builds and
> > > between these builds and installed qemu package. Changing the
> > > 'emulator' in the libvirt profile automatically brings the proper
> > > helper to work.
> >
> >
> > I'm not sure I get you here. We can still have default/sample helper to
> > make sure it works for different builds.
> >
> > If we can avoid the involvement of libvirt, that would be better.
>
> Hi Jason,
>
> Indeed I did not get the idea, can you please explain it in more
> details (as detailed as possible to avoid future misunderstanding),
> especially how exactly we can use the set-uid and what is the 'default' 
> helper.
> We also would prefer to do everything from qemu but we do not see how
> we can do that.


Something like:

1) -netdev tap,rss_helper=/path/to/name
2) having a sample/default helper implemented in Qemu
3) we can introduce something special path like "default", then if
-netdev tap,rss_helper="default" is specified, qemu will use the
sample helper

So we have:
1) set set-uid for the helper
2) libvirt may just choose to launch the default helper

>
> Our main points (what should be addressed):
> - qemu should be able to load ebpf and use the maps when it runs from
> libvirt (without special caps) and standalone (with caps)

This is solved by leaving the privileged operations to the helper with set-uid.

> - it is possible that there are different qemu builds on the machine,
> one of them might be installed, their ebpf's might be different and
> the interface between qemu and ebpf (exact content of maps and number
> of maps)

We can use different helpers in this way.

> - qemu configures the RSS dynamically according to the commands
> provided by the guest

Consider we decided to use mmap() based maps, this is not an issue.

Or am I missing something?

Thanks

>
> Thanks in advance
> Yuri
>
> >
> > Thanks
> >
> >
> > >
> > >>> Also, libbpf dependency now exclusively for Linux.
> > >>> Libbpf is used for eBPF RSS steering, which is supported only by Linux 
> > >>> TAP.
> > >>> There is no reason yet to build eBPF loader and helper for non Linux 
> > >>> systems,
> > >>> even if libbpf is present.
> > >>>
> > >>> Signed-off-by: Andrew Melnychenko 
> > >>> ---
> > >>>ebpf/qemu-ebpf-rss-helper.c | 130 
> > >>> 
> > >>>meson.build |  37 ++
> > >>>2 files changed, 154 insertions(+), 13 deletions(-)
> > >>>create mode 100644 ebpf/qemu-ebpf-rss-helper.c
> > >>>
> > >>> diff --git a/ebpf/qemu-ebpf-rss-helper.c b/ebpf/qemu-ebpf-rss-helper.c
> > >>> new file mode 100644
> > >>> index 00..fe68758f57
> > >>> --- /dev/null
> > >>> +++ b/ebpf/qemu-ebpf-rss-helper.c
> > >>> @@ -0,0 +1,130 @@
> > >>> +/*
> > >>> + * eBPF RSS Helper
> > >>> + *
> > >>> + * Developed by Daynix Computing LTD (http://www.daynix.com)
> > >>> + *
> > >>> + * Authors:
> > >>> + *  Andrew Melnychenko 
> > >>> + *
> > >>> + * This work is licensed under the terms of the GNU GPL, version 2.  
> > >>> See
> > >>> + * the COPYING file in the top-level directory.
> > >>> + *
> > >>> + * Description: This is helper program for libvirtd.
> > >>> + *  It loads eBPF RSS program and passes fds through unix 
> > >>> socket.
> > >>> + *  Built by meson, target - 'qemu-ebpf-rss-helper'.
> > >>> + */
> > >>> +
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +
> > >>> +#include "ebpf_rss.h"
> > >>> +
> > >>> +#include "qemu-helper-stamp.h"
> > >>> +
> > >>> +void QEMU_HELPER_STAMP(void) {}
> > >>> +
> > >>> +static int send_fds(int socket, int *fds, int n)
> > >>> +{
> > >>> +struct msghdr msg = {};
> > >>> +struct cmsghdr *cmsg = NULL;
> > >>> +char buf[CMSG_SPACE(n * sizeof(int))];
> > >>> +char 

Re: [PATCH v2 1/2] hw/timer: Add SiFive PWM support

2021-09-07 Thread Bin Meng
On Fri, Sep 3, 2021 at 7:25 AM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> This is the initial commit of the SiFive PWM timer. This is used by
> guest software are a timer and is included in the SiFive FU540 SoC.

"guest software are a time ..  This does not read right.

>
> Signed-off-by: Justin Restivo 
> Signed-off-by: Alexandra Clifford 
> Signed-off-by: Amanda Strnad 
> Signed-off-by: Alistair Francis 
> ---
>  include/hw/timer/sifive_pwm.h |  62 +
>  hw/timer/sifive_pwm.c | 467 ++
>  hw/timer/Kconfig  |   3 +
>  hw/timer/meson.build  |   1 +
>  hw/timer/trace-events |   6 +
>  5 files changed, 539 insertions(+)
>  create mode 100644 include/hw/timer/sifive_pwm.h
>  create mode 100644 hw/timer/sifive_pwm.c
>
> diff --git a/include/hw/timer/sifive_pwm.h b/include/hw/timer/sifive_pwm.h
> new file mode 100644
> index 00..e8bedca76e
> --- /dev/null
> +++ b/include/hw/timer/sifive_pwm.h
> @@ -0,0 +1,62 @@
> +/*
> + * SiFive FU540 PWM

remove FU540

> + *
> + * Copyright (c) 2020 Western Digital
> + *
> + * Author:  Alistair Francis 
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#ifndef HW_SIFIVE_PWM_H
> +#define HW_SIFIVE_PWM_H
> +
> +#include "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "qom/object.h"
> +
> +#define TYPE_SIFIVE_PWM "sifive-pwm"
> +
> +#define SIFIVE_PWM(obj) \
> +OBJECT_CHECK(SiFiveUPwmState, (obj), TYPE_SIFIVE_PWM)
> +
> +#define SIFIVE_PWM_CHANS  4
> +#define SIFIVE_PWM_IRQS   SIFIVE_PWM_CHANS
> +
> +typedef struct SiFiveUPwmState {

It should be named SiFivePwmState

> +/*  */
> +SysBusDevice parent_obj;
> +
> +/*  */
> +MemoryRegion mmio;
> +QEMUTimer timer[SIFIVE_PWM_CHANS];
> +/*
> + * if en bit(s) set, is the number of ticks when pwmcount was 0
> + * if en bit(s) not set, is the number of ticks in pwmcount
> + */
> +uint64_t tick_offset;
> +uint64_t freq_hz;
> +
> +uint32_t pwmcfg;
> +uint32_t pwmcmp[SIFIVE_PWM_CHANS];
> +
> +qemu_irq irqs[SIFIVE_PWM_IRQS];
> +} SiFiveUPwmState;
> +
> +#endif /* HW_SIFIVE_PWM_H */
> diff --git a/hw/timer/sifive_pwm.c b/hw/timer/sifive_pwm.c
> new file mode 100644
> index 00..61a97f9b46
> --- /dev/null
> +++ b/hw/timer/sifive_pwm.c
> @@ -0,0 +1,467 @@
> +/*
> + * SiFive PWM
> + *
> + * Copyright (c) 2020 Western Digital
> + *
> + * Author:  Alistair Francis 
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/irq.h"
> +#include "hw/timer/sifive_pwm.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/registerfields.h"
> +#include "migration/vmstate.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +
> +#define HAS_PWM_EN_BITS(cfg) ((cfg & 

Re: [PATCH v2 2/2] sifive_u: Connect the SiFive PWM device

2021-09-07 Thread Bin Meng
On Fri, Sep 3, 2021 at 7:25 AM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> Connect the SiFive PWM device and expose it via the device tree.
>
> Signed-off-by: Alistair Francis 
> ---
>  include/hw/riscv/sifive_u.h | 14 +-
>  hw/riscv/sifive_u.c | 55 -
>  hw/timer/sifive_pwm.c   |  1 +
>  hw/riscv/Kconfig|  1 +
>  4 files changed, 69 insertions(+), 2 deletions(-)

Please also update docs/system/riscv/sifive_u.rst for the supported device list

>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 2656b39808..0d010c7309 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -27,6 +27,7 @@
>  #include "hw/misc/sifive_u_otp.h"
>  #include "hw/misc/sifive_u_prci.h"
>  #include "hw/ssi/sifive_spi.h"
> +#include "hw/timer/sifive_pwm.h"
>
>  #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
>  #define RISCV_U_SOC(obj) \
> @@ -49,6 +50,7 @@ typedef struct SiFiveUSoCState {
>  SiFiveSPIState spi0;
>  SiFiveSPIState spi2;
>  CadenceGEMState gem;
> +SiFiveUPwmState pwm[2];
>
>  uint32_t serial;
>  char *cpu_type;
> @@ -92,7 +94,9 @@ enum {
>  SIFIVE_U_DEV_FLASH0,
>  SIFIVE_U_DEV_DRAM,
>  SIFIVE_U_DEV_GEM,
> -SIFIVE_U_DEV_GEM_MGMT
> +SIFIVE_U_DEV_GEM_MGMT,
> +SIFIVE_U_DEV_PWM0,
> +SIFIVE_U_DEV_PWM1
>  };
>
>  enum {
> @@ -126,6 +130,14 @@ enum {
>  SIFIVE_U_PDMA_IRQ5 = 28,
>  SIFIVE_U_PDMA_IRQ6 = 29,
>  SIFIVE_U_PDMA_IRQ7 = 30,
> +SIFIVE_U_DEV_PWM0_0 = 42,

For consistency, these should be SIFIVE_U_PWM0_IRQ0/1/2/3

> +SIFIVE_U_DEV_PWM0_1 = 43,
> +SIFIVE_U_DEV_PWM0_2 = 44,
> +SIFIVE_U_DEV_PWM0_3 = 45,
> +SIFIVE_U_DEV_PWM1_0 = 46,
> +SIFIVE_U_DEV_PWM1_1 = 47,
> +SIFIVE_U_DEV_PWM1_2 = 48,
> +SIFIVE_U_DEV_PWM1_3 = 49,
>  SIFIVE_U_QSPI0_IRQ = 51,
>  SIFIVE_U_GEM_IRQ = 53
>  };
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 6cc1a62b0f..ed2e75df36 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -17,6 +17,7 @@
>   * 7) DMA (Direct Memory Access Controller)
>   * 8) SPI0 connected to an SPI flash
>   * 9) SPI2 connected to an SD card
> + * 10) PWM0 and PWM1
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -75,6 +76,8 @@ static const MemMapEntry sifive_u_memmap[] = {
>  [SIFIVE_U_DEV_PRCI] = { 0x1000, 0x1000 },
>  [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
>  [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
> +[SIFIVE_U_DEV_PWM0] = { 0x1002, 0x1000 },
> +[SIFIVE_U_DEV_PWM1] = { 0x10021000, 0x1000 },
>  [SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
>  [SIFIVE_U_DEV_QSPI2] ={ 0x1005, 0x1000 },
>  [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
> @@ -441,6 +444,38 @@ static void create_fdt(SiFiveUState *s, const 
> MemMapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
>  g_free(nodename);
>
> +nodename = g_strdup_printf("/soc/pwm@%lx",
> +(long)memmap[SIFIVE_U_DEV_PWM0].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_DEV_PWM0].base,
> +0x0, memmap[SIFIVE_U_DEV_PWM0].size);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
> +   SIFIVE_U_DEV_PWM0_0, SIFIVE_U_DEV_PWM0_1,
> +   SIFIVE_U_DEV_PWM0_2, SIFIVE_U_DEV_PWM0_3);
> +qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +   prci_phandle, PRCI_CLK_TLCLK);
> +qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
> +g_free(nodename);
> +
> +nodename = g_strdup_printf("/soc/pwm@%lx",
> +(long)memmap[SIFIVE_U_DEV_PWM1].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,pwm0");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_DEV_PWM1].base,
> +0x0, memmap[SIFIVE_U_DEV_PWM1].size);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
> +   SIFIVE_U_DEV_PWM1_0, SIFIVE_U_DEV_PWM1_1,
> +   SIFIVE_U_DEV_PWM1_2, SIFIVE_U_DEV_PWM1_3);
> +qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +   prci_phandle, PRCI_CLK_TLCLK);
> +qemu_fdt_setprop_cell(fdt, nodename, "#pwm-cells", 0);
> +g_free(nodename);
> +
>  nodename = g_strdup_printf("/soc/serial@%lx",
>  (long)memmap[SIFIVE_U_DEV_UART1].base);
>  qemu_fdt_add_subnode(fdt, nodename);
> @@ -765,6 +800,8 @@ 

Re: [PATCH v1 3/3] migration: multifd: Enable zerocopy

2021-09-07 Thread Jason Wang
On Wed, Sep 8, 2021 at 11:24 AM Peter Xu  wrote:
>
> On Wed, Sep 08, 2021 at 10:59:57AM +0800, Jason Wang wrote:
> > On Wed, Sep 8, 2021 at 2:32 AM Peter Xu  wrote:
> > >
> > > On Thu, Sep 02, 2021 at 04:22:55AM -0300, Leonardo Bras Soares Passos 
> > > wrote:
> > > > > I don't think it is valid to unconditionally enable this feature due 
> > > > > to the
> > > > > resource usage implications
> > > > >
> > > > > https://www.kernel.org/doc/html/v5.4/networking/msg_zerocopy.html
> > > > >
> > > > >   "A zerocopy failure will return -1 with errno ENOBUFS. This happens
> > > > >if the socket option was not set, the socket exceeds its optmem
> > > > >limit or the user exceeds its ulimit on locked pages."
> > > >
> > > > You are correct, I unfortunately missed this part in the docs :(
> > > >
> > > > > The limit on locked pages is something that looks very likely to be
> > > > > exceeded unless you happen to be running a QEMU config that already
> > > > > implies locked memory (eg PCI assignment)
> > > >
> > > > Do you mean the limit an user has on locking memory?
> > > >
> > > > If so, that makes sense. I remember I needed to set the upper limit of 
> > > > locked
> > > > memory for the user before using it, or adding a capability to qemu 
> > > > before.
> > >
> > > So I'm a bit confused on why MSG_ZEROCOPY requires checking 
> > > RLIMIT_MEMLOCK.
> > >
> > > The thing is IIUC that's accounting for pinned pages only with either 
> > > mlock()
> > > (FOLL_MLOCK) or vfio (FOLL_PIN).
> > >
> > > I don't really think MSG_ZEROCOPY is doing that at all...  I'm looking at
> > > __zerocopy_sg_from_iter() -> iov_iter_get_pages().
> >
> > It happens probably here:
> >
> > E.g
> >
> > __ip_append_data()
> > msg_zerocopy_realloc()
> > mm_account_pinned_pages()
>
> Right. :)
>
> But my previous question is more about the reason behind it - I thought that's
> a common GUP and it shouldn't rely on locked_vm because it should still be
> temporary GUP rather than a long time GUP, IMHO that's how we use locked_vm 
> (we
> don't account for temp GUPs but only longterm ones). IOW, I'm wondering 
> whether
> all the rest of iov_iter_get_pages() callers should check locked_vm too, and
> AFAIU they're not doing that right now..

You are probably right, but I'm not sure if it's too late to fix that.
(E.g it will break existing userspace)

Thanks

>
> Thanks,
>
> --
> Peter Xu
>




Re: [PATCH v1 3/3] migration: multifd: Enable zerocopy

2021-09-07 Thread Peter Xu
On Wed, Sep 08, 2021 at 10:59:57AM +0800, Jason Wang wrote:
> On Wed, Sep 8, 2021 at 2:32 AM Peter Xu  wrote:
> >
> > On Thu, Sep 02, 2021 at 04:22:55AM -0300, Leonardo Bras Soares Passos wrote:
> > > > I don't think it is valid to unconditionally enable this feature due to 
> > > > the
> > > > resource usage implications
> > > >
> > > > https://www.kernel.org/doc/html/v5.4/networking/msg_zerocopy.html
> > > >
> > > >   "A zerocopy failure will return -1 with errno ENOBUFS. This happens
> > > >if the socket option was not set, the socket exceeds its optmem
> > > >limit or the user exceeds its ulimit on locked pages."
> > >
> > > You are correct, I unfortunately missed this part in the docs :(
> > >
> > > > The limit on locked pages is something that looks very likely to be
> > > > exceeded unless you happen to be running a QEMU config that already
> > > > implies locked memory (eg PCI assignment)
> > >
> > > Do you mean the limit an user has on locking memory?
> > >
> > > If so, that makes sense. I remember I needed to set the upper limit of 
> > > locked
> > > memory for the user before using it, or adding a capability to qemu 
> > > before.
> >
> > So I'm a bit confused on why MSG_ZEROCOPY requires checking RLIMIT_MEMLOCK.
> >
> > The thing is IIUC that's accounting for pinned pages only with either 
> > mlock()
> > (FOLL_MLOCK) or vfio (FOLL_PIN).
> >
> > I don't really think MSG_ZEROCOPY is doing that at all...  I'm looking at
> > __zerocopy_sg_from_iter() -> iov_iter_get_pages().
> 
> It happens probably here:
> 
> E.g
> 
> __ip_append_data()
> msg_zerocopy_realloc()
> mm_account_pinned_pages()

Right. :)

But my previous question is more about the reason behind it - I thought that's
a common GUP and it shouldn't rely on locked_vm because it should still be
temporary GUP rather than a long time GUP, IMHO that's how we use locked_vm (we
don't account for temp GUPs but only longterm ones). IOW, I'm wondering whether
all the rest of iov_iter_get_pages() callers should check locked_vm too, and
AFAIU they're not doing that right now..

Thanks,

-- 
Peter Xu




Re: [PATCH v5 3/4] spapr_numa.c: base FORM2 NUMA affinity support

2021-09-07 Thread David Gibson
On Tue, Sep 07, 2021 at 07:07:41AM -0300, Daniel Henrique Barboza wrote:
65;6402;1c> 
> 
> On 9/6/21 10:02 PM, David Gibson wrote:
> > On Mon, Sep 06, 2021 at 09:25:26PM -0300, Daniel Henrique Barboza wrote:
> > > The main feature of FORM2 affinity support is the separation of NUMA
> > > distances from ibm,associativity information. This allows for a more
> > > flexible and straightforward NUMA distance assignment without relying on
> > > complex associations between several levels of NUMA via
> > > ibm,associativity matches. Another feature is its extensibility. This base
> > > support contains the facilities for NUMA distance assignment, but in the
> > > future more facilities will be added for latency, performance, bandwidth
> > > and so on.
> > > 
> > > This patch implements the base FORM2 affinity support as follows:
> > > 
> > > - the use of FORM2 associativity is indicated by using bit 2 of byte 5
> > > of ibm,architecture-vec-5. A FORM2 aware guest can choose to use FORM1
> > > or FORM2 affinity. Setting both forms will default to FORM2. We're not
> > > advertising FORM2 for pseries-6.1 and older machine versions to prevent
> > > guest visible changes in those;
> > > 
> > > - call spapr_numa_associativity_reset() in 
> > > do_client_architecture_support()
> > > if FORM2 is chosen. This will avoid re-initializing FORM1 artifacts that
> > > were already initialized in spapr_machine_reset();
> > > 
> > > - ibm,associativity-reference-points has a new semantic. Instead of
> > > being used to calculate distances via NUMA levels, it's now used to
> > > indicate the primary domain index in the ibm,associativity domain of
> > > each resource. In our case it's set to {0x4}, matching the position
> > > where we already place logical_domain_id;
> > 
> > Hmm... I'm a bit torn on this.  The whole reason the ibm,associativity
> > things are arrays rather than just numbers was to enable the FORM1
> > nonsense. So we have a choice here: keep the associativity arrays in
> > the same form, for simplicity of the code, or reduce the associativity
> > arrays to one entry for FORM2, to simplify the overall DT contents in
> > the "modern" case.
> 
> I'm not against making it different from FORM2. I did it this way because
> it minimizes the amount of code being changed.
> 
> In fact, if we're going to add separated data structures for both FORM1 and
> FORM2, might as well start both FORM1 and FORM2 data structures during
> machine_init() and then just switch to the chosen affinity after CAS.
> 
> Something like a FORM1_assoc_array[N][MAX_DISTANCE_REF_POINTS], that contains
> all the initialization already done today and a FORM2_assoc_array[N][2],
> where FORM2_assoc_array[node_id] = {1, node_id}, changing reference-points
> accordingly of course.
> 
> spapr_numa_assoc_array would become a pointer that would point to either
> FORM1_assoc_array[][] or FORM2_assoc_array[][] depending on guest choice. I
> think this might be enough to make everything we already have just works, 
> although
> I need to check how much code is dependant on the MAX_DISTANCE_REF_POINTS
> macro and adapt it.
> 
> If no one opposes I'll go for this approach.

I think that's the way to go.  Thanks for working on this.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH] ebpf: only include in system emulators

2021-09-07 Thread Jason Wang



在 2021/9/7 下午6:45, Paolo Bonzini 写道:

eBPF files are being included in system emulators, which is useless



I think it should work since it's an independent feature. The current 
use case is to offload the RSS from Qemu to kernel TAP.




  and
also breaks compilation because ebpf/trace-events is only processed
if a system emulator is included in the build.



Andrew, any way to fix this?

Thanks




Resolves: https://gitlab.com/qemu-project/qemu/-/issues/566
Signed-off-by: Paolo Bonzini 
---
  ebpf/meson.build | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ebpf/meson.build b/ebpf/meson.build
index 9cd0635370..2dd0fd8948 100644
--- a/ebpf/meson.build
+++ b/ebpf/meson.build
@@ -1 +1 @@
-common_ss.add(when: libbpf, if_true: files('ebpf_rss.c'), if_false: 
files('ebpf_rss-stub.c'))
+softmmu_ss.add(when: libbpf, if_true: files('ebpf_rss.c'), if_false: 
files('ebpf_rss-stub.c'))





Re: [PATCH v1 3/3] migration: multifd: Enable zerocopy

2021-09-07 Thread Jason Wang
On Wed, Sep 8, 2021 at 2:32 AM Peter Xu  wrote:
>
> On Thu, Sep 02, 2021 at 04:22:55AM -0300, Leonardo Bras Soares Passos wrote:
> > > I don't think it is valid to unconditionally enable this feature due to 
> > > the
> > > resource usage implications
> > >
> > > https://www.kernel.org/doc/html/v5.4/networking/msg_zerocopy.html
> > >
> > >   "A zerocopy failure will return -1 with errno ENOBUFS. This happens
> > >if the socket option was not set, the socket exceeds its optmem
> > >limit or the user exceeds its ulimit on locked pages."
> >
> > You are correct, I unfortunately missed this part in the docs :(
> >
> > > The limit on locked pages is something that looks very likely to be
> > > exceeded unless you happen to be running a QEMU config that already
> > > implies locked memory (eg PCI assignment)
> >
> > Do you mean the limit an user has on locking memory?
> >
> > If so, that makes sense. I remember I needed to set the upper limit of 
> > locked
> > memory for the user before using it, or adding a capability to qemu before.
>
> So I'm a bit confused on why MSG_ZEROCOPY requires checking RLIMIT_MEMLOCK.
>
> The thing is IIUC that's accounting for pinned pages only with either mlock()
> (FOLL_MLOCK) or vfio (FOLL_PIN).
>
> I don't really think MSG_ZEROCOPY is doing that at all...  I'm looking at
> __zerocopy_sg_from_iter() -> iov_iter_get_pages().

It happens probably here:

E.g

__ip_append_data()
msg_zerocopy_realloc()
mm_account_pinned_pages()

Thanks

>
> Say, I think there're plenty of iov_iter_get_pages() callers and normal GUPs, 
> I
> think most of them do no need such accountings.
>
> --
> Peter Xu
>




Re: Application of QEMUTimer in short timing.

2021-09-07 Thread Duo jia
thank you for your reply.I understand.

Also I want to know how to make a delay in qemu.
For example, when I send a UART data, there is a certain time interval from
setting the register to when the data is sent. Most of this time does not
affect the simulation effect, but some guest firmware will execute errors
when there is no such delay. This is a comparison. Few, but it does exist.

My question is, if I really want to add such a delay, how to do it. For
example, in USART, can I set a callback for sending completion, or add some
delays that will not cause qemu to freeze.





Peter Maydell  于2021年9月7日周二 下午8:20写道:

> On Tue, 7 Sept 2021 at 12:28, Duo jia  wrote:
> >
> > In the controller, QEMUTimer will be used in the implementation of timer
> simulation.
> >
> > I wrote an auto-loading timer with a period of 1ms and the clock source
> used is QEMU_CLOCK_VIRTUAL. But it doesn't seem to be very accurate,
> because the actual time after I accumulated it to 500 times took about
> 700ms.
>
> It depends on how you use it. Generally the actual firing will not happen
> exactly on the specified mark. So if your implementation is "set clock
> for 1ms in the future; when it fires, set for 1ms in the future again"
> that is likely to be inaccurate. If you implement it as "set clock for
> 1ms in the future; when it fires, set for 1ms after the time when it
> should have fired" it will probably be better.
>
> In particular, if the semantics of your timer fit the ptimer API
> (which can implement oneshot and periodic timers) then I would recommend
> using that instead of a raw QEMUTimer; it deals with a lot of these
> fiddly details for you.
>
> -- PMM
>


Re: [PATCH v5 1/4] spapr: move NUMA associativity init to machine reset

2021-09-07 Thread David Gibson
On Tue, Sep 07, 2021 at 09:10:13AM +0200, Greg Kurz wrote:
> On Tue, 7 Sep 2021 10:37:27 +1000
> David Gibson  wrote:
> 
> > On Mon, Sep 06, 2021 at 09:25:24PM -0300, Daniel Henrique Barboza wrote:
> > > At this moment we only support one form of NUMA affinity, FORM1. This
> > > allows us to init the internal structures during machine_init(), and
> > > given that NUMA distances won't change during the guest lifetime we
> > > don't need to bother with that again.
> > > 
> > > We're about to introduce FORM2, a new NUMA affinity mode for pSeries
> > > guests. This means that we'll only be certain about the affinity mode
> > > being used after client architecture support. This also means that the
> > > guest can switch affinity modes in machine reset.
> > > 
> > > Let's prepare the ground for the FORM2 support by moving the NUMA
> > > internal data init from machine_init() to machine_reset(). Change the
> > > name to spapr_numa_associativity_reset() to make it clearer that this is
> > > a function that can be called multiple times during the guest lifecycle.
> > > We're also simplifying its current API since this method will be called
> > > during CAS time (do_client_architecture_support()) later on and there's no
> > > MachineState pointer already solved there.
> > > 
> > > Signed-off-by: Daniel Henrique Barboza 
> > 
> > Applied to ppc-for-6.2, thanks.
> > 
> 
> Even if already applied :
> 
> Reviewed-by: Greg Kurz 

Added, thanks.

> > > ---
> > >  hw/ppc/spapr.c  | 6 +++---
> > >  hw/ppc/spapr_numa.c | 4 ++--
> > >  include/hw/ppc/spapr_numa.h | 9 +
> > >  3 files changed, 6 insertions(+), 13 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index d39fd4e644..8e1ff6cd10 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -1621,6 +1621,9 @@ static void spapr_machine_reset(MachineState 
> > > *machine)
> > >   */
> > >  spapr_irq_reset(spapr, _fatal);
> > >  
> > > +/* Reset numa_assoc_array */
> > > +spapr_numa_associativity_reset(spapr);
> > > +
> > >  /*
> > >   * There is no CAS under qtest. Simulate one to please the code that
> > >   * depends on spapr->ov5_cas. This is especially needed to test 
> > > device
> > > @@ -2808,9 +2811,6 @@ static void spapr_machine_init(MachineState 
> > > *machine)
> > >  
> > >  spapr->gpu_numa_id = spapr_numa_initial_nvgpu_numa_id(machine);
> > >  
> > > -/* Init numa_assoc_array */
> > > -spapr_numa_associativity_init(spapr, machine);
> > > -
> > >  if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
> > >  ppc_type_check_compat(machine->cpu_type, 
> > > CPU_POWERPC_LOGICAL_3_00, 0,
> > >spapr->max_compat_pvr)) {
> > > diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
> > > index 779f18b994..9ee4b479fe 100644
> > > --- a/hw/ppc/spapr_numa.c
> > > +++ b/hw/ppc/spapr_numa.c
> > > @@ -155,10 +155,10 @@ static void 
> > > spapr_numa_define_associativity_domains(SpaprMachineState *spapr)
> > >  
> > >  }
> > >  
> > > -void spapr_numa_associativity_init(SpaprMachineState *spapr,
> > > -   MachineState *machine)
> > > +void spapr_numa_associativity_reset(SpaprMachineState *spapr)
> > >  {
> > >  SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> > > +MachineState *machine = MACHINE(spapr);
> > >  int nb_numa_nodes = machine->numa_state->num_nodes;
> > >  int i, j, max_nodes_with_gpus;
> > >  bool using_legacy_numa = spapr_machine_using_legacy_numa(spapr);
> > > diff --git a/include/hw/ppc/spapr_numa.h b/include/hw/ppc/spapr_numa.h
> > > index 6f9f02d3de..0e457bba57 100644
> > > --- a/include/hw/ppc/spapr_numa.h
> > > +++ b/include/hw/ppc/spapr_numa.h
> > > @@ -16,14 +16,7 @@
> > >  #include "hw/boards.h"
> > >  #include "hw/ppc/spapr.h"
> > >  
> > > -/*
> > > - * Having both SpaprMachineState and MachineState as arguments
> > > - * feels odd, but it will spare a MACHINE() call inside the
> > > - * function. spapr_machine_init() is the only caller for it, and
> > > - * it has both pointers resolved already.
> > > - */
> > > -void spapr_numa_associativity_init(SpaprMachineState *spapr,
> > > -   MachineState *machine);
> > 
> > Nice additional cleanup to the signature, thanks.
> > 
> > > +void spapr_numa_associativity_reset(SpaprMachineState *spapr);
> > >  void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int 
> > > rtas);
> > >  void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void 
> > > *fdt,
> > > int offset, int nodeid);
> > 
> 



-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: arm: Launching EFI-enabled arm32 Linux

2021-09-07 Thread Andre Przywara
On Wed, 8 Sep 2021 01:25:04 +0200
Adam Lackorzynski  wrote:

Hi Adam,

> On Mon Sep 06, 2021 at 16:34:03 +0100, Andre Przywara wrote:
> > On Sat, 4 Sep 2021 21:26:45 +0200
> > Adam Lackorzynski  wrote:
> > 
> > Hi Adam,
> >   
> > > while trying to launch an EFI-enabled arm32 Linux binary (zImage) I
> > > noticed I get an undefined instruction exception on the first
> > > instruction. Now this is a bit special because Linux uses a nop
> > > instruction there that also is a PE file signature ('MZ') such that the
> > > CPU runs over it and the file is still recognized as a PE binary. Linux
> > > uses 0x13105a4d (tstne r0, #0x4d000) as the instruction (see also
> > > arch/arm/boot/compressed/head.S and efi-header.S in Linux).
> > > However, QEMU's instruction decoder will only recognize TST with bits
> > > 12-15 being 0, which this instruction is not fullfilling, and thus the
> > > undef exception. I guess other CPU implementations will allow this
> > > encoding. So while investigating I was doing the following to make Linux
> > > proceed. I also believe this was working in a previous version of QEMU.
> > > 
> > > diff --git a/target/arm/a32.decode b/target/arm/a32.decode
> > > index fcd8cd4f7d..222553750e 100644
> > > --- a/target/arm/a32.decode
> > > +++ b/target/arm/a32.decode
> > > @@ -127,7 +127,7 @@ ADD_rri   001 0100 .   
> > >    @s_rri_rot
> > >  ADC_rri   001 0101 .      @s_rri_rot
> > >  SBC_rri   001 0110 .      @s_rri_rot
> > >  RSC_rri   001 0111 .      @s_rri_rot
> > > -TST_xri   001 1000 1      @S_xri_rot
> > > +TST_xri   001 1000 1      @S_xri_rot
> > >  TEQ_xri   001 1001 1      @S_xri_rot
> > >  CMP_xri   001 1010 1      @S_xri_rot
> > >  CMN_xri   001 1011 1      @S_xri_rot
> > > 
> > > 
> > > Any thoughts on this?  
> > 
> > thanks for the report, I was looking at this and have a kernel patch
> > to fix this properly as Peter suggested. And while I agree on the
> > problem, I was struggling to reproduce this in reality: both with
> > -kernel and when booting through U-Boot the "Z" bit is set, which lets
> > QEMU not even bother about the rest of the encoding - the condition
> > flags don't match, so it proceeds. If I change the __nop to use "tsteq",
> > I see it hanging due to the missing exception handler, but not with
> > "tstne".
> > So can you say how you spotted this issue? This would be needed as a
> > justification for patching the guts of the ARM Linux kernel port.  
> 
> Good point with the condition flags. I'm doing this with our own vmm
> where I'm loading the binary directly as the payload (as mandated by the
> header), and where psr is set to a defined value with all flags cleared.

Right, I was thinking something like this.

> If I set the Z bit than it also works (of course).
> Looking a bit around in QEMU as well as u-boot I it looks like this is
> rather by luck how flags are set.

Yes, the kernel boot protocol doesn't say anything about the condition
flags, so any combination would be valid and we were just lucky before.
I did also test on an Cortex-A7 and A53, both ignore bits [15:12] (so
execute the instruction as if they were 0), which explains why it works
on real hardware.

> Thanks for doing the Linux patch, I'll scrap mine, and also thanks to
> Peter for the idea!

Oh, didn't want to cut you off, if you want to have the commit: be my
guest!
Otherwise I will send something tomorrow, with a Reported-by: to you.

Grüße an die Elbe!

Cheers,
Andre



[PATCH 2/4] hw/sd: add nuvoton MMC

2021-09-07 Thread Hao Wu
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
---
 hw/arm/npcm7xx.c  |  12 +++-
 hw/sd/meson.build |   1 +
 hw/sd/npcm7xx_sdhci.c | 131 ++
 include/hw/arm/npcm7xx.h  |   2 +
 include/hw/sd/npcm7xx_sdhci.h |  65 +
 5 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 hw/sd/npcm7xx_sdhci.c
 create mode 100644 include/hw/sd/npcm7xx_sdhci.h

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 2ab0080e0b..878c2208e0 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -63,6 +63,8 @@
 #define NPCM7XX_ROM_BA  (0x)
 #define NPCM7XX_ROM_SZ  (64 * KiB)
 
+/* SDHCI Modules */
+#define NPCM7XX_MMC_BA  (0xf0842000)
 
 /* Clock configuration values to be fixed up when bypassing bootloader */
 
@@ -83,6 +85,7 @@ enum NPCM7xxInterrupt {
 NPCM7XX_UART3_IRQ,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
+NPCM7XX_MMC_IRQ = 26,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -443,6 +446,8 @@ static void npcm7xx_init(Object *obj)
 for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
+
+object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
 static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -707,6 +712,12 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
_abort);
 memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, >irom);
 
+/* SDHCI */
+sysbus_realize(SYS_BUS_DEVICE(>mmc), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>mmc), 0, NPCM7XX_MMC_BA);
+sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
+npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -736,7 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.usbd[8]",  0xf0838000,   4 * KiB);
 create_unimplemented_device("npcm7xx.usbd[9]",  0xf0839000,   4 * KiB);
 create_unimplemented_device("npcm7xx.sd",   0xf084,   8 * KiB);
-create_unimplemented_device("npcm7xx.mmc",  0xf0842000,   8 * KiB);
 create_unimplemented_device("npcm7xx.pcimbx",   0xf0848000, 512 * KiB);
 create_unimplemented_device("npcm7xx.aes",  0xf0858000,   4 * KiB);
 create_unimplemented_device("npcm7xx.des",  0xf0859000,   4 * KiB);
diff --git a/hw/sd/meson.build b/hw/sd/meson.build
index f1ce357a3b..807ca07b7c 100644
--- a/hw/sd/meson.build
+++ b/hw/sd/meson.build
@@ -9,4 +9,5 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
files('pxa2xx_mmci.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c'))
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c'))
 softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: 
files('allwinner-sdhost.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_sdhci.c'))
 softmmu_ss.add(when: 'CONFIG_CADENCE_SDHCI', if_true: files('cadence_sdhci.c'))
diff --git a/hw/sd/npcm7xx_sdhci.c b/hw/sd/npcm7xx_sdhci.c
new file mode 100644
index 00..85cccdc485
--- /dev/null
+++ b/hw/sd/npcm7xx_sdhci.c
@@ -0,0 +1,131 @@
+/*
+ * NPCM7xx SD-3.0 / eMMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * 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.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/sd/npcm7xx_sdhci.h"
+#include "sdhci-internal.h"
+
+static uint64_t npcm7xx_sdhci_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+NPCM7xxSDHCIState *s = opaque;
+uint64_t val = 0;
+
+switch (addr) {
+case NPCM7XX_PRSTVALS_0:
+case NPCM7XX_PRSTVALS_1:
+case NPCM7XX_PRSTVALS_2:
+case NPCM7XX_PRSTVALS_3:
+case NPCM7XX_PRSTVALS_4:
+case NPCM7XX_PRSTVALS_5:
+val = (uint64_t)s->regs.prstvals[(addr - NPCM7XX_PRSTVALS_0) / 2];
+break;
+case NPCM7XX_BOOTTOCTRL:
+val = (uint64_t)s->regs.boottoctrl;
+break;
+default:
+val = (uint64_t)s->sdhci.io_ops->read(>sdhci, addr, size);
+}
+
+return val;
+}
+
+static void npcm7xx_sdhci_write(void 

[PATCH 4/4] tests/qtest: add qtests for npcm7xx sdhci

2021-09-07 Thread Hao Wu
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_sdhci-test.c | 201 +++
 2 files changed, 202 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 757bb8499a..ef9c904779 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -157,6 +157,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_sdhci-test',
'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test'] + \
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
new file mode 100644
index 00..5c4e78fda4
--- /dev/null
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -0,0 +1,201 @@
+/*
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * 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.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sd/npcm7xx_sdhci.h"
+
+#include "libqos/libqtest.h"
+#include "libqtest-single.h"
+#include "libqos/sdhci-cmd.h"
+
+#define NPCM7XX_MMC_BA 0xF0842000
+#define NPCM7XX_BLK_SIZE 512
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
+
+char *sd_path;
+
+static QTestState *setup_sd_card(void)
+{
+QTestState *qts = qtest_initf(
+"-machine quanta-gbs-bmc "
+"-device sd-card,drive=drive0 "
+"-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
+sd_path);
+
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
+ SDHC_CLOCK_INT_EN);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4120, 0, (41 << 8));
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4567, 0,
+   SDHC_SELECT_DESELECT_CARD);
+
+return qts;
+}
+
+static void write_sdread(QTestState *qts, const char *msg)
+{
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message to sd */
+int fd = open(sd_path, O_WRONLY);
+int ret = write(fd, msg, len);
+close(fd);
+g_assert(ret == len);
+
+/* read message using sdhci */
+ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
+g_assert(ret == len);
+g_assert(!strcmp(rmsg, msg));
+
+free(rmsg);
+}
+
+/* Check MMC can read values from sd */
+static void test_read_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+write_sdread(qts, "hello world");
+write_sdread(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+static void sdwrite_read(QTestState *qts, const char *msg)
+{
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message using sdhci */
+sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
+
+/* read message from sd */
+int fd = open(sd_path, O_RDONLY);
+int ret = read(fd, rmsg, len);
+close(fd);
+g_assert(ret == len);
+
+g_assert(!strcmp(rmsg, msg));
+
+free(rmsg);
+}
+
+/* Check MMC can write values to sd */
+static void test_write_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+sdwrite_read(qts, "hello world");
+sdwrite_read(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+/* Check SDHCI has correct default values. */
+static void test_reset(void)
+{
+QTestState *qts = qtest_init("-machine quanta-gbs-bmc");
+
+uint64_t addr = NPCM7XX_MMC_BA;
+uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
+uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
+  NPCM7XX_PRSTVALS_1_RESET,
+  0,
+  NPCM7XX_PRSTVALS_3_RESET,
+  0,
+  0};
+int i;
+uint32_t mask;
+while (addr < end_addr) {
+switch (addr - NPCM7XX_MMC_BA) {
+case SDHC_PRNSTS:
+/* ignores bits 20 to 24: they are changed when reading registers 
*/
+mask = 0x1f0;
+g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
+NPCM7XX_PRSNTS_RESET | mask);
+addr 

[PATCH 0/4] hw/arm: Add MMC device for NPCM7XX boards

2021-09-07 Thread Hao Wu
This patch set implements the Nuvoton MMC device
for NPCM7XX boards.

The MMC device is compatible with the SDHCI interface
in QEMU. It allows the user to attach an SD card image
to it.

Shengtan Mao (4):
  tests/qtest/libqos: add SDHCI commands
  hw/sd: add nuvoton MMC
  hw/arm: Attach MMC to quanta-gbs-bmc
  tests/qtest: add qtests for npcm7xx sdhci

 hw/arm/npcm7xx.c |  12 +-
 hw/arm/npcm7xx_boards.c  |  21 
 hw/sd/meson.build|   1 +
 hw/sd/npcm7xx_sdhci.c| 131 
 include/hw/arm/npcm7xx.h |   2 +
 include/hw/sd/npcm7xx_sdhci.h|  65 ++
 tests/qtest/libqos/meson.build   |   1 +
 tests/qtest/libqos/sdhci-cmd.c   | 116 ++
 tests/qtest/libqos/sdhci-cmd.h   |  70 +++
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_sdhci-test.c | 201 +++
 11 files changed, 620 insertions(+), 1 deletion(-)
 create mode 100644 hw/sd/npcm7xx_sdhci.c
 create mode 100644 include/hw/sd/npcm7xx_sdhci.h
 create mode 100644 tests/qtest/libqos/sdhci-cmd.c
 create mode 100644 tests/qtest/libqos/sdhci-cmd.h
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

-- 
2.33.0.153.gba50c8fa24-goog




[PATCH 1/4] tests/qtest/libqos: add SDHCI commands

2021-09-07 Thread Hao Wu
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
---
 tests/qtest/libqos/meson.build |   1 +
 tests/qtest/libqos/sdhci-cmd.c | 116 +
 tests/qtest/libqos/sdhci-cmd.h |  70 
 3 files changed, 187 insertions(+)
 create mode 100644 tests/qtest/libqos/sdhci-cmd.c
 create mode 100644 tests/qtest/libqos/sdhci-cmd.h

diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 1f5c8f1053..4af1f04787 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -5,6 +5,7 @@ libqos_srcs = files('../libqtest.c',
 'fw_cfg.c',
 'malloc.c',
 'libqos.c',
+'sdhci-cmd.c',
 
 # spapr
 'malloc-spapr.c',
diff --git a/tests/qtest/libqos/sdhci-cmd.c b/tests/qtest/libqos/sdhci-cmd.c
new file mode 100644
index 00..2d9e518341
--- /dev/null
+++ b/tests/qtest/libqos/sdhci-cmd.c
@@ -0,0 +1,116 @@
+/*
+ * MMC Host Controller Commands
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * 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.
+ */
+
+#include "qemu/osdep.h"
+#include "sdhci-cmd.h"
+#include "libqtest.h"
+
+static ssize_t read_fifo(QTestState *qts, uint64_t reg, char *msg, size_t 
count)
+{
+uint32_t mask = 0xff;
+size_t index = 0;
+uint32_t msg_frag;
+int size;
+while (index < count) {
+size = count - index;
+if (size > 4) {
+size = 4;
+}
+msg_frag = qtest_readl(qts, reg);
+while (size > 0) {
+msg[index] = msg_frag & mask;
+if (msg[index++] == 0) {
+return index;
+}
+msg_frag >>= 8;
+--size;
+}
+}
+return index;
+}
+
+static void write_fifo(QTestState *qts, uint64_t reg, const char *msg,
+   size_t count)
+{
+size_t index = 0;
+uint32_t msg_frag;
+int size;
+int frag_i;
+while (index < count) {
+size = count - index;
+if (size > 4) {
+size = 4;
+}
+msg_frag = 0;
+frag_i = 0;
+while (frag_i < size) {
+msg_frag |= ((uint32_t)msg[index++]) << (frag_i * 8);
+++frag_i;
+}
+qtest_writel(qts, reg, msg_frag);
+}
+}
+
+static void fill_block(QTestState *qts, uint64_t reg, int count)
+{
+while (--count >= 0) {
+qtest_writel(qts, reg, 0);
+}
+}
+
+void sdhci_cmd_regs(QTestState *qts, uint64_t base_addr, uint16_t blksize,
+uint16_t blkcnt, uint32_t argument, uint16_t trnmod,
+uint16_t cmdreg)
+{
+qtest_writew(qts, base_addr + SDHC_BLKSIZE, blksize);
+qtest_writew(qts, base_addr + SDHC_BLKCNT, blkcnt);
+qtest_writel(qts, base_addr + SDHC_ARGUMENT, argument);
+qtest_writew(qts, base_addr + SDHC_TRNMOD, trnmod);
+qtest_writew(qts, base_addr + SDHC_CMDREG, cmdreg);
+}
+
+ssize_t sdhci_read_cmd(QTestState *qts, uint64_t base_addr, char *msg,
+   size_t count)
+{
+sdhci_cmd_regs(qts, base_addr, count, 1, 0,
+   SDHC_TRNS_MULTI | SDHC_TRNS_READ | SDHC_TRNS_BLK_CNT_EN,
+   SDHC_READ_MULTIPLE_BLOCK | SDHC_CMD_DATA_PRESENT);
+
+/* read sd fifo_buffer */
+ssize_t bytes_read = read_fifo(qts, base_addr + SDHC_BDATA, msg, count);
+
+sdhci_cmd_regs(qts, base_addr, 0, 0, 0,
+   SDHC_TRNS_MULTI | SDHC_TRNS_READ | SDHC_TRNS_BLK_CNT_EN,
+   SDHC_STOP_TRANSMISSION);
+
+return bytes_read;
+}
+
+void sdhci_write_cmd(QTestState *qts, uint64_t base_addr, const char *msg,
+ size_t count, size_t blksize)
+{
+sdhci_cmd_regs(qts, base_addr, blksize, 1, 0,
+   SDHC_TRNS_MULTI | SDHC_TRNS_WRITE | SDHC_TRNS_BLK_CNT_EN,
+   SDHC_WRITE_MULTIPLE_BLOCK | SDHC_CMD_DATA_PRESENT);
+
+/* write to sd fifo_buffer */
+write_fifo(qts, base_addr + SDHC_BDATA, msg, count);
+fill_block(qts, base_addr + SDHC_BDATA, (blksize - count) / 4);
+
+sdhci_cmd_regs(qts, base_addr, 0, 0, 0,
+   SDHC_TRNS_MULTI | SDHC_TRNS_WRITE | SDHC_TRNS_BLK_CNT_EN,
+   SDHC_STOP_TRANSMISSION);
+}
diff --git a/tests/qtest/libqos/sdhci-cmd.h b/tests/qtest/libqos/sdhci-cmd.h
new file mode 100644
index 00..64763c5a2a
--- /dev/null
+++ b/tests/qtest/libqos/sdhci-cmd.h
@@ -0,0 +1,70 @@
+/*
+ * MMC Host Controller Commands
+ *
+ * Copyright (c) 2021 Google LLC
+ *

[PATCH 3/4] hw/arm: Attach MMC to quanta-gbs-bmc

2021-09-07 Thread Hao Wu
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Reviewed-by: Hao Wu 
Reviewed-by: Tyrone Ting 
---
 hw/arm/npcm7xx_boards.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index e5a3243995..7205483280 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -27,6 +27,10 @@
 #include "qemu-common.h"
 #include "qemu/datadir.h"
 #include "qemu/units.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
+
 
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
@@ -80,6 +84,22 @@ static void npcm7xx_connect_dram(NPCM7xxState *soc, 
MemoryRegion *dram)
  _abort);
 }
 
+static void sdhci_attach_drive(SDHCIState *sdhci)
+{
+DriveInfo *di = drive_get_next(IF_SD);
+BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
+
+BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
+if (bus == NULL) {
+error_report("No SD bus found in SOC object");
+exit(1);
+}
+
+DeviceState *carddev = qdev_new(TYPE_SD_CARD);
+qdev_prop_set_drive_err(carddev, "drive", blk, _fatal);
+qdev_realize_and_unref(carddev, bus, _fatal);
+}
+
 static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
 uint32_t hw_straps)
 {
@@ -354,6 +374,7 @@ static void quanta_gbs_init(MachineState *machine)
   drive_get(IF_MTD, 0, 0));
 
 quanta_gbs_i2c_init(soc);
+sdhci_attach_drive(>mmc.sdhci);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.33.0.153.gba50c8fa24-goog




Re: arm: Launching EFI-enabled arm32 Linux

2021-09-07 Thread Adam Lackorzynski
Hi Andre,

On Mon Sep 06, 2021 at 16:34:03 +0100, Andre Przywara wrote:
> On Sat, 4 Sep 2021 21:26:45 +0200
> Adam Lackorzynski  wrote:
> 
> Hi Adam,
> 
> > while trying to launch an EFI-enabled arm32 Linux binary (zImage) I
> > noticed I get an undefined instruction exception on the first
> > instruction. Now this is a bit special because Linux uses a nop
> > instruction there that also is a PE file signature ('MZ') such that the
> > CPU runs over it and the file is still recognized as a PE binary. Linux
> > uses 0x13105a4d (tstne r0, #0x4d000) as the instruction (see also
> > arch/arm/boot/compressed/head.S and efi-header.S in Linux).
> > However, QEMU's instruction decoder will only recognize TST with bits
> > 12-15 being 0, which this instruction is not fullfilling, and thus the
> > undef exception. I guess other CPU implementations will allow this
> > encoding. So while investigating I was doing the following to make Linux
> > proceed. I also believe this was working in a previous version of QEMU.
> > 
> > diff --git a/target/arm/a32.decode b/target/arm/a32.decode
> > index fcd8cd4f7d..222553750e 100644
> > --- a/target/arm/a32.decode
> > +++ b/target/arm/a32.decode
> > @@ -127,7 +127,7 @@ ADD_rri   001 0100 .    
> >   @s_rri_rot
> >  ADC_rri   001 0101 .      @s_rri_rot
> >  SBC_rri   001 0110 .      @s_rri_rot
> >  RSC_rri   001 0111 .      @s_rri_rot
> > -TST_xri   001 1000 1      @S_xri_rot
> > +TST_xri   001 1000 1      @S_xri_rot
> >  TEQ_xri   001 1001 1      @S_xri_rot
> >  CMP_xri   001 1010 1      @S_xri_rot
> >  CMN_xri   001 1011 1      @S_xri_rot
> > 
> > 
> > Any thoughts on this?
> 
> thanks for the report, I was looking at this and have a kernel patch
> to fix this properly as Peter suggested. And while I agree on the
> problem, I was struggling to reproduce this in reality: both with
> -kernel and when booting through U-Boot the "Z" bit is set, which lets
> QEMU not even bother about the rest of the encoding - the condition
> flags don't match, so it proceeds. If I change the __nop to use "tsteq",
> I see it hanging due to the missing exception handler, but not with
> "tstne".
> So can you say how you spotted this issue? This would be needed as a
> justification for patching the guts of the ARM Linux kernel port.

Good point with the condition flags. I'm doing this with our own vmm
where I'm loading the binary directly as the payload (as mandated by the
header), and where psr is set to a defined value with all flags cleared.
If I set the Z bit than it also works (of course).
Looking a bit around in QEMU as well as u-boot I it looks like this is
rather by luck how flags are set.

Thanks for doing the Linux patch, I'll scrap mine, and also thanks to
Peter for the idea!


Adam



Re: [PATCH v3 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines

2021-09-07 Thread Alistair Francis
On Mon, Aug 30, 2021 at 3:36 PM Alistair Francis
 wrote:
>
> From: Alistair Francis 
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer MIP bits.
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Philippe Mathieu-Daudé 
> Reviewed-by: Richard Henderson 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  include/hw/timer/ibex_timer.h |  2 ++
>  hw/riscv/opentitan.c  |  3 +++
>  hw/timer/ibex_timer.c | 17 -
>  3 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
> index 6a43537003..b6f69b38ee 100644
> --- a/include/hw/timer/ibex_timer.h
> +++ b/include/hw/timer/ibex_timer.h
> @@ -48,5 +48,7 @@ struct IbexTimerState {
>  uint32_t timebase_freq;
>
>  qemu_irq irq;
> +
> +qemu_irq m_timer_irq;
>  };
>  #endif /* HW_IBEX_TIMER_H */
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> index 048aced0ec..f7cfcf1c3a 100644
> --- a/hw/riscv/opentitan.c
> +++ b/hw/riscv/opentitan.c
> @@ -183,6 +183,9 @@ static void lowrisc_ibex_soc_realize(DeviceState 
> *dev_soc, Error **errp)
>  sysbus_connect_irq(SYS_BUS_DEVICE(>timer),
> 0, qdev_get_gpio_in(DEVICE(>plic),
> IBEX_TIMER_TIMEREXPIRED0_0));
> +qdev_connect_gpio_out(DEVICE(>timer), 0,
> +  qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
> +   IRQ_M_TIMER));
>
>  create_unimplemented_device("riscv.lowrisc.ibex.gpio",
>  memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
> diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> index 5befb53506..66e1f8e48c 100644
> --- a/hw/timer/ibex_timer.c
> +++ b/hw/timer/ibex_timer.c
> @@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>  /*
>   * If the mtimecmp was in the past raise the interrupt now.
>   */
> -riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +qemu_irq_raise(s->m_timer_irq);
>  if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>  s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>  qemu_set_irq(s->irq, true);
> @@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>  }
>
>  /* Setup a timer to trigger the interrupt in the future */
> -riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +qemu_irq_lower(s->m_timer_irq);
>  qemu_set_irq(s->irq, false);
>
>  diff = cpu->env.timecmp - now;
> @@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>  static void ibex_timer_cb(void *opaque)
>  {
>  IbexTimerState *s = opaque;
> -CPUState *cs = qemu_get_cpu(0);
> -RISCVCPU *cpu = RISCV_CPU(cs);
>
> -riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +qemu_irq_raise(s->m_timer_irq);
>  if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>  s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>  qemu_set_irq(s->irq, true);
> @@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
>  sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
>  }
>
> +static void ibex_timer_realize(DeviceState *dev, Error **errp)
> +{
> +IbexTimerState *s = IBEX_TIMER(dev);
> +
> +qdev_init_gpio_out(dev, >m_timer_irq, 1);
> +}
> +
> +
>  static void ibex_timer_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>
>  dc->reset = ibex_timer_reset;
>  dc->vmsd = _ibex_timer;
> +dc->realize = ibex_timer_realize;
>  device_class_set_props(dc, ibex_timer_properties);
>  }
>
> --
> 2.31.1
>



[PATCH v2] hw/arm: Add support for kudo-bmc board.

2021-09-07 Thread Chris Rauer
kudo-bmc is a board supported by OpenBMC.
https://github.com/openbmc/openbmc/tree/master/meta-fii/meta-kudo

Since v1:
- hyphenated Cortex-A9

Tested: Booted kudo firmware.
Signed-off-by: Chris Rauer 
---
 docs/system/arm/nuvoton.rst |  1 +
 hw/arm/npcm7xx_boards.c | 34 ++
 2 files changed, 35 insertions(+)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 69f57c2886..adf497e679 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -20,6 +20,7 @@ Hyperscale applications. The following machines are based on 
this chip :
 
 - ``quanta-gbs-bmc``Quanta GBS server BMC
 - ``quanta-gsj``Quanta GSJ server BMC
+- ``kudo-bmc``  Fii USA Kudo server BMC
 
 There are also two more SoCs, NPCM710 and NPCM705, which are single-core
 variants of NPCM750 and NPCM730, respectively. These are currently not
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index e5a3243995..a656169f61 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -31,6 +31,7 @@
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
 #define QUANTA_GBS_POWER_ON_STRAPS 0x17ff
+#define KUDO_BMC_POWER_ON_STRAPS 0x1fff
 
 static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
 
@@ -357,6 +358,23 @@ static void quanta_gbs_init(MachineState *machine)
 npcm7xx_load_kernel(machine, soc);
 }
 
+static void kudo_bmc_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, KUDO_BMC_POWER_ON_STRAPS);
+npcm7xx_connect_dram(soc, machine->ram);
+qdev_realize(DEVICE(soc), NULL, _fatal);
+
+npcm7xx_load_bootrom(machine, soc);
+npcm7xx_connect_flash(>fiu[0], 0, "mx66u51235f",
+  drive_get(IF_MTD, 0, 0));
+npcm7xx_connect_flash(>fiu[1], 0, "mx66u51235f",
+  drive_get(IF_MTD, 3, 0));
+
+npcm7xx_load_kernel(machine, soc);
+}
+
 static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
 {
 NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
@@ -417,6 +435,18 @@ static void gbs_bmc_machine_class_init(ObjectClass *oc, 
void *data)
 mc->default_ram_size = 1 * GiB;
 }
 
+static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
+MachineClass *mc = MACHINE_CLASS(oc);
+
+npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
+
+mc->desc = "Kudo BMC (Cortex-A9)";
+mc->init = kudo_bmc_init;
+mc->default_ram_size = 1 * GiB;
+};
+
 static const TypeInfo npcm7xx_machine_types[] = {
 {
 .name   = TYPE_NPCM7XX_MACHINE,
@@ -437,6 +467,10 @@ static const TypeInfo npcm7xx_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
 .parent = TYPE_NPCM7XX_MACHINE,
 .class_init = gbs_bmc_machine_class_init,
+}, {
+.name   = MACHINE_TYPE_NAME("kudo-bmc"),
+.parent = TYPE_NPCM7XX_MACHINE,
+.class_init = kudo_bmc_machine_class_init,
 },
 };
 
-- 
2.33.0.153.gba50c8fa24-goog




[PULL 42/42] bsd-user: Update mapping to handle reserved and starting conditions

2021-09-07 Thread imp
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.

This has 18e80c55bb6 from linux-user folded in to the upstream
bsd-user code as well.

Signed-off-by: Mikaël Urankar 
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 bsd-user/main.c |  43 -
 bsd-user/mmap.c | 415 
 bsd-user/qemu.h |   5 +-
 3 files changed, 392 insertions(+), 71 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 6df4f4f011..48643eeabc 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -52,10 +52,47 @@
 #include "target_arch_cpu.h"
 
 int singlestep;
-unsigned long mmap_min_addr;
 uintptr_t guest_base;
 bool have_guest_base;
+/*
+ * 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.
+ *
+ * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
+ * of the address for the kernel.  Some cpus rely on this and user space
+ * uses the high bit(s) for pointer tagging and the like.  For them, we
+ * must preserve the expected address space.
+ */
+#ifndef MAX_RESERVED_VA
+# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
+#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
+  (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
+/*
+ * There are a number of places where we assign reserved_va to a variable
+ * of type abi_ulong and expect it to fit.  Avoid the last page.
+ */
+#   define MAX_RESERVED_VA  (0xul & TARGET_PAGE_MASK)
+#  else
+#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
+#  endif
+# else
+#  define MAX_RESERVED_VA  0
+# endif
+#endif
+
+/*
+ * That said, reserving *too* much vm space via mmap can run into problems
+ * with rlimits, oom due to page table creation, etc.  We will still try it,
+ * if directed by the command-line option, but not by default.
+ */
+#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
+unsigned long reserved_va = MAX_RESERVED_VA;
+#else
 unsigned long reserved_va;
+#endif
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
@@ -439,6 +476,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;
+}
+
 {
 Error *err = NULL;
 if (seed_optarg != NULL) {
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 8918c4ae68..b40ab9045f 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -188,64 +188,207 @@ 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;
+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;
 
-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);
+while (1) {

[PULL 38/42] bsd-user: Refactor load_elf_sections and is_target_elf_binary

2021-09-07 Thread imp
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 
Reviewed-by: Kyle Evans 
---
 bsd-user/elfload.c | 344 +
 1 file changed, 158 insertions(+), 186 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 3660961582..142a5bfac2 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,93 +321,33 @@ 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
  * address in qemu, we allocate a big enough memory zone.
  */
-error = target_mmap(0, INTERP_MAP_SIZE, PROT_NONE,
+rbase = 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) + 

[PULL 36/42] bsd-user: add stubbed out core dump support

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfcore.c | 10 ++
 bsd-user/elfload.c | 22 --
 bsd-user/qemu.h|  6 ++
 3 files changed, 36 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..c49d9280e2
--- /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 = { 0 };
+
+bswap_note();
+
+return 0;
+}
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 11ca813c7a..05751f3ce7 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -26,15 +26,17 @@
 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 inline void memcpy_fromfs(void *to, const void *from, unsigned long n)
 {
 memcpy(to, from, n);
@@ -100,15 +102,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
@@ -834,6 +846,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 3685156123..8d20554688 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -51,6 +51,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;
@@ -65,6 +66,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
@@ -132,6 +136,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);
@@ -145,6 +150,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




[PULL 34/42] bsd-user: Add target_arch_reg to describe a target's register set

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 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;
+

[PULL 40/42] bsd-user: Implement interlock for atomic operations

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 768f4ee41e..659dd2b512 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -69,15 +69,39 @@ 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




[PULL 39/42] bsd-user: move gemu_log to later in the file

2021-09-07 Thread imp
From: Warner Losh 

Signed-off-by: Warner Losh 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 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 71fd9d5aba..768f4ee41e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -69,14 +69,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)
 {
@@ -165,6 +157,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




[PULL 33/42] bsd-user: update debugging in mmap.c

2021-09-07 Thread imp
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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 bsd-user/mmap.c | 55 ++---
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 03119b1f20..8918c4ae68 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,47 @@ 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_FIXED)
+if (flags & MAP_ALIGNMENT_MASK) {
+printf("MAP_ALIGNED(%u) ", (flags & MAP_ALIGNMENT_MASK)
+>> MAP_ALIGNMENT_SHIFT);
+}
+#if MAP_GUARD
+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:
+}
+#ifdef MAP_EXCL
+if (flags & MAP_EXCL) {
+printf("MAP_EXCL ");
+}
+#endif
+if (flags & MAP_PRIVATE) {
 printf("MAP_PRIVATE ");
-break;
-case MAP_SHARED:
+}
+if (flags & 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);
+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 +418,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 +435,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




Re: [PATCH v2] Prevent vhost-user-blk-test hang

2021-09-07 Thread ebl...@redhat.com
On Mon, Sep 06, 2021 at 01:25:20PM +, Raphael Norwitz wrote:
> In the vhost-user-blk-test, as of now there is nothing stoping
> vhost-user-blk in QEMU writing to the socket right after forking off the
> storage daemon before it has a chance to come up properly, leaving the
> test hanging forever. This intermittently hanging test has caused QEMU
> automation failures reported multiple times on the mailing list [1].
> 
> This change makes the storage-daemon notify the vhost-user-blk-test
> that it is fully initialized and ready to handle client connections by
> creating a pidfile on initialiation. This ensures that the storage-daemon
> backend won't miss vhost-user messages and thereby resolves the hang.
> 
> [1] 
> https://lore.kernel.org/qemu-devel/CAFEAcA8kYpz9LiPNxnWJAPSjc=nv532bedyfynabemeohqb...@mail.gmail.com/
> 
> Signed-off-by: Raphael Norwitz 
> ---
>  tests/qtest/vhost-user-blk-test.c | 33 ++-
>  1 file changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/vhost-user-blk-test.c 
> b/tests/qtest/vhost-user-blk-test.c
> index 6f108a1b62..78140e6f28 100644
> --- a/tests/qtest/vhost-user-blk-test.c
> +++ b/tests/qtest/vhost-user-blk-test.c
> @@ -24,6 +24,9 @@
>  #define TEST_IMAGE_SIZE (64 * 1024 * 1024)
>  #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
>  #define PCI_SLOT_HP 0x06
> +#define PIDFILE_RETRIES 5
> +
> +const char *pidfile_format = "/tmp/daemon-%d";

Why is this not static?  In fact...

>  
>  typedef struct {
>  pid_t pid;
> @@ -885,7 +888,8 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
>   int num_queues)
>  {
>  const char *vhost_user_blk_bin = qtest_qemu_storage_daemon_binary();
> -int i;
> +int i, err, retries;
> +char *daemon_pidfile_path;
>  gchar *img_path;
>  GString *storage_daemon_command = g_string_new(NULL);
>  QemuStorageDaemonState *qsd;
> @@ -898,6 +902,12 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
>  " -object memory-backend-memfd,id=mem,size=256M,share=on "
>  " -M memory-backend=mem -m 256M ");
>  
> +err = asprintf(_pidfile_path, pidfile_format, getpid());

...action at a distance makes it harder for gcc to warn about bad
formats.  I'd just inline "/tmp/daemon-%d" here in the asprintf call,
and drop pidfile_format altogether.

Why are we using bare asprintf instead of glib's g_strdup_printf?

> +if (err == -1) {
> +fprintf(stderr, "Failed to format storage-daemon pidfile name %m");

%m in printf is a glibc-ism; not portable to non-Linux.  Do we care?

> +abort();

Rather than directly abort, since this is a glib test runner, is there
a glib function we should be using?  For example, using
g_assert_cmpint((err, !=, -1)?

> +}
> +
>  for (i = 0; i < vus_instances; i++) {
>  int fd;
>  char *sock_path = create_listen_socket();
> @@ -914,6 +924,9 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
> i + 1, sock_path);
>  }
>  
> +g_string_append_printf(storage_daemon_command, "--pidfile %s",

Missing a space on the tail end if there are more arguments to append
to the command line.

> +   daemon_pidfile_path);
> +
>  g_test_message("starting vhost-user backend: %s",
> storage_daemon_command->str);
>  pid_t pid = fork();
> @@ -930,7 +943,25 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
>  execlp("/bin/sh", "sh", "-c", storage_daemon_command->str, NULL);
>  exit(1);
>  }
> +
> +/*
> + * Ensure the storage-daemon has come up properly before allowing the
> + * test to proceed.
> + */
> +retries = 0;
> +while (access(daemon_pidfile_path, F_OK) != 0) {
> +if (retries > PIDFILE_RETRIES) {
> +fprintf(stderr, "The storage-daemon failed to come up after %d "
> +"seconds - killing the test", PIDFILE_RETRIES);
> +abort();

Again, would some form of g_assert*() be better than bare abort?

> +}
> +
> +retries++;
> +usleep(1000);

We're inconsistent on whether qtest files use bare usleep or g_usleep.

> +}
> +
>  g_string_free(storage_daemon_command, true);
> +free(daemon_pidfile_path);

Do you want to unlink() the file (if it exists)?

>  
>  qsd = g_new(QemuStorageDaemonState, 1);
>  qsd->pid = pid;
> -- 
> 2.20.1
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




[PULL 26/42] bsd-user: *BSD specific siginfo defintions

2021-09-07 Thread imp
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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 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   |  69 +
 bsd-user/openbsd/target_os_siginfo.h |  82 +++
 bsd-user/openbsd/target_os_signal.h  |  69 +
 bsd-user/qemu.h  |   1 +
 bsd-user/syscall_defs.h  |  10 --
 bsd-user/x86_64/target_arch_signal.h |  94 +
 10 files changed, 714 insertions(+), 10 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..84944faa4d
--- /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) 

[PULL 35/42] bsd-user: Add target_os_user.h to capture the user/kernel structures

2021-09-07 Thread imp
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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 bsd-user/freebsd/target_os_user.h | 427 ++
 1 file changed, 427 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..95b1fa9f99
--- /dev/null
+++ b/bsd-user/freebsd/target_os_user.h
@@ -0,0 +1,427 @@
+/*
+ *  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
+
+#define TARGET_KF_TYPE_NONE 0
+#define TARGET_KF_TYPE_VNODE1
+#define TARGET_KF_TYPE_SOCKET   2
+#define TARGET_KF_TYPE_PIPE 3
+#define TARGET_KF_TYPE_FIFO 4
+#define TARGET_KF_TYPE_KQUEUE   5
+#define TARGET_KF_TYPE_CRYPTO   6
+#define TARGET_KF_TYPE_MQUEUE   7
+#define TARGET_KF_TYPE_SHM  8
+#define TARGET_KF_TYPE_SEM  9
+#define TARGET_KF_TYPE_PTS  10
+#define TARGET_KF_TYPE_PROCDESC 11
+#define TARGET_KF_TYPE_DEV  12
+#define TARGET_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 */
+

[PULL 41/42] bsd-user: Add '-0 argv0' option to bsd-user/main.c

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 659dd2b512..6df4f4f011 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -243,6 +243,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();
 
@@ -367,6 +368,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();
 }
@@ -390,6 +393,9 @@ int main(int argc, char **argv)
 usage();
 }
 filename = argv[optind];
+if (argv0) {
+argv[optind] = argv0;
+}
 
 if (!trace_init_backends()) {
 exit(1);
-- 
2.32.0




[PULL 27/42] bsd-user: Implement --seed and initialize random state

2021-09-07 Thread imp
From: Warner Losh 

Copy --seed implementation (translated from linux-user's newer command
line scheme to the older one bsd-user still uses). Initialize the
randomness with the glib if a specific seed is specified or use the
qcrypto library if not.

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

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 19bf3a09a7..71fd9d5aba 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -45,6 +45,8 @@
 #include "qemu/cutils.h"
 #include "exec/log.h"
 #include "trace/control.h"
+#include "crypto/init.h"
+#include "qemu/guest-random.h"
 
 #include "host-os.h"
 #include "target_arch_cpu.h"
@@ -203,6 +205,7 @@ int main(int argc, char **argv)
 const char *cpu_type;
 const char *log_file = NULL;
 const char *log_mask = NULL;
+const char *seed_optarg = NULL;
 struct target_pt_regs regs1, *regs = 
 struct image_info info1, *info = 
 struct bsd_binprm bprm;
@@ -331,6 +334,8 @@ int main(int argc, char **argv)
 usage();
 }
 optind++;
+} else if (!strcmp(r, "seed")) {
+seed_optarg = optarg;
 } else if (!strcmp(r, "singlestep")) {
 singlestep = 1;
 } else if (!strcmp(r, "strace")) {
@@ -403,6 +408,19 @@ int main(int argc, char **argv)
 target_environ = envlist_to_environ(envlist, NULL);
 envlist_free(envlist);
 
+{
+Error *err = NULL;
+if (seed_optarg != NULL) {
+qemu_guest_random_seed_main(seed_optarg, );
+} else {
+qcrypto_init();
+}
+if (err) {
+error_reportf_err(err, "cannot initialize crypto: ");
+exit(1);
+}
+}
+
 /*
  * Now that page sizes are configured we can do
  * proper page alignment for guest_base.
-- 
2.32.0




[PULL 37/42] bsd-user: elfload.c style catch up patch

2021-09-07 Thread imp
From: Warner Losh 

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

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 208 ++---
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 05751f3ce7..3660961582 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -143,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;
@@ -156,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;
@@ -182,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);
@@ -210,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 - end_addr1,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-}
+/*
+ * 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 

[PULL 32/42] bsd-user: Rewrite target system call definintion glue

2021-09-07 Thread imp
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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 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 

[PULL 24/42] bsd-user: Create target specific vmparam.h

2021-09-07 Thread imp
From: Warner Losh 

Target specific values for vm parameters and details.

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/freebsd/target_os_vmparam.h  | 38 ++
 bsd-user/i386/target_arch_vmparam.h   | 46 +++
 bsd-user/qemu.h   |  1 +
 bsd-user/x86_64/target_arch_vmparam.h | 46 +++
 4 files changed, 131 insertions(+)
 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..990300c619
--- /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..bb7718265b
--- /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  (128 * MiB) /* max text size */
+#define TARGET_DFLDSIZ  (128 * MiB) /* initial data size limit */
+#define TARGET_MAXDSIZ  (512 * MiB) /* max data size */
+#define TARGET_DFLSSIZ  (8 * MiB)   /* initial stack size limit */
+#define TARGET_MAXSSIZ  (64 * MiB)  /* max stack size */
+#define TARGET_SGROWSIZ (128 * KiB) /* 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 fea1a167e4..1b37757e06 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -41,6 +41,7 @@ extern enum BSDType bsd_type;
 #include "target_arch.h"
 #include "syscall_defs.h"
 #include "target_syscall.h"
+#include "target_os_vmparam.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..81a915f2e5
--- /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,
+ *  but WITHOUT ANY WARRANTY; 

[PULL 31/42] bsd-user: Remove dead #ifdefs from elfload.c

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 6156f9775d..11ca813c7a 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);
@@ -843,15 +832,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




[PULL 22/42] bsd-user: Include more things in qemu.h

2021-09-07 Thread imp
From: Warner Losh 

Include more header files to match bsd-user fork.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/qemu.h | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5e4cbb40d4..55d71130bb 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -18,12 +18,12 @@
 #define QEMU_H
 
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
 
 #undef DEBUG_REMAP
-#ifdef DEBUG_REMAP
-#endif /* DEBUG_REMAP */
 
 #include "exec/user/abitypes.h"
 
@@ -36,6 +36,8 @@ 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 "exec/gdbstub.h"
-- 
2.32.0




[PULL 30/42] bsd-user: elf cleanup

2021-09-07 Thread imp
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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 bsd-user/elfload.c   | 191 ---
 bsd-user/freebsd/target_os_elf.h | 137 ++
 bsd-user/netbsd/target_os_elf.h  | 146 +++
 bsd-user/openbsd/target_os_elf.h | 146 +++
 bsd-user/qemu.h  |   1 +
 5 files changed, 454 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 59465b71d4..6156f9775d 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,
- 

[PULL 28/42] bsd-user: Move stack initializtion into a per-os file.

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 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..1bb1a2bf56
--- /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"
+#include "qemu/guest-random.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);
+
+/* 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;
+}
+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. */
+qemu_guest_getrandom_nofail(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 

[PULL 29/42] bsd-user: Add architecture specific signal tramp code

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 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..cb4e89b0b0
--- /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 0;
+}
+#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..29d4a8b55f
--- /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 0;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
-- 
2.32.0




[PULL 16/42] bsd-user: add host-os.h

2021-09-07 Thread imp
From: Warner Losh 

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

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 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..bd3f2892db
--- /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..d4bbc7d58f
--- /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..ae23bfef64
--- /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




[PULL 20/42] bsd-user: Move per-cpu code into target_arch_cpu.h

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/target_arch_cpu.c   |   1 +
 bsd-user/i386/target_arch_cpu.h   | 209 
 bsd-user/main.c   | 317 ++
 bsd-user/qemu.h   |   1 +
 bsd-user/x86_64/target_arch_cpu.c |   1 +
 bsd-user/x86_64/target_arch_cpu.h | 247 +++
 6 files changed, 473 insertions(+), 303 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..978e8066af
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -0,0 +1,209 @@
+/*
+ *  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);

[PULL 21/42] bsd-user: pull in target_arch_thread.h update target_arch_elf.h

2021-09-07 Thread imp
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). FreeBSD doesn't do
AT_HWCAP, so remove that code. Linux does, and this code came from there.

These changes are all interrelated and could be brokend down, 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 
Reviewed-by: Kyle Evans 
---
 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, 171 insertions(+), 85 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 ccb1744800..c28ef34143 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 84f61bd930..eb760e07fa 100644
--- a/bsd-user/i386/target_arch_elf.h
+++ b/bsd-user/i386/target_arch_elf.h
@@ -19,62 +19,16 @@
 #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
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
+#define ELF_ET_DYN_LOAD_ADDR0x01001000
 #define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486))
 
-/*
- * These are used to set parameters in the core dumps.
- */
+#define ELF_HWCAP   0 /* FreeBSD doesn't do AT_HWCAP{,2} on x86 */
+
 #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 

[PULL 23/42] bsd-user: define max args in terms of pages

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/qemu.h | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 55d71130bb..fea1a167e4 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "qemu/units.h"
 #include "exec/cpu_ldst.h"
 #include "exec/exec-all.h"
 
@@ -101,11 +102,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 * KiB)
+#else
+#define TARGET_ARG_MAX (256 * KiB)
+#endif
+#define MAX_ARG_PAGES (TARGET_ARG_MAX / TARGET_PAGE_SIZE)
 
 /*
  * This structure is used to hold the arguments that are
-- 
2.32.0




[PULL 25/42] bsd-user: Add system independent stack, data and text limiting

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c |  2 +-
 bsd-user/main.c| 52 +-
 bsd-user/qemu.h|  7 ++-
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index c28ef34143..59465b71d4 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 3d4ed202a0..19bf3a09a7 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,23 @@ 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 +216,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 +278,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 

[PULL 11/42] bsd-user: Eliminate elf personality

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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 ? 

[PULL 14/42] bsd-user: elfload: simplify bswap a bit.

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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 4f3fa83c2c..ccb1744800 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 

[PULL 17/42] bsd-user: Include host-os.h from main

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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 bd3f2892db..dfb8344b7b 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 e06cc7b414..607fdd8380 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 d4bbc7d58f..c0be51a7ef 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 ae23bfef64..eb8fdf1567 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




[PULL 19/42] bsd-user: start to move target CPU functions to target_arch*

2021-09-07 Thread imp
From: Warner Losh 

Move the CPU functions 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 
Reviewed-by: Richard Henderson 
---
 bsd-user/i386/target_arch.h   | 31 +
 bsd-user/i386/target_arch_cpu.c   | 75 +++
 bsd-user/main.c   | 35 ---
 bsd-user/x86_64/target_arch.h | 31 +
 bsd-user/x86_64/target_arch_cpu.c | 75 +++
 configure |  7 +--
 meson.build   |  7 ++-
 7 files changed, 218 insertions(+), 43 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 d7c8a3e348..f7c75df64d 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,
   

[PULL 12/42] bsd-user: remove a.out support

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 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 32f7fd5dec..6aefc7a28b 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..4f3fa83c2c 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;

[PULL 13/42] bsd-user: TARGET_NGROUPS unused in this file, remove

2021-09-07 Thread imp
From: Warner Losh 

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

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 6aefc7a28b..5b3c061a45 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




[PULL 10/42] bsd-user: implement path searching

2021-09-07 Thread imp
From: Warner Losh 

Use the PATH to find the executable given a bare argument. We need to do
this so we can implement mixing native and emulated binaries (e.g.,
execing a x86 native binary from an emulated arm binary to optimize
parts of the build). By finding the binary, we will know how to exec it.

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

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 379015c744..32f7fd5dec 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -139,21 +139,55 @@ 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;
+}
+
 int loader_exec(const char *filename, char **argv, char **envp,
 struct target_pt_regs *regs, struct image_info *infop,
 struct bsd_binprm *bprm)
 {
+char *path, 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;
+}
+} else {
+path = g_find_program_in_path(filename);
+if (path == NULL) {
+return -1;
+}
+}
+
+retval = open(path, O_RDONLY);
 if (retval < 0) {
+g_free(path);
 return retval;
 }
 
+bprm->fullpath = path;
 bprm->fd = retval;
 bprm->filename = (char *)filename;
 bprm->argc = count(argv);
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




[PULL 18/42] bsd-user: save the path to the qemu emulator

2021-09-07 Thread imp
From: 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 
Acked-by: Richard Henderson 
Reviewed-by: Kyle Evans 
---
 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 607fdd8380..d7c8a3e348 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 = sizeof(qemu_proc_pathname);
+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




[PULL 06/42] bsd-user: Remove all non-x86 code from elfload.c

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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 

[PULL 07/42] bsd-user: move arch specific defines out of elfload.c

2021-09-07 Thread imp
From: Warner Losh 

Move the architecture specific defines to target_arch_elf.h and delete
them from elfload.c. Only retain ifdefs appropriate for i386 and x86_64.
Add the copyright/license comments, and guard ifdefs.

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 bsd-user/elfload.c| 81 +--
 bsd-user/i386/target_arch_elf.h   | 81 +++
 bsd-user/x86_64/target_arch_elf.h | 67 +
 slirp |  2 +-
 4 files changed, 151 insertions(+), 80 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..84f61bd930
--- /dev/null
+++ b/bsd-user/i386/target_arch_elf.h
@@ -0,0 +1,81 @@
+/*
+ *  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()
+
+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   

[PULL 08/42] bsd-user: pass the bsd_param into loader_exec

2021-09-07 Thread imp
From: Warner Losh 

Pass the bsd_param into loader_exec, and adjust. We use it to track the
inital stack allocation and to set stack, open files, and other state
shared between bsdload.c and elfload.c

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 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 39c4a0f33c..1388c7a13d 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));
 
@@ -566,7 +570,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




[PULL 15/42] bsd-user: assume pthreads and support of __thread

2021-09-07 Thread imp
From: Warner Losh 

All compilers for some time have supported this. Follow linux-user and
eliminate the #define THREAD and unconditionally insert __thread where
needed. Please insert: "(see 24cb36a61c6: "configure: Make NPTL
non-optional")"

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 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 1388c7a13d..e06cc7b414 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




[PULL 01/42] bsd-user: remove sparc and sparc64

2021-09-07 Thread imp
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 
Reviewed-by: Richard Henderson 
---
 bsd-user/main.c| 289 -
 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, 477 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..38185da111 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 = 

[PULL 03/42] bsd-user: Add Stacey's copyright to main.c

2021-09-07 Thread imp
From: Warner Losh 

Add Stacey's updated copyright to main.c

Signed-off-by: Warner Losh 
Signed-off-by: Stacey Son 
Reviewed-by: Richard Henderson 
---
 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 38185da111..39c4a0f33c 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




[PULL 05/42] bsd-user: style nits: bsdload.c whitespace to qemu standard

2021-09-07 Thread imp
From: Warner Losh 

Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 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 0ade58b9e2..ec71c5e923 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -140,7 +140,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;
@@ -148,7 +148,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




[PULL 09/42] bsd-user: Fix calculation of size to allocate

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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




[PULL 04/42] bsd-user: add license to bsdload.c

2021-09-07 Thread imp
From: 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 
Reviewed-by: Richard Henderson 
---
 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 8d83f21eda..0ade58b9e2 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




[PULL 02/42] bsd-user: add copyright header to elfload.c

2021-09-07 Thread imp
From: Warner Losh 

Add Stacey's copyright to elfload.c

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
Reviewed-by: Richard Henderson 
---
 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




[PULL 00/42] bsd-user updates to run hello world

2021-09-07 Thread imp
From: Warner Losh 

The following changes since commit f214d8e0150766c31172e16ef4b17674f549d852:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210826' 
into staging (2021-08-26 18:03:57 +0100)

are available in the Git repository at:

  https://gitlab.com/bsdimp/qemu.git tags/bsd-user-pull-20210907-tag

for you to fetch changes up to dc96376e46a52ac63a27ea185c3f0a6fd54e3c82:

  bsd-user: Update mapping to handle reserved and starting conditions 
(2021-09-07 08:26:53 -0600)



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.

v2: rejected patches dropped
Use suggested glibc routines
Updated to be closer to qemu style
Disable bsd-user on netbsd and openbsd since they don't compile
fold together a couple of related changes
[[ tagged the review-by and acked-by from last series, but by hand...
  I think I got them all... ]]

v3:

Re: [PATCH v3 9/9] iotests: add nbd-reconnect-on-open test

2021-09-07 Thread Eric Blake
On Mon, Sep 06, 2021 at 10:06:54PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  .../qemu-iotests/tests/nbd-reconnect-on-open  | 71 +++
>  .../tests/nbd-reconnect-on-open.out   | 11 +++
>  2 files changed, 82 insertions(+)
>  create mode 100755 tests/qemu-iotests/tests/nbd-reconnect-on-open
>  create mode 100644 tests/qemu-iotests/tests/nbd-reconnect-on-open.out

I'm less confident in my review of the python code, but...

> 
> diff --git a/tests/qemu-iotests/tests/nbd-reconnect-on-open 
> b/tests/qemu-iotests/tests/nbd-reconnect-on-open
> new file mode 100755
> index 00..7ee9bce947
> --- /dev/null
> +++ b/tests/qemu-iotests/tests/nbd-reconnect-on-open
> @@ -0,0 +1,71 @@

> +
> +def create_args(open_timeout):
> +return ['--image-opts', '-c', 'read 0 1M',
> +f'driver=nbd,open-timeout={open_timeout},'
> +f'server.type=unix,server.path={nbd_sock}']
> +
> +
> +def check_fail_to_connect(open_timeout):
> +log(f'Check fail to connect with {open_timeout} seconds of timeout')
> +
> +start_t = time.time()
> +qemu_io_log(*create_args(open_timeout))
> +delta_t = time.time() - start_t
> +
> +max_delta = open_timeout + 0.2

Is this fractional delay going to bite us on heavily-loaded CI machines?

> +if open_timeout <= delta_t <= max_delta:
> +log(f'qemu_io finished in {open_timeout}..{max_delta} seconds, OK')
> +else:
> +note = 'too early' if delta_t < open_timeout else 'too long'
> +log(f'qemu_io finished in {delta_t:.1f} seconds, {note}')
> +
> +
> +qemu_img_create('-f', iotests.imgfmt, disk, '1M')
> +
> +# Start NBD client when NBD server is not yet running. It should not fail, 
> but
> +# wait for 5 seconds for the server to be available.
> +client = qemu_io_popen(*create_args(5))
> +
> +time.sleep(1)
> +qemu_nbd('-k', nbd_sock, '-f', iotests.imgfmt, disk)
> +
> +# client should succeed
> +log(client.communicate()[0], filters=[iotests.filter_qemu_io])
> +
> +# Server was started without --persistent flag, so it should be off now. 
> Let's
> +# check it and it the same time check that with open-timeout=0 client fails

check it and at

> +# immediately.
> +check_fail_to_connect(0)
> +
> +# Check that we will fail after non-zero timeout if server is still 
> unavailable
> +check_fail_to_connect(1)
> diff --git a/tests/qemu-iotests/tests/nbd-reconnect-on-open.out 
> b/tests/qemu-iotests/tests/nbd-reconnect-on-open.out
> new file mode 100644
> index 00..a35ae30ea4
> --- /dev/null
> +++ b/tests/qemu-iotests/tests/nbd-reconnect-on-open.out
> @@ -0,0 +1,11 @@
> +read 1048576/1048576 bytes at offset 0
> +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +
> +Check fail to connect with 0 seconds of timeout
> +qemu-io: can't open: Failed to connect to 'TEST_DIR/PID-nbd-sock': No such 
> file or directory
> +
> +qemu_io finished in 0..0.2 seconds, OK
> +Check fail to connect with 1 seconds of timeout
> +qemu-io: can't open: Failed to connect to 'TEST_DIR/PID-nbd-sock': No such 
> file or directory
> +
> +qemu_io finished in 1..1.2 seconds, OK

Overall, the test looks like a nice demonstration of the feature: you
are showing that the client can now start before the server, and that
the retry for N seconds is handled gracefully both by the creation of
the server and by the expiration of the retry timeout.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v3 5/9] nbd/client-connection: improve error message of cancelled attempt

2021-09-07 Thread Eric Blake
On Mon, Sep 06, 2021 at 10:06:50PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  nbd/client-connection.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake 

> 
> diff --git a/nbd/client-connection.c b/nbd/client-connection.c
> index 722998c985..2bda42641d 100644
> --- a/nbd/client-connection.c
> +++ b/nbd/client-connection.c
> @@ -351,8 +351,15 @@ nbd_co_establish_connection(NBDClientConnection *conn, 
> NBDExportInfo *info,
>  if (conn->err) {
>  error_propagate(errp, error_copy(conn->err));
>  } else {
> -error_setg(errp,
> -   "Connection attempt cancelled by other 
> operation");
> +/*
> + * The only possible case here is cancelling by open_timer
> + * during nbd_open(). So, the error message is for that case.
> + * If we have more use cases, we can refactor
> + * nbd_co_establish_connection_cancel() to take an additional
> + * parameter cancel_reason, that would be passed than to the
> + * caller of cancelled nbd_co_establish_connection().
> + */
> +error_setg(errp, "Connection attempt cancelled by timeout");
>  }
>  
>  return NULL;
> -- 
> 2.29.2
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v3 4/9] nbd/client-connection: nbd_co_establish_connection(): return real error

2021-09-07 Thread Eric Blake
On Mon, Sep 06, 2021 at 10:06:49PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> The only user of errp is call to nbd_do_establish_connection() in
> nbd_open(). The only way to cancel this call is through open_timer

The only caller of nbd_do_establish_connection() that uses errp is
nbd_open().

> timeout. And for this case, user will be more interested in description
> of last failed connect rather than in
> "Connection attempt cancelled by other operation".
> 
> So, let's change behavior on cancel to return previous failure error if
> available.
> 
> Do the same for non-blocking failure case. In this case we still don't
> have a caller that is interested in errp. But let's be consistent.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  nbd/client-connection.c | 50 -
>  1 file changed, 34 insertions(+), 16 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v3 3/9] nbd: allow reconnect on open, with corresponding new options

2021-09-07 Thread Eric Blake
On Mon, Sep 06, 2021 at 10:06:48PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> It is useful when start of vm and start of nbd server are not
> simple to sync.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  qapi/block-core.json |  9 -
>  block/nbd.c  | 45 +++-
>  2 files changed, 52 insertions(+), 2 deletions(-)
>

Reviewed-by: Eric Blake 

This is when qemu is acting as NBD client (and does not affect qemu
acting as NBD server).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




Re: [PULL 00/20] s390x patches

2021-09-07 Thread Peter Maydell
On Tue, 7 Sept 2021 at 14:15, Thomas Huth  wrote:
>
>  Hi Peter!
>
> The following changes since commit 935efca6c246c108253b0e4e51cc87648fc7ca10:
>
>   Merge remote-tracking branch 
> 'remotes/thuth-gitlab/tags/pull-request-2021-09-06' into staging (2021-09-06 
> 12:38:07 +0100)
>
> are available in the Git repository at:
>
>   https://gitlab.com/thuth/qemu.git tags/s390x-pull-request-2021-09-07
>
> for you to fetch changes up to 30e398f796d882d829162a16ab7c920f7422da3b:
>
>   s390x/cpumodel: Add more feature to gen16 default model (2021-09-07 
> 13:36:43 +0200)
>
> (Cornelia is currently on vacation, so I'm doing the s390x patches this time)
>
> 
> * Some CSS related fixes
> * Storage key related fixes
> * Test SIGILL and SIGSEGV handling in usermode emulation
> * Fix SETPREFIX instruction
> * Replace PAGE_SIZE, PAGE_SHIFT and PAGE_MASK to fix Alpine compilation
> * Add more feature to gen16 default model


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.2
for any user-visible changes.

-- PMM



Re: [PATCH] meson: look up cp and dtrace with find_program()

2021-09-07 Thread Marc-André Lureau
Hi

On Tue, Sep 7, 2021 at 9:27 PM Paolo Bonzini  wrote:

> Avoid that meson prints a "Program xyz found" test once per
> custom_target.
>
> Signed-off-by: Paolo Bonzini 
>

Reviewed-by: Marc-André Lureau 

Is there a meson bug already?


> ---
>  pc-bios/keymaps/meson.build | 3 ++-
>  trace/meson.build   | 5 +++--
>  2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
> index 05eda6c0d2..44247a12b5 100644
> --- a/pc-bios/keymaps/meson.build
> +++ b/pc-bios/keymaps/meson.build
> @@ -38,6 +38,7 @@ if meson.is_cross_build() or 'CONFIG_XKBCOMMON' not in
> config_host
>  else
>native_qemu_keymap = qemu_keymap
>  endif
> +cp = find_program('cp')
>
>  t = []
>  foreach km, args: keymaps
> @@ -55,7 +56,7 @@ foreach km, args: keymaps
> build_by_default: true,
> input: km,
> output: km,
> -   command: ['cp', '@INPUT@', '@OUTPUT@'],
> +   command: [cp, '@INPUT@', '@OUTPUT@'],
> install: true,
> install_dir: qemu_datadir / 'keymaps')
>endif
> diff --git a/trace/meson.build b/trace/meson.build
> index 74c3214a13..54e509c17c 100644
> --- a/trace/meson.build
> +++ b/trace/meson.build
> @@ -2,6 +2,7 @@
>  specific_ss.add(files('control-target.c'))
>
>  trace_events_files = []
> +dtrace = find_program('dtrace')
>  foreach dir : [ '.' ] + trace_events_subdirs
>trace_events_file = meson.project_source_root() / dir / 'trace-events'
>trace_events_files += [ trace_events_file ]
> @@ -39,13 +40,13 @@ foreach dir : [ '.' ] + trace_events_subdirs
>  trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'),
> output: fmt.format('trace-dtrace',
> 'h'),
> input: trace_dtrace,
> -   command: [ 'dtrace', '-DSTAP_SDT_V2',
> '-o', '@OUTPUT@', '-h', '-s', '@INPUT@' ])
> +   command: [ dtrace, '-DSTAP_SDT_V2',
> '-o', '@OUTPUT@', '-h', '-s', '@INPUT@' ])
>  trace_ss.add(trace_dtrace_h)
>  if host_machine.system() != 'darwin'
>trace_dtrace_o = custom_target(fmt.format('trace-dtrace', 'o'),
>   output: fmt.format('trace-dtrace',
> 'o'),
>   input: trace_dtrace,
> - command: [ 'dtrace',
> '-DSTAP_SDT_V2', '-o', '@OUTPUT@', '-G', '-s', '@INPUT@' ])
> + command: [ dtrace, '-DSTAP_SDT_V2',
> '-o', '@OUTPUT@', '-G', '-s', '@INPUT@' ])
>trace_ss.add(trace_dtrace_o)
>  endif
>
> --
> 2.31.1
>
>
>

-- 
Marc-André Lureau


Re: [PATCH v1 3/3] migration: multifd: Enable zerocopy

2021-09-07 Thread Peter Xu
On Thu, Sep 02, 2021 at 04:22:55AM -0300, Leonardo Bras Soares Passos wrote:
> > I don't think it is valid to unconditionally enable this feature due to the
> > resource usage implications
> >
> > https://www.kernel.org/doc/html/v5.4/networking/msg_zerocopy.html
> >
> >   "A zerocopy failure will return -1 with errno ENOBUFS. This happens
> >if the socket option was not set, the socket exceeds its optmem
> >limit or the user exceeds its ulimit on locked pages."
> 
> You are correct, I unfortunately missed this part in the docs :(
> 
> > The limit on locked pages is something that looks very likely to be
> > exceeded unless you happen to be running a QEMU config that already
> > implies locked memory (eg PCI assignment)
> 
> Do you mean the limit an user has on locking memory?
> 
> If so, that makes sense. I remember I needed to set the upper limit of locked
> memory for the user before using it, or adding a capability to qemu before.

So I'm a bit confused on why MSG_ZEROCOPY requires checking RLIMIT_MEMLOCK.

The thing is IIUC that's accounting for pinned pages only with either mlock()
(FOLL_MLOCK) or vfio (FOLL_PIN).

I don't really think MSG_ZEROCOPY is doing that at all...  I'm looking at
__zerocopy_sg_from_iter() -> iov_iter_get_pages().

Say, I think there're plenty of iov_iter_get_pages() callers and normal GUPs, I
think most of them do no need such accountings.

-- 
Peter Xu




  1   2   3   4   5   >