Re: [PATCH] hw/smbios: Add table 4 parameter, "processor-id"

2022-01-18 Thread Igor Mammedov
On Tue, 18 Jan 2022 09:15:42 -0800
Patrick Venture  wrote:

> On Tue, Jan 11, 2022 at 5:13 AM Igor Mammedov  wrote:
> 
> > On Thu,  6 Jan 2022 14:33:16 -0800
> > Patrick Venture  wrote:
> >  
[...]
> > > diff --git a/qemu-options.hx b/qemu-options.hx
> > > index ec90505d84..3c51b6cf8f 100644
> > > --- a/qemu-options.hx
> > > +++ b/qemu-options.hx
> > > @@ -2527,6 +2527,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
> > >  "specify SMBIOS type 3 fields\n"
> > >  "-smbios  
> > type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str]\n"  
> > >  "  
> > [,asset=str][,part=str][,max-speed=%d][,current-speed=%d]\n"  
> > > +"  [,processor-id=%d]\n"
> > >  "specify SMBIOS type 4 fields\n"
> > >  "-smbios type=11[,value=str][,path=filename]\n"
> > >  "specify SMBIOS type 11 fields\n"  
> >
> > missing update of SRST part
> >  
> 
> I grepped for SRST, where is this that I need to update also?

option definition has 2 parts DEF() and SRST that follows right
after it, the later is used as help text for the option
SRST
 
``-smbios file=binary`` 
...

> 
> Thanks!




Re: [PATCH v2 3/3] roms/opensbi: Remove ELF images

2022-01-18 Thread Bin Meng
On Tue, Jan 18, 2022 at 7:18 PM Anup Patel  wrote:
>
> Now that all RISC-V machines can use OpenSBI BIN images, we remove
> OpenSBI ELF images and also exclude these images from BIOS build.
>
> Signed-off-by: Anup Patel 
> ---
>  pc-bios/meson.build|   2 --
>  pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | Bin 838904 -> 0 bytes
>  pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | Bin 934696 -> 0 bytes
>  roms/Makefile  |   2 --
>  4 files changed, 4 deletions(-)
>  delete mode 100644 pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
>  delete mode 100644 pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
>

.gitlab-ci.d/opensbi.yml should also be updated to remove .elf build

Otherwise,
Reviewed-by: Bin Meng 



Re: [PATCH v2 1/3] hw/riscv: spike: Allow using binary firmware as bios

2022-01-18 Thread Bin Meng
On Tue, Jan 18, 2022 at 7:18 PM Anup Patel  wrote:
>
> Currently, we have to use OpenSBI firmware ELF as bios for the spike
> machine because the HTIF console requires ELF for parsing "fromhost"
> and "tohost" symbols.
>
> The latest OpenSBI can now optionally pick-up HTIF register address
> from HTIF DT node so using this feature spike machine can now use
> OpenSBI firmware BIN as bios.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/char/riscv_htif.c | 33 +++--
>  hw/riscv/spike.c | 41 ++--
>  include/hw/char/riscv_htif.h |  5 -
>  include/hw/riscv/spike.h |  1 +
>  4 files changed, 52 insertions(+), 28 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 2/3] hw/riscv: Remove macros for ELF BIOS image names

2022-01-18 Thread Bin Meng
On Tue, Jan 18, 2022 at 7:18 PM Anup Patel  wrote:
>
> Now that RISC-V Spike machine can use BIN BIOS images, we remove
> the macros used for ELF BIOS image names.
>
> Signed-off-by: Anup Patel 
> ---
>  hw/riscv/spike.c| 4 ++--
>  include/hw/riscv/boot.h | 2 --
>  2 files changed, 2 insertions(+), 4 deletions(-)
>

Reviewed-by: Bin Meng 



[PATCH v7 22/22] target/riscv: Relax UXL field for debugging

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 90f78eca65..c6b2407a06 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -584,7 +584,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
 MSTATUS_TW | MSTATUS_VS;
 
-if (xl != MXL_RV32) {
+if (xl != MXL_RV32 || env->debugger) {
 /*
  * RV32: MPV and GVA are not in mstatus. The current plan is to
  * add them to mstatush. For now, we just don't support it.
@@ -909,7 +909,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int 
csrno,
target_ulong *val)
 {
 target_ulong mask = (sstatus_v1_10_mask);
-if (env->xl != MXL_RV32) {
+if (env->xl != MXL_RV32 || env->debugger) {
 mask |= SSTATUS64_UXL;
 }
 /* TODO: Use SXL not MXL. */
@@ -921,7 +921,8 @@ static RISCVException write_sstatus(CPURISCVState *env, int 
csrno,
 target_ulong val)
 {
 target_ulong mask = (sstatus_v1_10_mask);
-if (env->xl != MXL_RV32) {
+
+if (env->xl != MXL_RV32 || env->debugger) {
 mask |= SSTATUS64_UXL;
 }
 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
-- 
2.25.1




[PATCH v7 20/22] target/riscv: Adjust scalar reg in vector with XLEN

2022-01-18 Thread LIU Zhiwei
When sew <= 32bits, not need to extend scalar reg.
When sew > 32bits, if xlen is less that sew, we should sign extend
the scalar register, except explicitly specified by the spec.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index e03959c46f..f85a9e83b4 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1258,7 +1258,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2, uint32_t vm,
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
 src2 = tcg_temp_new_ptr();
-src1 = get_gpr(s, rs1, EXT_NONE);
+src1 = get_gpr(s, rs1, EXT_SIGN);
 
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-- 
2.25.1




[PATCH v7 17/22] target/riscv: Remove VILL field in VTYPE

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Acked-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fe58ccaeae..55635d68d5 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -111,7 +111,6 @@ FIELD(VTYPE, VTA, 6, 1)
 FIELD(VTYPE, VMA, 7, 1)
 FIELD(VTYPE, VEDIV, 8, 2)
 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
-FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
 target_ulong gpr[32];
-- 
2.25.1




[PATCH v7 14/22] target/riscv: Split pm_enabled into mask and base

2022-01-18 Thread LIU Zhiwei
Use cached cur_pmmask and cur_pmbase to infer the
current PM mode.

This may decrease the TCG IR by one when pm_enabled
is true and pm_base_enabled is false.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  3 ++-
 target/riscv/cpu_helper.c | 24 ++--
 target/riscv/translate.c  | 12 
 3 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6fe842edfd..89621e1996 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -448,7 +448,8 @@ FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
 FIELD(TB_FLAGS, XL, 20, 2)
 /* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b239d721f4..502aee84ab 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -97,27 +97,15 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
 }
-if (riscv_has_ext(env, RVJ)) {
-int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
-bool pm_enabled = false;
-switch (priv) {
-case PRV_U:
-pm_enabled = env->mmte & U_PM_ENABLE;
-break;
-case PRV_S:
-pm_enabled = env->mmte & S_PM_ENABLE;
-break;
-case PRV_M:
-pm_enabled = env->mmte & M_PM_ENABLE;
-break;
-default:
-g_assert_not_reached();
-}
-flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
-}
 #endif
 
 flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
+if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
+flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
+}
+if (env->cur_pmbase != 0) {
+flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
+}
 
 *pflags = flags;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 33564d059d..f0bbe80875 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -108,7 +108,8 @@ typedef struct DisasContext {
 /* Space for 3 operands plus 1 extra for address computation. */
 TCGv temp[4];
 /* PointerMasking extension */
-bool pm_enabled;
+bool pm_mask_enabled;
+bool pm_base_enabled;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -397,12 +398,14 @@ static TCGv get_address(DisasContext *ctx, int rs1, int 
imm)
 TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
 
 tcg_gen_addi_tl(addr, src1, imm);
-if (ctx->pm_enabled) {
+if (ctx->pm_mask_enabled) {
 tcg_gen_and_tl(addr, addr, pm_mask);
-tcg_gen_or_tl(addr, addr, pm_base);
 } else if (get_xl(ctx) == MXL_RV32) {
 tcg_gen_ext32u_tl(addr, addr);
 }
+if (ctx->pm_base_enabled) {
+tcg_gen_or_tl(addr, addr, pm_base);
+}
 return addr;
 }
 
@@ -925,7 +928,8 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->cs = cs;
 ctx->ntemp = 0;
 memset(ctx->temp, 0, sizeof(ctx->temp));
-ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
+ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
+ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
 ctx->zero = tcg_constant_tl(0);
 }
 
-- 
2.25.1




[PATCH v7 18/22] target/riscv: Fix check range for first fault only

2022-01-18 Thread LIU Zhiwei
Only check the range that has passed the address translation.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8b7c9ec890..efb3129532 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -500,12 +500,12 @@ vext_ldff(void *vd, void *v0, target_ulong base,
  cpu_mmu_index(env, false));
 if (host) {
 #ifdef CONFIG_USER_ONLY
-if (page_check_range(addr, nf << esz, PAGE_READ) < 0) {
+if (page_check_range(addr, offset, PAGE_READ) < 0) {
 vl = i;
 goto ProbeSuccess;
 }
 #else
-probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
+probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
 #endif
 } else {
 vl = i;
-- 
2.25.1




[PATCH v7 16/22] target/riscv: Adjust vsetvl according to XLEN

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   | 5 +
 target/riscv/vector_helper.c | 7 +--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6c740b92c1..fe58ccaeae 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -491,6 +491,11 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
 }
 #endif
 
+static inline int riscv_cpu_xlen(CPURISCVState *env)
+{
+return 16 << env->xl;
+}
+
 /*
  * Encode LMUL to lmul as follows:
  * LMULvlmullmul
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a9484c22ea..8b7c9ec890 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -36,8 +36,11 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
 uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
 uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
 uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
-bool vill = FIELD_EX64(s2, VTYPE, VILL);
-target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+int xlen = riscv_cpu_xlen(env);
+bool vill = (s2 >> (xlen - 1)) & 0x1;
+target_ulong reserved = s2 &
+MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
+xlen - 1 - R_VTYPE_RESERVED_SHIFT);
 
 if (lmul & 4) {
 /* Fractional LMUL. */
-- 
2.25.1




[PATCH v7 09/22] target/riscv: Relax debug check for pm write

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9be2820d2b..c00a82022e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1556,6 +1556,9 @@ static bool check_pm_current_disabled(CPURISCVState *env, 
int csrno)
 int csr_priv = get_field(csrno, 0x300);
 int pm_current;
 
+if (env->debugger) {
+return false;
+}
 /*
  * If priv lvls differ that means we're accessing csr from higher priv lvl,
  * so allow the access
-- 
2.25.1




[PATCH v7 13/22] target/riscv: Calculate address according to XLEN

2022-01-18 Thread LIU Zhiwei
Define one common function to compute a canonical address from a register
plus offset. Merge gen_pm_adjust_address into this function.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rva.c.inc |  9 +++--
 target/riscv/insn_trans/trans_rvd.c.inc | 19 ++-
 target/riscv/insn_trans/trans_rvf.c.inc | 19 ++-
 target/riscv/insn_trans/trans_rvi.c.inc | 18 ++
 target/riscv/translate.c| 25 -
 5 files changed, 21 insertions(+), 69 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
b/target/riscv/insn_trans/trans_rva.c.inc
index 86032fa9a7..45db82c9be 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -20,12 +20,11 @@
 
 static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+TCGv src1 = get_address(ctx, a->rs1, 0);
 
 if (a->rl) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
 }
-src1 = gen_pm_adjust_address(ctx, src1);
 tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
 if (a->aq) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -44,8 +43,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 TCGLabel *l1 = gen_new_label();
 TCGLabel *l2 = gen_new_label();
 
-src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
-src1 = gen_pm_adjust_address(ctx, src1);
+src1 = get_address(ctx, a->rs1, 0);
 tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
 /*
@@ -83,10 +81,9 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
 MemOp mop)
 {
 TCGv dest = dest_gpr(ctx, a->rd);
-TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+TCGv src1 = get_address(ctx, a->rs1, 0);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 
-src1 = gen_pm_adjust_address(ctx, src1);
 func(dest, src1, src2, ctx->mem_idx, mop);
 
 gen_set_gpr(ctx, a->rd, dest);
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index ed444b042a..091ed3a8ad 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -25,14 +25,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 REQUIRE_FPU;
 REQUIRE_EXT(ctx, RVD);
 
-addr = get_gpr(ctx, a->rs1, EXT_NONE);
-if (a->imm) {
-TCGv temp = temp_new(ctx);
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
-addr = gen_pm_adjust_address(ctx, addr);
-
+addr = get_address(ctx, a->rs1, a->imm);
 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
 
 mark_fs_dirty(ctx);
@@ -46,16 +39,8 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 REQUIRE_FPU;
 REQUIRE_EXT(ctx, RVD);
 
-addr = get_gpr(ctx, a->rs1, EXT_NONE);
-if (a->imm) {
-TCGv temp = temp_new(ctx);
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
-addr = gen_pm_adjust_address(ctx, addr);
-
+addr = get_address(ctx, a->rs1, a->imm);
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
-
 return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index b5459249c4..0aac87f7db 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -31,14 +31,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 REQUIRE_FPU;
 REQUIRE_EXT(ctx, RVF);
 
-addr = get_gpr(ctx, a->rs1, EXT_NONE);
-if (a->imm) {
-TCGv temp = temp_new(ctx);
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
-addr = gen_pm_adjust_address(ctx, addr);
-
+addr = get_address(ctx, a->rs1, a->imm);
 dest = cpu_fpr[a->rd];
 tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
 gen_nanbox_s(dest, dest);
@@ -54,16 +47,8 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 REQUIRE_FPU;
 REQUIRE_EXT(ctx, RVF);
 
-addr = get_gpr(ctx, a->rs1, EXT_NONE);
-if (a->imm) {
-TCGv temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
-addr = gen_pm_adjust_address(ctx, addr);
-
+addr = get_address(ctx, a->rs1, a->imm);
 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
-
 return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 631bc1f09e..3cd1b3f877 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -226,14 +226,7 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
 TCGv dest = dest_gpr(ctx, a->rd);
-TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
-
-if (a->imm) {
-TCGv temp = temp_new(ctx);
-

[PATCH v7 15/22] target/riscv: Split out the vill from vtype

2022-01-18 Thread LIU Zhiwei
We need not specially process vtype when XLEN changes.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   |  1 +
 target/riscv/cpu_helper.c|  3 +--
 target/riscv/csr.c   | 13 -
 target/riscv/machine.c   |  5 +++--
 target/riscv/vector_helper.c |  3 ++-
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 89621e1996..6c740b92c1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -125,6 +125,7 @@ struct CPURISCVState {
 target_ulong vl;
 target_ulong vstart;
 target_ulong vtype;
+bool vill;
 
 target_ulong pc;
 target_ulong load_res;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 502aee84ab..327a2c4f1d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -60,8 +60,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 uint32_t maxsz = vlmax << sew;
 bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
(maxsz >= 8);
-flags = FIELD_DP32(flags, TB_FLAGS, VILL,
-FIELD_EX64(env->vtype, VTYPE, VILL));
+flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
 flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
 flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
 FIELD_EX64(env->vtype, VTYPE, VLMUL));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 292f7e1624..b11d92b51b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -283,7 +283,18 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
 static RISCVException read_vtype(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
-*val = env->vtype;
+uint64_t vill;
+switch (env->xl) {
+case MXL_RV32:
+vill = (uint32_t)env->vill << 31;
+break;
+case MXL_RV64:
+vill = (uint64_t)env->vill << 63;
+break;
+default:
+g_assert_not_reached();
+}
+*val = (target_ulong)vill | env->vtype;
 return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index a4b7859c2a..740e11fcff 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -124,8 +124,8 @@ static bool vector_needed(void *opaque)
 
 static const VMStateDescription vmstate_vector = {
 .name = "cpu/vector",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .needed = vector_needed,
 .fields = (VMStateField[]) {
 VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
@@ -134,6 +134,7 @@ static const VMStateDescription vmstate_vector = {
 VMSTATE_UINTTL(env.vl, RISCVCPU),
 VMSTATE_UINTTL(env.vstart, RISCVCPU),
 VMSTATE_UINTTL(env.vtype, RISCVCPU),
+VMSTATE_BOOL(env.vill, RISCVCPU),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ad505ec9b2..a9484c22ea 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -52,7 +52,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
 || (ediv != 0)
 || (reserved != 0)) {
 /* only set vill bit. */
-env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+env->vill = 1;
+env->vtype = 0;
 env->vl = 0;
 env->vstart = 0;
 return 0;
-- 
2.25.1




[PATCH v7 06/22] target/riscv: Ignore the pc bits above XLEN

2022-01-18 Thread LIU Zhiwei
The read from PC for translation is in cpu_get_tb_cpu_state, before translation.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8ebcd57af0..d73925a823 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -43,7 +43,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 
 uint32_t flags = 0;
 
-*pc = env->pc;
+*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
 *cs_base = 0;
 
 if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) 
{
-- 
2.25.1




[PATCH v7 11/22] target/riscv: Create current pm fields in env

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h|  4 
 target/riscv/cpu_helper.c | 43 +++
 target/riscv/csr.c| 19 +
 target/riscv/machine.c|  1 +
 5 files changed, 68 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 690c879901..a120d474df 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -430,6 +430,7 @@ static void riscv_cpu_reset(DeviceState *dev)
 env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
 env->xl = riscv_cpu_mxl(env);
+riscv_cpu_update_mask(env);
 cs->exception_index = RISCV_EXCP_NONE;
 env->load_res = -1;
 set_default_nan_mode(1, >fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7657e22a56..6fe842edfd 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -266,6 +266,8 @@ struct CPURISCVState {
 target_ulong upmmask;
 target_ulong upmbase;
 #endif
+target_ulong cur_pmmask;
+target_ulong cur_pmbase;
 
 float_status fp_status;
 
@@ -515,6 +517,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, 
target_ulong vtype)
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags);
 
+void riscv_cpu_update_mask(CPURISCVState *env);
+
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index d73925a823..b239d721f4 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -122,6 +122,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 *pflags = flags;
 }
 
+void riscv_cpu_update_mask(CPURISCVState *env)
+{
+target_ulong mask = -1, base = 0;
+/*
+ * TODO: Current RVJ spec does not specify
+ * how the extension interacts with XLEN.
+ */
+#ifndef CONFIG_USER_ONLY
+if (riscv_has_ext(env, RVJ)) {
+switch (env->priv) {
+case PRV_M:
+if (env->mmte & M_PM_ENABLE) {
+mask = env->mpmmask;
+base = env->mpmbase;
+}
+break;
+case PRV_S:
+if (env->mmte & S_PM_ENABLE) {
+mask = env->spmmask;
+base = env->spmbase;
+}
+break;
+case PRV_U:
+if (env->mmte & U_PM_ENABLE) {
+mask = env->upmmask;
+base = env->upmbase;
+}
+break;
+default:
+g_assert_not_reached();
+}
+}
+#endif
+if (env->xl == MXL_RV32) {
+env->cur_pmmask = mask & UINT32_MAX;
+env->cur_pmbase = base & UINT32_MAX;
+} else {
+env->cur_pmmask = mask;
+env->cur_pmbase = base;
+}
+}
+
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
@@ -334,6 +376,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
 /* tlb_flush is unnecessary as mode is contained in mmu_idx */
 env->priv = newpriv;
 env->xl = cpu_recompute_xl(env);
+riscv_cpu_update_mask(env);
 
 /*
  * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c00a82022e..292f7e1624 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1607,6 +1607,7 @@ static RISCVException write_mmte(CPURISCVState *env, int 
csrno,
 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
 env->mmte = wpri_val | PM_EXT_DIRTY;
+riscv_cpu_update_mask(env);
 
 /* Set XS and SD bits, since PM CSRs are dirty */
 mstatus = env->mstatus | MSTATUS_XS;
@@ -1682,6 +1683,9 @@ static RISCVException write_mpmmask(CPURISCVState *env, 
int csrno,
 uint64_t mstatus;
 
 env->mpmmask = val;
+if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+env->cur_pmmask = val;
+}
 env->mmte |= PM_EXT_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1707,6 +1711,9 @@ static RISCVException write_spmmask(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->spmmask = val;
+if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+env->cur_pmmask = val;
+}
 env->mmte |= PM_EXT_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1732,6 +1739,9 @@ static RISCVException write_upmmask(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->upmmask = val;
+if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+env->cur_pmmask = val;
+}
 env->mmte |= PM_EXT_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are 

[PATCH v7 21/22] target/riscv: Enable uxl field write

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b11d92b51b..90f78eca65 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -572,6 +572,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
 {
 uint64_t mstatus = env->mstatus;
 uint64_t mask = 0;
+RISCVMXL xl = riscv_cpu_mxl(env);
 
 /* flush tlb on mstatus fields that affect VM */
 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
@@ -583,21 +584,22 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
 MSTATUS_TW | MSTATUS_VS;
 
-if (riscv_cpu_mxl(env) != MXL_RV32) {
+if (xl != MXL_RV32) {
 /*
  * RV32: MPV and GVA are not in mstatus. The current plan is to
  * add them to mstatush. For now, we just don't support it.
  */
 mask |= MSTATUS_MPV | MSTATUS_GVA;
+if ((val & MSTATUS64_UXL) != 0) {
+mask |= MSTATUS64_UXL;
+}
 }
 
 mstatus = (mstatus & ~mask) | (val & mask);
 
-RISCVMXL xl = riscv_cpu_mxl(env);
 if (xl > MXL_RV32) {
-/* SXL and UXL fields are for now read only */
+/* SXL field is for now read only */
 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
-mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
 }
 env->mstatus = mstatus;
 env->xl = cpu_recompute_xl(env);
@@ -907,7 +909,9 @@ static RISCVException read_sstatus(CPURISCVState *env, int 
csrno,
target_ulong *val)
 {
 target_ulong mask = (sstatus_v1_10_mask);
-
+if (env->xl != MXL_RV32) {
+mask |= SSTATUS64_UXL;
+}
 /* TODO: Use SXL not MXL. */
 *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
 return RISCV_EXCP_NONE;
@@ -917,6 +921,9 @@ static RISCVException write_sstatus(CPURISCVState *env, int 
csrno,
 target_ulong val)
 {
 target_ulong mask = (sstatus_v1_10_mask);
+if (env->xl != MXL_RV32) {
+mask |= SSTATUS64_UXL;
+}
 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
 return write_mstatus(env, CSR_MSTATUS, newval);
 }
-- 
2.25.1




[PATCH v7 12/22] target/riscv: Alloc tcg global for cur_pm[mask|base]

2022-01-18 Thread LIU Zhiwei
Replace the array of pm_mask/pm_base with scalar variables.
Remove the cached array value in DisasContext.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/translate.c | 32 
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2a88bd99dc..43e2ec6dce 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -38,8 +38,8 @@ static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
 /* globals for PM CSRs */
-static TCGv pm_mask[4];
-static TCGv pm_base[4];
+static TCGv pm_mask;
+static TCGv pm_base;
 
 #include "exec/gen-icount.h"
 
@@ -109,8 +109,6 @@ typedef struct DisasContext {
 TCGv temp[4];
 /* PointerMasking extension */
 bool pm_enabled;
-TCGv pm_mask;
-TCGv pm_base;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -403,8 +401,8 @@ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
 return src;
 } else {
 temp = temp_new(s);
-tcg_gen_andc_tl(temp, src, s->pm_mask);
-tcg_gen_or_tl(temp, temp, s->pm_base);
+tcg_gen_andc_tl(temp, src, pm_mask);
+tcg_gen_or_tl(temp, temp, pm_base);
 return temp;
 }
 }
@@ -929,10 +927,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->ntemp = 0;
 memset(ctx->temp, 0, sizeof(ctx->temp));
 ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
-int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
-ctx->pm_mask = pm_mask[priv];
-ctx->pm_base = pm_base[priv];
-
 ctx->zero = tcg_constant_tl(0);
 }
 
@@ -1050,19 +1044,9 @@ void riscv_translate_init(void)
  "load_res");
 load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
  "load_val");
-#ifndef CONFIG_USER_ONLY
 /* Assign PM CSRs to tcg globals */
-pm_mask[PRV_U] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
-pm_base[PRV_U] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
-pm_mask[PRV_S] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
-pm_base[PRV_S] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
-pm_mask[PRV_M] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
-pm_base[PRV_M] =
-  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
-#endif
+pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmmask),
+ "pmmask");
+pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmbase),
+ "pmbase");
 }
-- 
2.25.1




[PATCH v7 04/22] target/riscv: Sign extend pc for different XLEN

2022-01-18 Thread LIU Zhiwei
When pc is written, it is sign-extended to fill the widest supported XLEN.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 .../riscv/insn_trans/trans_privileged.c.inc   |  2 +-
 target/riscv/insn_trans/trans_rvi.c.inc   |  5 ++--
 target/riscv/insn_trans/trans_rvv.c.inc   |  4 +--
 target/riscv/translate.c  | 25 ---
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
b/target/riscv/insn_trans/trans_privileged.c.inc
index 6077bbbf11..53613682e8 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -102,7 +102,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
 static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
 {
 #ifndef CONFIG_USER_ONLY
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_set_pc_imm(ctx, ctx->pc_succ_insn);
 gen_helper_wfi(cpu_env);
 return true;
 #else
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index b9ba57f266..04d3ea237f 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -59,6 +59,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
+gen_set_pc(ctx, cpu_pc);
 if (!has_ext(ctx, RVC)) {
 TCGv t0 = tcg_temp_new();
 
@@ -827,7 +828,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
  * FENCE_I is a no-op in QEMU,
  * however we need to end the translation block
  */
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_set_pc_imm(ctx, ctx->pc_succ_insn);
 tcg_gen_exit_tb(NULL, 0);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -836,7 +837,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
 static bool do_csr_post(DisasContext *ctx)
 {
 /* We may have changed important cpu state -- exit to main loop. */
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_set_pc_imm(ctx, ctx->pc_succ_insn);
 tcg_gen_exit_tb(NULL, 0);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 7a040b3089..e03959c46f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -194,7 +194,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, 
TCGv s2)
 gen_set_gpr(s, rd, dst);
 mark_vs_dirty(s);
 
-tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+gen_set_pc_imm(s, s->pc_succ_insn);
 tcg_gen_lookup_and_goto_ptr();
 s->base.is_jmp = DISAS_NORETURN;
 
@@ -219,7 +219,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, 
TCGv s2)
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(s, rd, dst);
 mark_vs_dirty(s);
-tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+gen_set_pc_imm(s, s->pc_succ_insn);
 tcg_gen_lookup_and_goto_ptr();
 s->base.is_jmp = DISAS_NORETURN;
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 30c0e28778..2a88bd99dc 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -193,16 +193,33 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
 tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
 }
 
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+{
+if (get_xl(ctx) == MXL_RV32) {
+dest = (int32_t)dest;
+}
+tcg_gen_movi_tl(cpu_pc, dest);
+}
+
+static void gen_set_pc(DisasContext *ctx, TCGv dest)
+{
+if (get_xl(ctx) == MXL_RV32) {
+tcg_gen_ext32s_tl(cpu_pc, dest);
+} else {
+tcg_gen_mov_tl(cpu_pc, dest);
+}
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_set_pc_imm(ctx, ctx->base.pc_next);
 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_set_pc_imm(ctx, ctx->base.pc_next);
 tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
 ctx->base.is_jmp = DISAS_NORETURN;
@@ -225,10 +242,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 {
 if (translator_use_goto_tb(>base, dest)) {
 tcg_gen_goto_tb(n);
-tcg_gen_movi_tl(cpu_pc, dest);
+gen_set_pc_imm(ctx, dest);
 tcg_gen_exit_tb(ctx->base.tb, n);
 } else {
-tcg_gen_movi_tl(cpu_pc, dest);
+gen_set_pc_imm(ctx, dest);
 tcg_gen_lookup_and_goto_ptr();
 }
 }
-- 
2.25.1




[PATCH v7 10/22] target/riscv: Adjust csr write mask with XLEN

2022-01-18 Thread LIU Zhiwei
Write mask is representing the bits we care about.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 12 
 target/riscv/op_helper.c|  3 ++-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 04d3ea237f..631bc1f09e 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -924,7 +924,8 @@ static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-if (get_xl(ctx) < MXL_RV128) {
+RISCVMXL xl = get_xl(ctx);
+if (xl < MXL_RV128) {
 TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
 
 /*
@@ -935,7 +936,8 @@ static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 return do_csrw(ctx, a->csr, src);
 }
 
-TCGv mask = tcg_constant_tl(-1);
+TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+ (target_ulong)-1);
 return do_csrrw(ctx, a->rd, a->csr, src, mask);
 } else {
 TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -1013,7 +1015,8 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
 
 static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 {
-if (get_xl(ctx) < MXL_RV128) {
+RISCVMXL xl = get_xl(ctx);
+if (xl < MXL_RV128) {
 TCGv src = tcg_constant_tl(a->rs1);
 
 /*
@@ -1024,7 +1027,8 @@ static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 return do_csrw(ctx, a->csr, src);
 }
 
-TCGv mask = tcg_constant_tl(-1);
+TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+ (target_ulong)-1);
 return do_csrrw(ctx, a->rd, a->csr, src, mask);
 } else {
 TCGv src = tcg_constant_tl(a->rs1);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 67693cb42b..1a75ba11e6 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -50,7 +50,8 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
 
 void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
-RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
+target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
+RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
 
 if (ret != RISCV_EXCP_NONE) {
 riscv_raise_exception(env, ret, GETPC());
-- 
2.25.1




[PATCH v7 19/22] target/riscv: Adjust vector address with mask

2022-01-18 Thread LIU Zhiwei
The mask comes from the pointer masking extension, or the max value
corresponding to XLEN bits.

Signed-off-by: LIU Zhiwei 
Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index efb3129532..020d2e841f 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -139,6 +139,11 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
uint32_t esz)
 return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
+static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
+{
+return (addr & env->cur_pmmask) | env->cur_pmbase;
+}
+
 /*
  * This function checks watchpoint before real load operation.
  *
@@ -156,12 +161,12 @@ static void probe_pages(CPURISCVState *env, target_ulong 
addr,
 target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
 target_ulong curlen = MIN(pagelen, len);
 
-probe_access(env, addr, curlen, access_type,
+probe_access(env, adjust_addr(env, addr), curlen, access_type,
  cpu_mmu_index(env, false), ra);
 if (len > curlen) {
 addr += curlen;
 curlen = len - curlen;
-probe_access(env, addr, curlen, access_type,
+probe_access(env, adjust_addr(env, addr), curlen, access_type,
  cpu_mmu_index(env, false), ra);
 }
 }
@@ -239,7 +244,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 k = 0;
 while (k < nf) {
 target_ulong addr = base + stride * i + (k << esz);
-ldst_elem(env, addr, i + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
 }
@@ -295,7 +300,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 k = 0;
 while (k < nf) {
 target_ulong addr = base + ((i * nf + k) << esz);
-ldst_elem(env, addr, i + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
 }
@@ -409,7 +414,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 k = 0;
 while (k < nf) {
 abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
-ldst_elem(env, addr, i + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
 }
@@ -488,7 +493,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 if (!vm && !vext_elem_mask(v0, i)) {
 continue;
 }
-addr = base + i * (nf << esz);
+addr = adjust_addr(env, base + i * (nf << esz));
 if (i == 0) {
 probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
 } else {
@@ -515,7 +520,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 break;
 }
 remain -= offset;
-addr += offset;
+addr = adjust_addr(env, addr + offset);
 }
 }
 }
@@ -531,7 +536,7 @@ ProbeSuccess:
 }
 while (k < nf) {
 target_ulong addr = base + ((i * nf + k) << esz);
-ldst_elem(env, addr, i + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
 }
@@ -585,7 +590,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 /* load/store rest of elements of current segment pointed by vstart */
 for (pos = off; pos < max_elems; pos++, env->vstart++) {
 target_ulong addr = base + ((pos + k * max_elems) << esz);
-ldst_elem(env, addr, pos + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), pos + k * max_elems, vd, 
ra);
 }
 k++;
 }
@@ -594,7 +599,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 for (; k < nf; k++) {
 for (i = 0; i < max_elems; i++, env->vstart++) {
 target_ulong addr = base + ((i + k * max_elems) << esz);
-ldst_elem(env, addr, i + k * max_elems, vd, ra);
+ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 }
 }
 
-- 
2.25.1




[PATCH v7 08/22] target/riscv: Use gdb xml according to max mxlen

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c |  8 ++---
 target/riscv/gdbstub.c | 71 +++---
 2 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index eac5f7bf03..690c879901 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -466,6 +466,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 RISCVCPU *cpu = RISCV_CPU(dev);
 CPURISCVState *env = >env;
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
+CPUClass *cc = CPU_CLASS(mcc);
 int priv_version = 0;
 Error *local_err = NULL;
 
@@ -516,11 +517,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 switch (env->misa_mxl_max) {
 #ifdef TARGET_RISCV64
 case MXL_RV64:
+cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
 break;
 case MXL_RV128:
 break;
 #endif
 case MXL_RV32:
+cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
 break;
 default:
 g_assert_not_reached();
@@ -802,11 +805,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
 cc->gdb_read_register = riscv_cpu_gdb_read_register;
 cc->gdb_write_register = riscv_cpu_gdb_write_register;
 cc->gdb_num_core_regs = 33;
-#if defined(TARGET_RISCV32)
-cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-#elif defined(TARGET_RISCV64)
-cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-#endif
 cc->gdb_stop_before_watchpoint = true;
 cc->disas_set_info = riscv_cpu_disas_set_info;
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index a5429b92d4..f531a74c2f 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -50,11 +50,23 @@ int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
+target_ulong tmp;
 
 if (n < 32) {
-return gdb_get_regl(mem_buf, env->gpr[n]);
+tmp = env->gpr[n];
 } else if (n == 32) {
-return gdb_get_regl(mem_buf, env->pc);
+tmp = env->pc;
+} else {
+return 0;
+}
+
+switch (env->misa_mxl_max) {
+case MXL_RV32:
+return gdb_get_reg32(mem_buf, tmp);
+case MXL_RV64:
+return gdb_get_reg64(mem_buf, tmp);
+default:
+g_assert_not_reached();
 }
 return 0;
 }
@@ -63,18 +75,32 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-
-if (n == 0) {
-/* discard writes to x0 */
-return sizeof(target_ulong);
-} else if (n < 32) {
-env->gpr[n] = ldtul_p(mem_buf);
-return sizeof(target_ulong);
+int length = 0;
+target_ulong tmp;
+
+switch (env->misa_mxl_max) {
+case MXL_RV32:
+tmp = (int32_t)ldl_p(mem_buf);
+length = 4;
+break;
+case MXL_RV64:
+if (env->xl < MXL_RV64) {
+tmp = (int32_t)ldq_p(mem_buf);
+} else {
+tmp = ldq_p(mem_buf);
+}
+length = 8;
+break;
+default:
+g_assert_not_reached();
+}
+if (n > 0 && n < 32) {
+env->gpr[n] = tmp;
 } else if (n == 32) {
-env->pc = ldtul_p(mem_buf);
-return sizeof(target_ulong);
+env->pc = tmp;
 }
-return 0;
+
+return length;
 }
 
 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
@@ -387,13 +413,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
*cs)
   
cs->gdb_num_regs),
  "riscv-vector.xml", 0);
 }
-#if defined(TARGET_RISCV32)
-gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
- 1, "riscv-32bit-virtual.xml", 0);
-#elif defined(TARGET_RISCV64)
-gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
- 1, "riscv-64bit-virtual.xml", 0);
-#endif
+switch (env->misa_mxl_max) {
+case MXL_RV32:
+gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+ riscv_gdb_set_virtual,
+ 1, "riscv-32bit-virtual.xml", 0);
+break;
+case MXL_RV64:
+gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+ riscv_gdb_set_virtual,
+ 1, "riscv-64bit-virtual.xml", 0);
+break;
+default:
+g_assert_not_reached();
+}
 
 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
  riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
-- 
2.25.1




[PATCH v7 03/22] target/riscv: Sign extend link reg for jal and jalr

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
 target/riscv/translate.c| 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 3a0ae28fef..b9ba57f266 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_temp_free(t0);
 }
 
-if (a->rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
-}
+gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
 tcg_gen_lookup_and_goto_ptr();
 
 if (misaligned) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 330904265e..30c0e28778 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -369,10 +369,8 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 return;
 }
 }
-if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-}
 
+gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
 gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety 
*/
 ctx->base.is_jmp = DISAS_NORETURN;
 }
-- 
2.25.1




[PATCH v7 07/22] target/riscv: Extend pc for runtime pc write

2022-01-18 Thread LIU Zhiwei
In some cases, we must restore the guest PC to the address of the start of
the TB, such as when the instruction counter hits zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 736cf1d4e7..eac5f7bf03 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -355,7 +355,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-env->pc = value;
+
+if (env->xl == MXL_RV32) {
+env->pc = (int32_t)value;
+} else {
+env->pc = value;
+}
 }
 
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -363,7 +368,13 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-env->pc = tb->pc;
+RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+
+if (xl == MXL_RV32) {
+env->pc = (int32_t)tb->pc;
+} else {
+env->pc = tb->pc;
+}
 }
 
 static bool riscv_cpu_has_work(CPUState *cs)
@@ -384,7 +395,12 @@ static bool riscv_cpu_has_work(CPUState *cs)
 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
   target_ulong *data)
 {
-env->pc = data[0];
+RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+if (xl == MXL_RV32) {
+env->pc = (int32_t)data[0];
+} else {
+env->pc = data[0];
+}
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
-- 
2.25.1




[PATCH v7 05/22] target/riscv: Create xl field in env

2022-01-18 Thread LIU Zhiwei
Current xlen has been used in helper functions and many other places.
The computation of current xlen is not so trivial, so that we should
recompute it as little as possible.

Fortunately, xlen only changes in very seldom cases, such as exception,
misa write, mstatus write, cpu reset, migration load. So that we can only
recompute xlen in this places and cache it into CPURISCVState.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h| 31 +++
 target/riscv/cpu_helper.c | 34 ++
 target/riscv/csr.c|  2 ++
 target/riscv/machine.c| 10 ++
 5 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c2b570e904..736cf1d4e7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -413,6 +413,7 @@ static void riscv_cpu_reset(DeviceState *dev)
 /* mmte is supposed to have pm.current hardwired to 1 */
 env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
+env->xl = riscv_cpu_mxl(env);
 cs->exception_index = RISCV_EXCP_NONE;
 env->load_res = -1;
 set_default_nan_mode(1, >fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 03552f4aaa..7657e22a56 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -146,6 +146,7 @@ struct CPURISCVState {
 uint32_t misa_mxl_max;  /* max mxl for this cpu */
 uint32_t misa_ext;  /* current extensions */
 uint32_t misa_ext_mask; /* max ext for this cpu */
+uint32_t xl;/* current xlen */
 
 /* 128-bit helpers upper part return value */
 target_ulong retxh;
@@ -456,6 +457,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 }
 #endif
 
+#if defined(TARGET_RISCV32)
+#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+{
+RISCVMXL xl = env->misa_mxl;
+#if !defined(CONFIG_USER_ONLY)
+/*
+ * When emulating a 32-bit-only cpu, use RV32.
+ * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
+ * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
+ * back to RV64 for lower privs.
+ */
+if (xl != MXL_RV32) {
+switch (env->priv) {
+case PRV_M:
+break;
+case PRV_U:
+xl = get_field(env->mstatus, MSTATUS64_UXL);
+break;
+default: /* PRV_S | PRV_H */
+xl = get_field(env->mstatus, MSTATUS64_SXL);
+break;
+}
+}
+#endif
+return xl;
+}
+#endif
+
 /*
  * Encode LMUL to lmul as follows:
  * LMULvlmullmul
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index afee770951..8ebcd57af0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
-{
-#if defined(TARGET_RISCV32)
-return MXL_RV32;
-#elif defined(CONFIG_USER_ONLY)
-return MXL_RV64;
-#else
-RISCVMXL xl = riscv_cpu_mxl(env);
-
-/*
- * When emulating a 32-bit-only cpu, use RV32.
- * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
- * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
- * back to RV64 for lower privs.
- */
-if (xl != MXL_RV32) {
-switch (env->priv) {
-case PRV_M:
-break;
-case PRV_U:
-xl = get_field(env->mstatus, MSTATUS64_UXL);
-break;
-default: /* PRV_S | PRV_H */
-xl = get_field(env->mstatus, MSTATUS64_SXL);
-break;
-}
-}
-return xl;
-#endif
-}
-
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
@@ -148,7 +117,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 }
 #endif
 
-flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
 
 *pflags = flags;
 }
@@ -364,6 +333,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
 }
 /* tlb_flush is unnecessary as mode is contained in mmu_idx */
 env->priv = newpriv;
+env->xl = cpu_recompute_xl(env);
 
 /*
  * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6bc7ee780c..9be2820d2b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -589,6 +589,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
 mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
 }
 env->mstatus = mstatus;
+env->xl = cpu_recompute_xl(env);
 
 return RISCV_EXCP_NONE;
 }
@@ -704,6 +705,7 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 /* flush translation cache */
 

[PATCH v7 01/22] target/riscv: Adjust pmpcfg access with mxl

2022-01-18 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 19 +++
 target/riscv/pmp.c | 12 
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a9e7ac903b..6bc7ee780c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1497,9 +1497,23 @@ static RISCVException write_mseccfg(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
+{
+/* TODO: RV128 restriction check */
+if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+return false;
+}
+return true;
+}
+
 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
   target_ulong *val)
 {
+uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+if (!check_pmp_reg_index(env, reg_index)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
 *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
 return RISCV_EXCP_NONE;
 }
@@ -1507,6 +1521,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, 
int csrno,
 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
target_ulong val)
 {
+uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+if (!check_pmp_reg_index(env, reg_index)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
 pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
 return RISCV_EXCP_NONE;
 }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 54abf42583..81b61bb65c 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t 
reg_index,
 {
 int i;
 uint8_t cfg_val;
+int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
 trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
 
-if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "ignoring pmpcfg write - incorrect address\n");
-return;
-}
-
-for (i = 0; i < sizeof(target_ulong); i++) {
+for (i = 0; i < pmpcfg_nums; i++) {
 cfg_val = (val >> 8 * i)  & 0xff;
 pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
 }
@@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t 
reg_index)
 int i;
 target_ulong cfg_val = 0;
 target_ulong val = 0;
+int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
-for (i = 0; i < sizeof(target_ulong); i++) {
+for (i = 0; i < pmpcfg_nums; i++) {
 val = pmp_read_cfg(env, (reg_index * 4) + i);
 cfg_val |= (val << (i * 8));
 }
-- 
2.25.1




[PATCH v7 02/22] target/riscv: Don't save pc when exception return

2022-01-18 Thread LIU Zhiwei
As pc will be written by the xepc in exception return, just ignore
pc in translation.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h  | 4 ++--
 target/riscv/insn_trans/trans_privileged.c.inc | 7 ++-
 target/riscv/op_helper.c   | 4 ++--
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6cf6d6ce98..72cc2582f4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -100,8 +100,8 @@ DEF_HELPER_2(csrr_i128, tl, env, int)
 DEF_HELPER_4(csrw_i128, void, env, int, tl, tl)
 DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
 #ifndef CONFIG_USER_ONLY
-DEF_HELPER_2(sret, tl, env, tl)
-DEF_HELPER_2(mret, tl, env, tl)
+DEF_HELPER_1(sret, tl, env)
+DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
 #endif
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
b/target/riscv/insn_trans/trans_privileged.c.inc
index 75c6ef80a6..6077bbbf11 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -74,10 +74,8 @@ static bool trans_uret(DisasContext *ctx, arg_uret *a)
 static bool trans_sret(DisasContext *ctx, arg_sret *a)
 {
 #ifndef CONFIG_USER_ONLY
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
 if (has_ext(ctx, RVS)) {
-gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+gen_helper_sret(cpu_pc, cpu_env);
 tcg_gen_exit_tb(NULL, 0); /* no chaining */
 ctx->base.is_jmp = DISAS_NORETURN;
 } else {
@@ -92,8 +90,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
 static bool trans_mret(DisasContext *ctx, arg_mret *a)
 {
 #ifndef CONFIG_USER_ONLY
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+gen_helper_mret(cpu_pc, cpu_env);
 tcg_gen_exit_tb(NULL, 0); /* no chaining */
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 6f040f2fb9..67693cb42b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -115,7 +115,7 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
 
 #ifndef CONFIG_USER_ONLY
 
-target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_sret(CPURISCVState *env)
 {
 uint64_t mstatus;
 target_ulong prev_priv, prev_virt;
@@ -176,7 +176,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 return retpc;
 }
 
-target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_mret(CPURISCVState *env)
 {
 if (!(env->priv >= PRV_M)) {
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
-- 
2.25.1




[PATCH v7 00/22] Support UXL filed in xstatus

2022-01-18 Thread LIU Zhiwei
In this patch set, we process the pc reigsters writes,
gdb reads and writes, and address calculation under
different UXLEN settings.

The patch set v7 has been tested by running rv64 Linux with 
rv32 rootfs in compat mode. You can almost follow the test [1]
given by GuoRen, except using the branch riscv-upstream-uxl-v7
on my QEMU repo [2].

[1] 
https://lore.kernel.org/linux-arm-kernel/20211228143958.3409187-17-guo...@kernel.org/t/
[2] https://github.com/romanheros/qemu.git 

All patches have been reviewed or acked.

v7:
  Rebase to Alistair riscv_to_apply.next branch
  Add commit message for create xl field in CPURISCVState

v6:
  Pass boot 32bit rootfs on compat Linux
  Pass test cases on compat OpenTee
  Fix csr write mask 
  Fix WARL for uxl
  Fix sstatus read for uxl
  Relax UXL field for debugging
  Don't bump machine state version for xl
  Rename cpu_get_xl to cpu_recompute_xl
  Rebase to vector v1.0
  Rebase to 128 bit cpu

v5:
  Add xl field in env to clear up redundant riscv_cpu_xl
  Adjust pmpcfg access with mxl
  Select gdb core xml according to mxl 

v4:
  Support SSTATUS64_UXL write
  Bump vmstate version for vill split

v3:
  Merge gen_pm_adjust_address into a canonical address function
  Adjust address for RVA with XLEN
  Split pm_enabled into pm_mask_enabled and pm_base_enabled
  Replace array of pm tcg globals with one scalar tcg global
  Split and change patch sequence

v2:
  Split out vill from vtype
  Remove context switch when xlen changes at exception
  Use XL instead of OL in many places
  Use pointer masking and XLEN for vector address
  Define an common fuction to calculate address for ld

LIU Zhiwei (22):
  target/riscv: Adjust pmpcfg access with mxl
  target/riscv: Don't save pc when exception return
  target/riscv: Sign extend link reg for jal and jalr
  target/riscv: Sign extend pc for different XLEN
  target/riscv: Create xl field in env
  target/riscv: Ignore the pc bits above XLEN
  target/riscv: Extend pc for runtime pc write
  target/riscv: Use gdb xml according to max mxlen
  target/riscv: Relax debug check for pm write
  target/riscv: Adjust csr write mask with XLEN
  target/riscv: Create current pm fields in env
  target/riscv: Alloc tcg global for cur_pm[mask|base]
  target/riscv: Calculate address according to XLEN
  target/riscv: Split pm_enabled into mask and base
  target/riscv: Split out the vill from vtype
  target/riscv: Adjust vsetvl according to XLEN
  target/riscv: Remove VILL field in VTYPE
  target/riscv: Fix check range for first fault only
  target/riscv: Adjust vector address with mask
  target/riscv: Adjust scalar reg in vector with XLEN
  target/riscv: Enable uxl field write
  target/riscv: Relax UXL field for debugging

 target/riscv/cpu.c| 32 +--
 target/riscv/cpu.h| 45 -
 target/riscv/cpu_helper.c | 94 +--
 target/riscv/csr.c| 74 +--
 target/riscv/gdbstub.c| 71 ++
 target/riscv/helper.h |  4 +-
 .../riscv/insn_trans/trans_privileged.c.inc   |  9 +-
 target/riscv/insn_trans/trans_rva.c.inc   |  9 +-
 target/riscv/insn_trans/trans_rvd.c.inc   | 19 +---
 target/riscv/insn_trans/trans_rvf.c.inc   | 19 +---
 target/riscv/insn_trans/trans_rvi.c.inc   | 39 +++-
 target/riscv/insn_trans/trans_rvv.c.inc   |  6 +-
 target/riscv/machine.c| 16 +++-
 target/riscv/op_helper.c  |  7 +-
 target/riscv/pmp.c| 12 +--
 target/riscv/translate.c  | 90 +-
 target/riscv/vector_helper.c  | 39 +---
 17 files changed, 355 insertions(+), 230 deletions(-)

-- 
2.25.1




Re: [PATCH v7 1/5] QIOChannel: Add flags on io_writev and introduce io_flush callback

2022-01-18 Thread Leonardo Bras Soares Passos
Hello Daniel,

On Thu, Jan 13, 2022 at 7:53 AM Daniel P. Berrangé  wrote:
>
> On Thu, Jan 06, 2022 at 07:13:38PM -0300, Leonardo Bras wrote:
> > Add flags to io_writev and introduce io_flush as optional callback to
> > QIOChannelClass, allowing the implementation of zero copy writes by
> > subclasses.
> >
> > How to use them:
> > - Write data using qio_channel_writev(...,QIO_CHANNEL_WRITE_FLAG_ZERO_COPY),
> > - Wait write completion with qio_channel_flush().
> >
> > Notes:
> > As some zero copy implementations work asynchronously, it's
> > recommended to keep the write buffer untouched until the return of
> > qio_channel_flush(), to avoid the risk of sending an updated buffer
> > instead of the buffer state during write.
> >
> > As io_flush callback is optional, if a subclass does not implement it, then:
> > - io_flush will return 0 without changing anything.
> >
> > Also, some functions like qio_channel_writev_full_all() were adapted to
> > receive a flag parameter. That allows shared code between zero copy and
> > non-zero copy writev, and also an easier implementation on new flags.
> >
> > Signed-off-by: Leonardo Bras 
> > ---
> >  include/io/channel.h | 67 +++-
> >  io/channel-buffer.c  |  1 +
> >  io/channel-command.c |  1 +
> >  io/channel-file.c|  1 +
> >  io/channel-socket.c  |  2 ++
> >  io/channel-tls.c |  1 +
> >  io/channel-websock.c |  1 +
> >  io/channel.c | 51 +++--
> >  migration/rdma.c |  1 +
> >  9 files changed, 98 insertions(+), 28 deletions(-)
> >
> > diff --git a/include/io/channel.h b/include/io/channel.h
> > index 88988979f8..343766ce5b 100644
> > --- a/include/io/channel.h
> > +++ b/include/io/channel.h
> > @@ -32,12 +32,15 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
> >
> >  #define QIO_CHANNEL_ERR_BLOCK -2
> >
> > +#define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
> > +
> >  typedef enum QIOChannelFeature QIOChannelFeature;
> >
> >  enum QIOChannelFeature {
> >  QIO_CHANNEL_FEATURE_FD_PASS,
> >  QIO_CHANNEL_FEATURE_SHUTDOWN,
> >  QIO_CHANNEL_FEATURE_LISTEN,
> > +QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY,
> >  };
> >
> >
> > @@ -104,6 +107,7 @@ struct QIOChannelClass {
> >   size_t niov,
> >   int *fds,
> >   size_t nfds,
> > + int flags,
> >   Error **errp);
> >  ssize_t (*io_readv)(QIOChannel *ioc,
> >  const struct iovec *iov,
> > @@ -136,6 +140,8 @@ struct QIOChannelClass {
> >IOHandler *io_read,
> >IOHandler *io_write,
> >void *opaque);
> > +int (*io_flush)(QIOChannel *ioc,
> > +Error **errp);
> >  };
> >
> >  /* General I/O handling functions */
> > @@ -222,12 +228,13 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
> >
> >
> >  /**
> > - * qio_channel_writev_full:
> > + * qio_channel_writev_full_flags:
> >   * @ioc: the channel object
> >   * @iov: the array of memory regions to write data from
> >   * @niov: the length of the @iov array
> >   * @fds: an array of file handles to send
> >   * @nfds: number of file handles in @fds
> > + * @flags: write flags (QIO_CHANNEL_WRITE_FLAG_*)
> >   * @errp: pointer to a NULL-initialized error object
> >   *
> >   * Write data to the IO channel, reading it from the
> > @@ -255,12 +262,16 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
> >   * or QIO_CHANNEL_ERR_BLOCK if no data is can be sent
> >   * and the channel is non-blocking
> >   */
> > -ssize_t qio_channel_writev_full(QIOChannel *ioc,
> > -const struct iovec *iov,
> > -size_t niov,
> > -int *fds,
> > -size_t nfds,
> > -Error **errp);
> > +ssize_t qio_channel_writev_full_flags(QIOChannel *ioc,
> > +  const struct iovec *iov,
> > +  size_t niov,
> > +  int *fds,
> > +  size_t nfds,
> > +  int flags,
> > +  Error **errp);
> > +
> > +#define qio_channel_writev_full(ioc, iov, niov, fds, nfds, errp) \
> > +qio_channel_writev_full_flags(ioc, iov, niov, fds, nfds, 0, errp)
>
> Don't introduce yet another API variant here. Just add flags to
> all the existing write APIs with "full" in their name. The word
> "full" in their name was intended to indicate that they are
> accepting all possible parameters, so it doesn't mean sense to
> add APIs which take even more possible parameters.

Oh, I was not aware of that. Thanks for letting me know!

Sure, I will do this change for v8.


>
> > +int qio_channel_writev_full_all_flags(QIOChannel 

Re: [PATCH qemu] spapr: Force 32bit when resetting a core

2022-01-18 Thread Alexey Kardashevskiy




On 1/17/22 03:45, Peter Maydell wrote:

On Fri, 7 Jan 2022 at 07:29, Alexey Kardashevskiy  wrote:


"PowerPC Processor binding to IEEE 1275" says in
"8.2.1. Initial Register Values" that the initial state is defined as
32bit so do it for both SLOF and VOF.

This should not cause behavioral change as SLOF switches to 64bit very
early anyway. As nothing enforces LE anywhere, this drops it for VOF.

The goal is to make VOF work with TCG as otherwise it barfs with
qemu: fatal: TCG hflags mismatch (current:0x6c04 rebuilt:0x6c00)


If you get this assert it means that something is changing
the CPU state and not calling the function to recalculate
the hflags (which are basically caching part of the CPU state).
So I don't know whether this patch is correct or not in updating
MSR bits, but in any case I think it is only masking the
missing-hflags-update that is causing the assertion...



If we emulate a bare metal machine, then most likely we want MSR_SF 
(==64bit) set. But this particular case is paravirtual pseries/spapr and 
it requires special handling so spapr_reset_vcpu() seems to be the right 
place.





-- PMM




Re: [PATCH v6 05/22] target/riscv: Create xl field in env

2022-01-18 Thread Alistair Francis
On Wed, Jan 19, 2022 at 1:36 PM LIU Zhiwei  wrote:
>
>
> On 2022/1/19 上午11:24, Alistair Francis wrote:
> > On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei  wrote:
> >> Signed-off-by: LIU Zhiwei 
> > I'm not clear on why this is better?
>
> Current xlen has been used in helper functions and many other places.
> The computation of current xlen  is not so trivial, so that we should
> recompute it as little as possible.
> Fortunately, xlen only changes in very seldom cases, such as exception,
> misa write,  mstatus write, cpu reset, migration load.
> So that we can only recompute XLEN in this places and cache it into
> CPURISCVState.

Sounds good! Do you mind adding that to the commit message

Reviewed-by: Alistair Francis 

Alistair

>
> Thanks
> Zhiwei
>
> >
> > Alistair
> >
> >> ---
> >>   target/riscv/cpu.c|  1 +
> >>   target/riscv/cpu.h| 31 +++
> >>   target/riscv/cpu_helper.c | 34 ++
> >>   target/riscv/csr.c|  2 ++
> >>   target/riscv/machine.c| 10 ++
> >>   5 files changed, 46 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >> index 9bc25d3055..54c1cf8ec5 100644
> >> --- a/target/riscv/cpu.c
> >> +++ b/target/riscv/cpu.c
> >> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
> >>   /* mmte is supposed to have pm.current hardwired to 1 */
> >>   env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
> >>   #endif
> >> +env->xl = riscv_cpu_mxl(env);
> >>   cs->exception_index = RISCV_EXCP_NONE;
> >>   env->load_res = -1;
> >>   set_default_nan_mode(1, >fp_status);
> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> >> index 4d63086765..65fd849bef 100644
> >> --- a/target/riscv/cpu.h
> >> +++ b/target/riscv/cpu.h
> >> @@ -145,6 +145,7 @@ struct CPURISCVState {
> >>   uint32_t misa_mxl_max;  /* max mxl for this cpu */
> >>   uint32_t misa_ext;  /* current extensions */
> >>   uint32_t misa_ext_mask; /* max ext for this cpu */
> >> +uint32_t xl;/* current xlen */
> >>
> >>   /* 128-bit helpers upper part return value */
> >>   target_ulong retxh;
> >> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState 
> >> *env)
> >>   }
> >>   #endif
> >>
> >> +#if defined(TARGET_RISCV32)
> >> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> >> +#else
> >> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> >> +{
> >> +RISCVMXL xl = env->misa_mxl;
> >> +#if !defined(CONFIG_USER_ONLY)
> >> +/*
> >> + * When emulating a 32-bit-only cpu, use RV32.
> >> + * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> + * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> + * back to RV64 for lower privs.
> >> + */
> >> +if (xl != MXL_RV32) {
> >> +switch (env->priv) {
> >> +case PRV_M:
> >> +break;
> >> +case PRV_U:
> >> +xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> +break;
> >> +default: /* PRV_S | PRV_H */
> >> +xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> +break;
> >> +}
> >> +}
> >> +#endif
> >> +return xl;
> >> +}
> >> +#endif
> >> +
> >>   /*
> >>* Encode LMUL to lmul as follows:
> >>* LMULvlmullmul
> >> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> >> index 434a83e66a..32ea066ef0 100644
> >> --- a/target/riscv/cpu_helper.c
> >> +++ b/target/riscv/cpu_helper.c
> >> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> >>   #endif
> >>   }
> >>
> >> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> >> -{
> >> -#if defined(TARGET_RISCV32)
> >> -return MXL_RV32;
> >> -#elif defined(CONFIG_USER_ONLY)
> >> -return MXL_RV64;
> >> -#else
> >> -RISCVMXL xl = riscv_cpu_mxl(env);
> >> -
> >> -/*
> >> - * When emulating a 32-bit-only cpu, use RV32.
> >> - * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> - * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> - * back to RV64 for lower privs.
> >> - */
> >> -if (xl != MXL_RV32) {
> >> -switch (env->priv) {
> >> -case PRV_M:
> >> -break;
> >> -case PRV_U:
> >> -xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> -break;
> >> -default: /* PRV_S | PRV_H */
> >> -xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> -break;
> >> -}
> >> -}
> >> -return xl;
> >> -#endif
> >> -}
> >> -
> >>   void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> >> target_ulong *cs_base, uint32_t *pflags)
> >>   {
> >> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
> >> target_ulong *pc,
> >>   }
> >>   #endif
> >>
> >> -flags = FIELD_DP32(flags, TB_FLAGS, XL, 

Re: [PATCH v6 05/22] target/riscv: Create xl field in env

2022-01-18 Thread LIU Zhiwei



On 2022/1/19 上午11:24, Alistair Francis wrote:

On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei  wrote:

Signed-off-by: LIU Zhiwei 

I'm not clear on why this is better?


Current xlen has been used in helper functions and many other places.  
The computation of current xlen  is not so trivial, so that we should 
recompute it as little as possible.
Fortunately, xlen only changes in very seldom cases, such as exception, 
misa write,  mstatus write, cpu reset, migration load.
So that we can only recompute XLEN in this places and cache it into 
CPURISCVState.


Thanks
Zhiwei



Alistair


---
  target/riscv/cpu.c|  1 +
  target/riscv/cpu.h| 31 +++
  target/riscv/cpu_helper.c | 34 ++
  target/riscv/csr.c|  2 ++
  target/riscv/machine.c| 10 ++
  5 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9bc25d3055..54c1cf8ec5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
  /* mmte is supposed to have pm.current hardwired to 1 */
  env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
  #endif
+env->xl = riscv_cpu_mxl(env);
  cs->exception_index = RISCV_EXCP_NONE;
  env->load_res = -1;
  set_default_nan_mode(1, >fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d63086765..65fd849bef 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -145,6 +145,7 @@ struct CPURISCVState {
  uint32_t misa_mxl_max;  /* max mxl for this cpu */
  uint32_t misa_ext;  /* current extensions */
  uint32_t misa_ext_mask; /* max ext for this cpu */
+uint32_t xl;/* current xlen */

  /* 128-bit helpers upper part return value */
  target_ulong retxh;
@@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
  }
  #endif

+#if defined(TARGET_RISCV32)
+#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+{
+RISCVMXL xl = env->misa_mxl;
+#if !defined(CONFIG_USER_ONLY)
+/*
+ * When emulating a 32-bit-only cpu, use RV32.
+ * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
+ * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
+ * back to RV64 for lower privs.
+ */
+if (xl != MXL_RV32) {
+switch (env->priv) {
+case PRV_M:
+break;
+case PRV_U:
+xl = get_field(env->mstatus, MSTATUS64_UXL);
+break;
+default: /* PRV_S | PRV_H */
+xl = get_field(env->mstatus, MSTATUS64_SXL);
+break;
+}
+}
+#endif
+return xl;
+}
+#endif
+
  /*
   * Encode LMUL to lmul as follows:
   * LMULvlmullmul
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 434a83e66a..32ea066ef0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
  #endif
  }

-static RISCVMXL cpu_get_xl(CPURISCVState *env)
-{
-#if defined(TARGET_RISCV32)
-return MXL_RV32;
-#elif defined(CONFIG_USER_ONLY)
-return MXL_RV64;
-#else
-RISCVMXL xl = riscv_cpu_mxl(env);
-
-/*
- * When emulating a 32-bit-only cpu, use RV32.
- * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
- * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
- * back to RV64 for lower privs.
- */
-if (xl != MXL_RV32) {
-switch (env->priv) {
-case PRV_M:
-break;
-case PRV_U:
-xl = get_field(env->mstatus, MSTATUS64_UXL);
-break;
-default: /* PRV_S | PRV_H */
-xl = get_field(env->mstatus, MSTATUS64_SXL);
-break;
-}
-}
-return xl;
-#endif
-}
-
  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
  {
@@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
  }
  #endif

-flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);

  *pflags = flags;
  }
@@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
  }
  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
  env->priv = newpriv;
+env->xl = cpu_recompute_xl(env);

  /*
   * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e7578f3e0f..b282a642f5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
  mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
  }
  env->mstatus = mstatus;
+env->xl = cpu_recompute_xl(env);

Re: [PATCH v6 22/22] target/riscv: Relax UXL field for debugging

2022-01-18 Thread Alistair Francis
On Thu, Jan 13, 2022 at 10:23 PM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d944ee9caf..1037c6b15d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -580,7 +580,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
> int csrno,
>  MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
>  MSTATUS_TW | MSTATUS_VS;
>
> -if (xl != MXL_RV32) {
> +if (xl != MXL_RV32 || env->debugger) {
>  /*
>   * RV32: MPV and GVA are not in mstatus. The current plan is to
>   * add them to mstatush. For now, we just don't support it.
> @@ -905,7 +905,7 @@ static RISCVException read_sstatus(CPURISCVState *env, 
> int csrno,
> target_ulong *val)
>  {
>  target_ulong mask = (sstatus_v1_10_mask);
> -if (env->xl != MXL_RV32) {
> +if (env->xl != MXL_RV32 || env->debugger) {
>  mask |= SSTATUS64_UXL;
>  }
>  /* TODO: Use SXL not MXL. */
> @@ -917,7 +917,8 @@ static RISCVException write_sstatus(CPURISCVState *env, 
> int csrno,
>  target_ulong val)
>  {
>  target_ulong mask = (sstatus_v1_10_mask);
> -if (env->xl != MXL_RV32) {
> +
> +if (env->xl != MXL_RV32 || env->debugger) {
>  mask |= SSTATUS64_UXL;
>  }
>  target_ulong newval = (env->mstatus & ~mask) | (val & mask);
> --
> 2.25.1
>
>



Re: [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN

2022-01-18 Thread Alistair Francis
On Thu, Jan 13, 2022 at 10:20 PM LIU Zhiwei  wrote:
>
> When sew <= 32bits, not need to extend scalar reg.
> When sew > 32bits, if xlen is less that sew, we should sign extend
> the scalar register, except explicitly specified by the spec.
>
> Signed-off-by: LIU Zhiwei 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 1c8086d3a6..b6502cdc7c 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -1201,7 +1201,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
> uint32_t vs2, uint32_t vm,
>  dest = tcg_temp_new_ptr();
>  mask = tcg_temp_new_ptr();
>  src2 = tcg_temp_new_ptr();
> -src1 = get_gpr(s, rs1, EXT_NONE);
> +src1 = get_gpr(s, rs1, EXT_SIGN);
>
>  data = FIELD_DP32(data, VDATA, VM, vm);
>  data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> --
> 2.25.1
>
>



Re: [PATCH v6 05/22] target/riscv: Create xl field in env

2022-01-18 Thread Alistair Francis
On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

I'm not clear on why this is better?

Alistair

> ---
>  target/riscv/cpu.c|  1 +
>  target/riscv/cpu.h| 31 +++
>  target/riscv/cpu_helper.c | 34 ++
>  target/riscv/csr.c|  2 ++
>  target/riscv/machine.c| 10 ++
>  5 files changed, 46 insertions(+), 32 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9bc25d3055..54c1cf8ec5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>  /* mmte is supposed to have pm.current hardwired to 1 */
>  env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>  #endif
> +env->xl = riscv_cpu_mxl(env);
>  cs->exception_index = RISCV_EXCP_NONE;
>  env->load_res = -1;
>  set_default_nan_mode(1, >fp_status);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d63086765..65fd849bef 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -145,6 +145,7 @@ struct CPURISCVState {
>  uint32_t misa_mxl_max;  /* max mxl for this cpu */
>  uint32_t misa_ext;  /* current extensions */
>  uint32_t misa_ext_mask; /* max ext for this cpu */
> +uint32_t xl;/* current xlen */
>
>  /* 128-bit helpers upper part return value */
>  target_ulong retxh;
> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
>  }
>  #endif
>
> +#if defined(TARGET_RISCV32)
> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> +#else
> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> +{
> +RISCVMXL xl = env->misa_mxl;
> +#if !defined(CONFIG_USER_ONLY)
> +/*
> + * When emulating a 32-bit-only cpu, use RV32.
> + * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> + * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> + * back to RV64 for lower privs.
> + */
> +if (xl != MXL_RV32) {
> +switch (env->priv) {
> +case PRV_M:
> +break;
> +case PRV_U:
> +xl = get_field(env->mstatus, MSTATUS64_UXL);
> +break;
> +default: /* PRV_S | PRV_H */
> +xl = get_field(env->mstatus, MSTATUS64_SXL);
> +break;
> +}
> +}
> +#endif
> +return xl;
> +}
> +#endif
> +
>  /*
>   * Encode LMUL to lmul as follows:
>   * LMULvlmullmul
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 434a83e66a..32ea066ef0 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>  #endif
>  }
>
> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> -{
> -#if defined(TARGET_RISCV32)
> -return MXL_RV32;
> -#elif defined(CONFIG_USER_ONLY)
> -return MXL_RV64;
> -#else
> -RISCVMXL xl = riscv_cpu_mxl(env);
> -
> -/*
> - * When emulating a 32-bit-only cpu, use RV32.
> - * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> - * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> - * back to RV64 for lower privs.
> - */
> -if (xl != MXL_RV32) {
> -switch (env->priv) {
> -case PRV_M:
> -break;
> -case PRV_U:
> -xl = get_field(env->mstatus, MSTATUS64_UXL);
> -break;
> -default: /* PRV_S | PRV_H */
> -xl = get_field(env->mstatus, MSTATUS64_SXL);
> -break;
> -}
> -}
> -return xl;
> -#endif
> -}
> -
>  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>target_ulong *cs_base, uint32_t *pflags)
>  {
> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
> target_ulong *pc,
>  }
>  #endif
>
> -flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
> +flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>
>  *pflags = flags;
>  }
> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
> newpriv)
>  }
>  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>  env->priv = newpriv;
> +env->xl = cpu_recompute_xl(env);
>
>  /*
>   * Clear the load reservation - otherwise a reservation placed in one
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e7578f3e0f..b282a642f5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
> int csrno,
>  mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>  }
>  env->mstatus = mstatus;
> +env->xl = cpu_recompute_xl(env);
>
>  return RISCV_EXCP_NONE;
>  }
> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int 
> csrno,
>  /* flush translation cache */
>  tb_flush(env_cpu(env));
>  env->misa_ext = val;
> 

Re: [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr

2022-01-18 Thread Alistair Francis
On Thu, Jan 13, 2022 at 9:45 PM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
>  target/riscv/translate.c| 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
> b/target/riscv/insn_trans/trans_rvi.c.inc
> index 3a0ae28fef..b9ba57f266 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>  tcg_temp_free(t0);
>  }
>
> -if (a->rd != 0) {
> -tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
> -}
> +gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>  tcg_gen_lookup_and_goto_ptr();
>
>  if (misaligned) {
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 615048ec87..b47b308920 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -367,10 +367,8 @@ static void gen_jal(DisasContext *ctx, int rd, 
> target_ulong imm)
>  return;
>  }
>  }
> -if (rd != 0) {
> -tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
> -}
>
> +gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>  gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for 
> safety */
>  ctx->base.is_jmp = DISAS_NORETURN;
>  }
> --
> 2.25.1
>
>



Re: [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl

2022-01-18 Thread Alistair Francis
On Thu, Jan 13, 2022 at 9:41 PM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 19 +++
>  target/riscv/pmp.c | 12 
>  2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index adb3d4381d..e7578f3e0f 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1493,9 +1493,23 @@ static RISCVException write_mseccfg(CPURISCVState 
> *env, int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
> +{
> +/* TODO: RV128 restriction check */
> +if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
> +return false;
> +}
> +return true;
> +}
> +
>  static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>target_ulong *val)
>  {
> +uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +if (!check_pmp_reg_index(env, reg_index)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
>  *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
>  return RISCV_EXCP_NONE;
>  }
> @@ -1503,6 +1517,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, 
> int csrno,
>  static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
> target_ulong val)
>  {
> +uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +if (!check_pmp_reg_index(env, reg_index)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
>  pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
>  return RISCV_EXCP_NONE;
>  }
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..81b61bb65c 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t 
> reg_index,
>  {
>  int i;
>  uint8_t cfg_val;
> +int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
>  trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
>
> -if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> -qemu_log_mask(LOG_GUEST_ERROR,
> -  "ignoring pmpcfg write - incorrect address\n");
> -return;
> -}
> -
> -for (i = 0; i < sizeof(target_ulong); i++) {
> +for (i = 0; i < pmpcfg_nums; i++) {
>  cfg_val = (val >> 8 * i)  & 0xff;
>  pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
>  }
> @@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t 
> reg_index)
>  int i;
>  target_ulong cfg_val = 0;
>  target_ulong val = 0;
> +int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
> -for (i = 0; i < sizeof(target_ulong); i++) {
> +for (i = 0; i < pmpcfg_nums; i++) {
>  val = pmp_read_cfg(env, (reg_index * 4) + i);
>  cfg_val |= (val << (i * 8));
>  }
> --
> 2.25.1
>
>



Re: [RESEND PATCH v3 1/7] target/riscv: Add initial support for native debug

2022-01-18 Thread Alistair Francis
On Wed, Jan 5, 2022 at 1:09 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds initial support for the native debug via the Trigger Module,
> as defined in the RISC-V Debug Specification [1].

Doesn't this mean we are just supporting the Sdtrig extension?

>
> Only "Address / Data Match" trigger (type 2) is implemented as of now,
> which is mainly used for hardware breakpoint and watchpoint. The number
> of type 2 triggers implemented is 2, which is the number that we can
> find in the SiFive U54/U74 cores.
>
> [1] 
> https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf
>
> Signed-off-by: Bin Meng 
> ---
>
> Changes in v3:
> - drop riscv_trigger_init(), which will be moved to patch #5
>
>  target/riscv/cpu.h   |   5 +
>  target/riscv/debug.h | 108 +
>  target/riscv/debug.c | 339 +++
>  target/riscv/meson.build |   1 +
>  4 files changed, 453 insertions(+)
>  create mode 100644 target/riscv/debug.h
>  create mode 100644 target/riscv/debug.c
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index dc10f27093..0f3b3a4219 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -98,6 +98,7 @@ typedef struct CPURISCVState CPURISCVState;
>
>  #if !defined(CONFIG_USER_ONLY)
>  #include "pmp.h"
> +#include "debug.h"
>  #endif
>
>  #define RV_VLEN_MAX 1024
> @@ -234,6 +235,10 @@ struct CPURISCVState {
>  pmp_table_t pmp_state;
>  target_ulong mseccfg;
>
> +/* trigger module */
> +target_ulong trigger_cur;
> +trigger_type2_t trigger_type2[TRIGGER_TYPE2_NUM];
> +
>  /* machine specific rdtime callback */
>  uint64_t (*rdtime_fn)(uint32_t);
>  uint32_t rdtime_fn_arg;
> diff --git a/target/riscv/debug.h b/target/riscv/debug.h
> new file mode 100644
> index 00..0a3fda6c72
> --- /dev/null
> +++ b/target/riscv/debug.h
> @@ -0,0 +1,108 @@
> +/*
> + * QEMU RISC-V Native Debug Support
> + *
> + * Copyright (c) 2022 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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 RISCV_DEBUG_H
> +#define RISCV_DEBUG_H
> +
> +/* trigger indexes implemented */
> +enum {
> +TRIGGER_TYPE2_IDX_0 = 0,
> +TRIGGER_TYPE2_IDX_1,
> +TRIGGER_TYPE2_NUM,
> +TRIGGER_NUM = TRIGGER_TYPE2_NUM
> +};
> +
> +/* register index of tdata CSRs */
> +enum {
> +TDATA1 = 0,
> +TDATA2,
> +TDATA3,
> +TDATA_NUM
> +};
> +
> +typedef enum {
> +TRIGGER_TYPE_NO_EXIST = 0,  /* trigger does not exist */
> +TRIGGER_TYPE_AD_MATCH = 2,  /* address/data match trigger */
> +TRIGGER_TYPE_INST_CNT = 3,  /* instruction count trigger */
> +TRIGGER_TYPE_INT = 4,   /* interrupt trigger */
> +TRIGGER_TYPE_EXCP = 5,  /* exception trigger */
> +TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */
> +TRIGGER_TYPE_EXT_SRC = 7,   /* external source trigger */
> +TRIGGER_TYPE_UNAVAIL = 15   /* trigger exists, but unavailable */
> +} trigger_type_t;
> +
> +typedef struct {
> +target_ulong mcontrol;
> +target_ulong maddress;
> +struct CPUBreakpoint *bp;
> +struct CPUWatchpoint *wp;
> +} trigger_type2_t;

This is a confusing name

Alistair

> +
> +/* tdata field masks */
> +
> +#define RV32_TYPE(t)((uint32_t)(t) << 28)
> +#define RV32_TYPE_MASK  (0xf << 28)
> +#define RV32_DMODE  BIT(27)
> +#define RV64_TYPE(t)((uint64_t)(t) << 60)
> +#define RV64_TYPE_MASK  (0xfULL << 60)
> +#define RV64_DMODE  BIT_ULL(59)
> +
> +/* mcontrol field masks */
> +
> +#define TYPE2_LOAD  BIT(0)
> +#define TYPE2_STORE BIT(1)
> +#define TYPE2_EXEC  BIT(2)
> +#define TYPE2_U BIT(3)
> +#define TYPE2_S BIT(4)
> +#define TYPE2_M BIT(6)
> +#define TYPE2_MATCH (0xf << 7)
> +#define TYPE2_CHAIN BIT(11)
> +#define TYPE2_ACTION(0xf << 12)
> +#define TYPE2_SIZELO(0x3 << 16)
> +#define TYPE2_TIMINGBIT(18)
> +#define TYPE2_SELECTBIT(19)
> +#define TYPE2_HIT   BIT(20)
> +#define TYPE2_SIZEHI(0x3 << 21) /* RV64 only */
> +
> +/* access size */
> +enum {
> +SIZE_ANY = 0,
> +SIZE_1B,
> +SIZE_2B,
> +SIZE_4B,
> +SIZE_6B,
> +SIZE_8B,
> +SIZE_10B,
> +SIZE_12B,
> +SIZE_14B,
> +SIZE_16B,
> +SIZE_NUM = 16
> +};
> +
> +bool tdata_available(CPURISCVState *env, int tdata_index);
> +

Re: [PATCH v5 1/5] target/riscv: Ignore reserved bits in PTE for RV64

2022-01-18 Thread LIU Zhiwei



On 2022/1/18 下午7:29, Weiwei Li wrote:


在 2022/1/18 下午7:15, Guo Ren 写道:
On Tue, Jan 18, 2022 at 4:51 PM Anup Patel  
wrote:

On Tue, Jan 18, 2022 at 2:16 PM Guo Ren  wrote:
On Tue, Jan 18, 2022 at 11:32 AM Anup Patel  
wrote:
On Tue, Jan 18, 2022 at 6:47 AM Weiwei Li  
wrote:

From: Guo Ren 

Highest bits of PTE has been used for svpbmt, ref: [1], [2], so we
need to ignore them. They cannot be a part of ppn.

1: The RISC-V Instruction Set Manual, Volume II: Privileged 
Architecture

    4.4 Sv39: Page-Based 39-bit Virtual-Memory System
    4.5 Sv48: Page-Based 48-bit Virtual-Memory System

2: 
https://github.com/riscv/virtual-memory/blob/main/specs/663-Svpbmt-diff.pdf


Signed-off-by: Guo Ren 
Tested-by: Bin Meng 
Reviewed-by: Liu Zhiwei 
Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
---
  target/riscv/cpu_bits.h   | 7 +++
  target/riscv/cpu_helper.c | 2 +-
  2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 5a6d49aa64..282cd8eecd 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -490,6 +490,13 @@ typedef enum {
  /* Page table PPN shift amount */
  #define PTE_PPN_SHIFT   10

+/* Page table PPN mask */
+#if defined(TARGET_RISCV32)
+#define PTE_PPN_MASK    0xUL
+#elif defined(TARGET_RISCV64)
+#define PTE_PPN_MASK    0x3fULL
+#endif
+

Going forward we should avoid using target specific "#if"
so that we can use the same qemu-system-riscv64 for both
RV32 and RV64.


  /* Leaf page shift amount */
  #define PGSHIFT 12

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 434a83e66a..26608ddf1c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -619,7 +619,7 @@ restart:
  return TRANSLATE_FAIL;
  }

-    hwaddr ppn = pte >> PTE_PPN_SHIFT;
+    hwaddr ppn = (pte & PTE_PPN_MASK) >> PTE_PPN_SHIFT;

Rather than using "#if", please use "xlen" comparison to extract
PPN correctly from PTE.

Do you mean?

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9fffaccffb..071b7ea4cf 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -619,7 +619,11 @@ restart:
  return TRANSLATE_FAIL;
  }

-    hwaddr ppn = (pte & PTE_PPN_MASK) >> PTE_PPN_SHIFT;
+    if (riscv_cpu_mxl(env) == MXL_RV32) {
+   hwaddr ppn = pte  >> PTE_PPN_SHIFT;
+   } else {
+   hwaddr ppn = (pte & 0x3fULL) >> 
PTE_PPN_SHIFT;

+   }

Yes, something like this but use a define for 0x3fULL

Just as Alistair said: This will need to be dynamic based on get_xl()

  I still prefer:
+#if defined(TARGET_RISCV32)
+#define PTE_PPN_MASK    0xUL
+#elif defined(TARGET_RISCV64)
+#define PTE_PPN_MASK    0x3fULL
+#endif

+    hwaddr ppn = (pte & PTE_PPN_MASK) >> PTE_PPN_SHIFT;


I think the difference may be xl = MXL_RV32 in RV64.

Agree.


Or we may  define  PTE_PPN_MASK as  0x3fULL, and use type 
contrast


+    hwaddr ppn = (pte & (target_ulong)PTE_PPN_MASK) >> 
PTE_PPN_SHIFT;


It is absolutely not right to use target_ulong here.

Although we don't support dynamic SXLEN currently,   we should avoid 
assuming  that SXLEN is always 64 on qemu-system-riscv64. Get_cpu_xl is 
the right way.


I have  moved  xl to CPURISCVState in my patch set v6 for UXL. I think 
it will be much convenient for this situation and you can just use 
env->xl to get right XLEN.

But I don't know when it will be merged.

Thanks,
Zhiwei



Regards,
Weiwei Li


Regards,
Anup


  RISCVCPU *cpu = env_archcpu(env);
  if (!(pte & PTE_V)) {


Regards,
Anup


  if (!(pte & PTE_V)) {
  /* Invalid PTE */
--
2.17.1



--
Best Regards
  Guo Ren

ML: https://lore.kernel.org/linux-csky/











Re: [RESEND PATCH v3 5/7] target/riscv: csr: Hook debug CSR read/write

2022-01-18 Thread Alistair Francis
On Wed, Jan 5, 2022 at 1:15 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds debug CSR read/write support to the RISC-V CSR RW table.
>
> Signed-off-by: Bin Meng 
> ---
>
> Changes in v3:
> - add riscv_trigger_init(), moved from patch #1 to this patch
>
>  target/riscv/debug.h |  2 ++
>  target/riscv/cpu.c   |  6 +
>  target/riscv/csr.c   | 57 
>  target/riscv/debug.c | 27 +
>  4 files changed, 92 insertions(+)
>
> diff --git a/target/riscv/debug.h b/target/riscv/debug.h
> index d0f63e2414..f4da2db35d 100644
> --- a/target/riscv/debug.h
> +++ b/target/riscv/debug.h
> @@ -109,4 +109,6 @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
>  bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
>  bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
>
> +void riscv_trigger_init(CPURISCVState *env);
> +
>  #endif /* RISCV_DEBUG_H */
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d36c31ce9a..17dcc3c14f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -575,6 +575,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>
>  riscv_cpu_register_gdb_regs_for_features(cs);
>
> +#ifndef CONFIG_USER_ONLY
> +if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
> +riscv_trigger_init(env);
> +}
> +#endif
> +
>  qemu_init_vcpu(cs);
>  cpu_reset(cs);
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 146447eac5..189b9cc8c6 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -220,6 +220,15 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
>
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
> +
> +static RISCVException debug(CPURISCVState *env, int csrno)
> +{
> +if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
> +return RISCV_EXCP_NONE;
> +}
> +
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
>  #endif
>
>  /* User Floating-Point CSRs */
> @@ -1464,6 +1473,48 @@ static RISCVException write_pmpaddr(CPURISCVState 
> *env, int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException read_tselect(CPURISCVState *env, int csrno,
> +   target_ulong *val)
> +{
> +*val = tselect_csr_read(env);
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_tselect(CPURISCVState *env, int csrno,
> +target_ulong val)
> +{
> +tselect_csr_write(env, val);
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_tdata(CPURISCVState *env, int csrno,
> + target_ulong *val)
> +{
> +/* return 0 in tdata1 to end the trigger enumeration */
> +if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
> +*val = 0;
> +return RISCV_EXCP_NONE;
> +}
> +
> +if (!tdata_available(env, csrno - CSR_TDATA1)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +*val = tdata_csr_read(env, csrno - CSR_TDATA1);
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_tdata(CPURISCVState *env, int csrno,
> +  target_ulong val)
> +{
> +if (!tdata_available(env, csrno - CSR_TDATA1)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +tdata_csr_write(env, csrno - CSR_TDATA1, val);
> +return RISCV_EXCP_NONE;
> +}
> +
>  /*
>   * Functions to access Pointer Masking feature registers
>   * We have to check if current priv lvl could modify
> @@ -1962,6 +2013,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
>  [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
>
> +/* Debug CSRs */
> +[CSR_TSELECT]   =  { "tselect", debug, read_tselect, write_tselect },
> +[CSR_TDATA1]=  { "tdata1",  debug, read_tdata,   write_tdata   },
> +[CSR_TDATA2]=  { "tdata2",  debug, read_tdata,   write_tdata   },
> +[CSR_TDATA3]=  { "tdata3",  debug, read_tdata,   write_tdata   },
> +
>  /* User Pointer Masking */
>  [CSR_UMTE]={ "umte",pointer_masking, read_umte,
> write_umte},
>  [CSR_UPMMASK] ={ "upmmask", pointer_masking, read_upmmask, 
> write_upmmask },
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 7760c4611f..041a0d3a89 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -412,3 +412,30 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
> CPUWatchpoint *wp)
>
>  return false;
>  }
> +
> +void riscv_trigger_init(CPURISCVState *env)
> +{
> +target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
> +int i;
> +
> +/* type 2 triggers */
> +for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
> +/*
> + * type = TRIGGER_TYPE_AD_MATCH
> + * dmode = 0 (both debug and M-mode can write tdata)
> + * maskmax = 0 (unimplemented, always 0)
> + * sizehi = 0 (match against any size, 

[PATCH] qapi: Cleanup SGX related comments

2022-01-18 Thread Yang Zhong
The SGX NUMA patches were merged into Qemu 7.0 release, we need
clarify detailed version history information and also change
some related comments, which make SGX related comments clearer.

Signed-off-by: Yang Zhong 
---
 qapi/machine.json |  4 ++--
 qapi/misc-target.json | 14 +-
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index b6a37e17c4..cf47cb63a9 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1207,7 +1207,7 @@
 #
 # @memdev: memory backend linked with device
 #
-# @node: the numa node
+# @node: the numa node (Since: 7.0)
 #
 # Since: 6.2
 ##
@@ -1288,7 +1288,7 @@
 #
 # @memdev: memory backend linked with device
 #
-# @node: the numa node
+# @node: the numa node (Since: 7.0)
 #
 # Since: 6.2
 ##
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 1022aa0184..558521bd39 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -344,9 +344,9 @@
 #
 # @node: the numa node
 #
-# @size: the size of epc section
+# @size: the size of EPC section
 #
-# Since: 6.2
+# Since: 7.0
 ##
 { 'struct': 'SGXEPCSection',
   'data': { 'node': 'int',
@@ -365,7 +365,7 @@
 #
 # @flc: true if FLC is supported
 #
-# @sections: The EPC sections info for guest
+# @sections: The EPC sections info for guest(Since: 7.0)
 #
 # Since: 6.2
 ##
@@ -390,7 +390,9 @@
 #
 # -> { "execute": "query-sgx" }
 # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
-#  "flc": true, "section-size" : 0 } }
+#  "flc": true,  "sections":
+#  [{"node": 0, "size": 67108864},
+#  {"node": 1, "size": 29360128}]} }
 #
 ##
 { 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }
@@ -408,7 +410,9 @@
 #
 # -> { "execute": "query-sgx-capabilities" }
 # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true,
-#  "flc": true, "section-size" : 0 } }
+#  "flc": true, "section" :
+#  [{"node": 0, "size": 67108864},
+#  {"node": 1, "size": 29360128}]} }
 #
 ##
 { 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 
'TARGET_I386' }



Re: [PATCH v7 1/5] QIOChannel: Add flags on io_writev and introduce io_flush callback

2022-01-18 Thread Peter Xu
On Tue, Jan 18, 2022 at 05:45:09PM -0300, Leonardo Bras Soares Passos wrote:
> Hello Peter,
> 
> On Thu, Jan 13, 2022 at 3:28 AM Peter Xu  wrote:
> >
> > On Thu, Jan 06, 2022 at 07:13:38PM -0300, Leonardo Bras wrote:
> > > diff --git a/io/channel.c b/io/channel.c
> > > index e8b019dc36..904855e16e 100644
> > > --- a/io/channel.c
> > > +++ b/io/channel.c
> > > @@ -67,12 +67,13 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
> > >  }
> > >
> > >
> > > -ssize_t qio_channel_writev_full(QIOChannel *ioc,
> > > -const struct iovec *iov,
> > > -size_t niov,
> > > -int *fds,
> > > -size_t nfds,
> > > -Error **errp)
> > > +ssize_t qio_channel_writev_full_flags(QIOChannel *ioc,
> > > +  const struct iovec *iov,
> > > +  size_t niov,
> > > +  int *fds,
> > > +  size_t nfds,
> > > +  int flags,
> > > +  Error **errp)
> > >  {
> > >  QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
> > >
> > > @@ -83,7 +84,7 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
> > >  return -1;
> > >  }
> >
> > Should we better also check QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY here when
> > QIO_CHANNEL_WRITE_FLAG_ZERO_COPY is set?  Just like what we do with:
> 
> Yes, that's correct.
> I will also test for fds + zerocopy_flag , which should also fail here.
> 
> >
> > if ((fds || nfds) &&
> > !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
> > error_setg_errno(errp, EINVAL,
> >  "Channel does not support file descriptor 
> > passing");
> > return -1;
> > }
> >
> > I still think it's better to have the caller be crystal clear when to use
> > zero_copy feature because it has implication on buffer lifetime.
> 
> I don't disagree with that suggestion.
> 
> But the buffer lifetime limitation is something on the socket
> implementation, right?
> There could be some synchronous zerocopy implementation that does not
> require flush, and thus
> don't require the buffer to be treated any special. Or am I missing something?

Currently the flush() is required for zerocopy and not required for all the
existing non-zerocopy use cases, that's already an API difference so the caller
needs to identify it anyway.  Then I think it's simpler we expose all of it to
the user.

Not to mention IIUC if we don't fail here, it will just fail later when the
code will unconditionally convert the flags=ZEROCOPY into MSG_ZEROCOPY in your
next patch:

if (flags & QIO_CHANNEL_WRITE_FLAG_ZERO_COPY) {
sflags = MSG_ZEROCOPY;
}

So AFAIU it'll fail anyway, either here with the cap check I mentioned, or
later in sendmsg().

IOW, I think it fails cleaner here, rather than reaching sendmsg().

> 
> >
> > I might have commented similar things before, but I have missed a few 
> > versions
> > so I could also have missed some previous discussions..
> >
> 
> That's all great suggestions Peter!  Thanks for that!
> 
> Some of the previous suggestions may have been missed because a lot of
> code moved.
> Sorry about that.

Not a problem at all, I just want to make sure my question still makes
sense. :)

-- 
Peter Xu




Re: [PATCH v2 2/2] target/riscv: Add XVentanaCondOps custom extension

2022-01-18 Thread Alistair Francis
On Wed, Jan 19, 2022 at 11:19 AM Alistair Francis  wrote:
>
> On Wed, Jan 19, 2022 at 9:22 AM Philipp Tomsich
>  wrote:
> >
> > Alistair,
> >
> > Some of us (the merit almost exclusively goes to Kito) have been
> > working towards a similar policy for GCC/binutils and LLVM.
> > This currently lives in:
> >https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/17
>
> Ah cool! We can use that as a good starting point.
>
> >
> > A few comments & a question below.
> >
> > Thanks,
> > Philipp.
> >
> > On Tue, 18 Jan 2022 at 23:53, Alistair Francis  wrote:
> > >
> > > On Fri, Jan 14, 2022 at 6:22 AM Philipp Tomsich
> > >  wrote:
> > > >
> > > > This adds the decoder and translation for the XVentanaCondOps custom
> > > > extension (vendor-defined by Ventana Micro Systems), which is
> > > > documented at 
> > > > https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf
> > > >
> > > > This commit then also adds a guard-function (has_XVentanaCondOps_p)
> > > > and the decoder function to the table of decoders, enabling the
> > > > support for the XVentanaCondOps extension.
> > > >
> > > > Signed-off-by: Philipp Tomsich 
> > >
> > > This looks reasonable to me.
> > >
> > > I'm going to leave this for a bit in case there are any more comments.
> > >
> > > I was a little worried that taking vendor extensions isn't the right
> > > move, as we might get stuck with a large number of them. But this is
> > > pretty self contained and I think with the growing RISC-V interest
> > > it's something we will eventually need to support.
> > >
> > > I'm going to update the QEMU RISC-V wiki page with this to make the
> > > position clear (comments very welcome)
> > >
> > > === RISC-V Extensions ===
> > > As RISC-V has a range of possible extensions, QEMU has guidelines for
> > > supporting them all.
> > >
> > > If an extension is frozen or ratified by the RISC-V foundation, it can
> > > be supported in QEMU.
> > >
> > > If an official RISC-V foundation extension is in a reasonable draft
> > > state, that is not too many changes are still expected, it can be
> > > supported experimentally by QEMU. Experimental support means it must
> > > be disabled by default and marked with a "x-" in the properties. QEMU
> > > will only support the latest version of patches submitted for a draft
> > > extension. A draft extension can also be removed at any time if it
> > > conflicts with other extensions.
> > >
> > > QEMU will also support vendor extensions. Vendor extensions must be
> > > disabled by default, but can be enabled for specific vendor CPUs and
> > > boards. Vendor extensions must be maintained and tested by the vendor.
> >
> > I guess I should create a v3 with appropriate paths in the MAINTAINERS file?
>
> Hmm... Good point. I don't think you have to if you don't want to.
>
> My point here was more to just make it clear that upstream QEMU is not
> a dumping ground for vendor extensions to get them maintained by
> someone else. Obviously we won't purposely break things just for fun.
> There is an expectation that the vendor tests their extensions and
> responds to bug reports and things like that.
>
> >
> > > Vendor extensions can not interfere with other extensions and can not
> > > be obtrusive to the RISC-V target code.
> >
> > I know that there is some interest to have the XtheadV (the
> > instructions previously known as vectors 0.7.1-draft) supported and we
> > have the reality of a deployed base that implements it in hardware.
> > This would conflict with the opcode space used by the standard RISC-V
> > vectors, so it makes for an interesting test case (even if just to
> > clarify our intent)...
> > Personally, I would like to avoid precluding inclusion of something
> > useful (of course, "Vendor extensions must be maintained and tested by
> > the vendor." has to apply!), if a vendor was going to step up and also
> > offers to maintain it.
>
> Yeah... this is unfortunate. I agree that having the 0.7.1-draft
> extensions supported would be great. There is hardware that supports
> it.
>
> I think this point still stands though. IF the XtheadV implementation
> is self contained and doesn't interfere with the vector extensions,
> then that's great and we can support it. If instead it adds a large
> amount of conditionals to the released vector extension code then I
> don't think we can take it.
>
> There is some wiggle room, but the RISC-V tree already has enough
> going on and very little reviewers. If in the future we get more
> reviewers and testers we can re-evaulate what is acceptable, but for
> now I think we need to be a little strict. (Hint to any companies to
> give developers time to review)
>
> >
> > So let's assume such a (very significant) addition were factored out
> > similarly, interfacing just through a hook in decode_op and
> > argument-parsing logic that ensures that the conflicting
> > standard-extension is turned off: would this 

Re: [PATCH v2 2/2] target/riscv: Add XVentanaCondOps custom extension

2022-01-18 Thread Alistair Francis
On Wed, Jan 19, 2022 at 9:22 AM Philipp Tomsich
 wrote:
>
> Alistair,
>
> Some of us (the merit almost exclusively goes to Kito) have been
> working towards a similar policy for GCC/binutils and LLVM.
> This currently lives in:
>https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/17

Ah cool! We can use that as a good starting point.

>
> A few comments & a question below.
>
> Thanks,
> Philipp.
>
> On Tue, 18 Jan 2022 at 23:53, Alistair Francis  wrote:
> >
> > On Fri, Jan 14, 2022 at 6:22 AM Philipp Tomsich
> >  wrote:
> > >
> > > This adds the decoder and translation for the XVentanaCondOps custom
> > > extension (vendor-defined by Ventana Micro Systems), which is
> > > documented at 
> > > https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf
> > >
> > > This commit then also adds a guard-function (has_XVentanaCondOps_p)
> > > and the decoder function to the table of decoders, enabling the
> > > support for the XVentanaCondOps extension.
> > >
> > > Signed-off-by: Philipp Tomsich 
> >
> > This looks reasonable to me.
> >
> > I'm going to leave this for a bit in case there are any more comments.
> >
> > I was a little worried that taking vendor extensions isn't the right
> > move, as we might get stuck with a large number of them. But this is
> > pretty self contained and I think with the growing RISC-V interest
> > it's something we will eventually need to support.
> >
> > I'm going to update the QEMU RISC-V wiki page with this to make the
> > position clear (comments very welcome)
> >
> > === RISC-V Extensions ===
> > As RISC-V has a range of possible extensions, QEMU has guidelines for
> > supporting them all.
> >
> > If an extension is frozen or ratified by the RISC-V foundation, it can
> > be supported in QEMU.
> >
> > If an official RISC-V foundation extension is in a reasonable draft
> > state, that is not too many changes are still expected, it can be
> > supported experimentally by QEMU. Experimental support means it must
> > be disabled by default and marked with a "x-" in the properties. QEMU
> > will only support the latest version of patches submitted for a draft
> > extension. A draft extension can also be removed at any time if it
> > conflicts with other extensions.
> >
> > QEMU will also support vendor extensions. Vendor extensions must be
> > disabled by default, but can be enabled for specific vendor CPUs and
> > boards. Vendor extensions must be maintained and tested by the vendor.
>
> I guess I should create a v3 with appropriate paths in the MAINTAINERS file?

Hmm... Good point. I don't think you have to if you don't want to.

My point here was more to just make it clear that upstream QEMU is not
a dumping ground for vendor extensions to get them maintained by
someone else. Obviously we won't purposely break things just for fun.
There is an expectation that the vendor tests their extensions and
responds to bug reports and things like that.

>
> > Vendor extensions can not interfere with other extensions and can not
> > be obtrusive to the RISC-V target code.
>
> I know that there is some interest to have the XtheadV (the
> instructions previously known as vectors 0.7.1-draft) supported and we
> have the reality of a deployed base that implements it in hardware.
> This would conflict with the opcode space used by the standard RISC-V
> vectors, so it makes for an interesting test case (even if just to
> clarify our intent)...
> Personally, I would like to avoid precluding inclusion of something
> useful (of course, "Vendor extensions must be maintained and tested by
> the vendor." has to apply!), if a vendor was going to step up and also
> offers to maintain it.

Yeah... this is unfortunate. I agree that having the 0.7.1-draft
extensions supported would be great. There is hardware that supports
it.

I think this point still stands though. IF the XtheadV implementation
is self contained and doesn't interfere with the vector extensions,
then that's great and we can support it. If instead it adds a large
amount of conditionals to the released vector extension code then I
don't think we can take it.

There is some wiggle room, but the RISC-V tree already has enough
going on and very little reviewers. If in the future we get more
reviewers and testers we can re-evaulate what is acceptable, but for
now I think we need to be a little strict. (Hint to any companies to
give developers time to review)

>
> So let's assume such a (very significant) addition were factored out
> similarly, interfacing just through a hook in decode_op and
> argument-parsing logic that ensures that the conflicting
> standard-extension is turned off: would this still be acceptable under
> this policy — or would it trip the "obtrusive" condition?

I think that would be acceptable, I wouldn't say that is obtrusive as
it's self contained.

Alistair

>
> >
> > Alistair
> >
> > >
> > > ---
> > >
> > > Changes in v2:
> > > - Split off 

Re: [PATCH] meson.build: Use a function from libfdt 1.5.1 for the library check

2022-01-18 Thread David Gibson
On Tue, Jan 18, 2022 at 06:05:48PM +0100, Thomas Huth wrote:
> The fdt version test in meson.build uses a function from libfdt v1.4.7,
> but we require version 1.5.1 nowadays. Thus use a function that has
> been introduced in that version instead.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/822
> Signed-off-by: Thomas Huth 

Reviewed-by: David Gibson 

> ---
>  meson.build | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/meson.build b/meson.build
> index 762d7cee85..d1cc04c7a2 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2276,7 +2276,7 @@ if have_system
>  if fdt.found() and cc.links('''
> #include 
> #include 
> -   int main(void) { fdt_check_full(NULL, 0); return 0; }''',
> +   int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
>   dependencies: fdt)
>fdt_opt = 'system'
>  elif fdt_opt == 'system'

-- 
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 v2 1/2] python: introduce qmp-shell-wrap convenience tool

2022-01-18 Thread John Snow
On Tue, Jan 18, 2022 at 5:01 AM Daniel P. Berrangé  wrote:
>
> With the current 'qmp-shell' tool developers must first spawn QEMU with
> a suitable -qmp arg and then spawn qmp-shell in a separate terminal
> pointing to the right socket.
>
> With 'qmp-shell-wrap' developers can ignore QMP sockets entirely and
> just pass the QEMU command and arguments they want. The program will
> listen on a UNIX socket and tell QEMU to connect QMP to that.
>
> For example, this:
>
>  # qmp-shell-wrap -- qemu-system-x86_64 -display none
>
> Is roughly equivalent of running:
>
>  # qemu-system-x86_64 -display none -qmp qmp-shell-1234 &
>  # qmp-shell qmp-shell-1234
>
> Except that 'qmp-shell-wrap' switches the socket peers around so that
> it is the UNIX socket server and QEMU is the socket client. This makes
> QEMU reliably go away when qmp-shell-wrap exits, closing the server
> socket.
>
> Signed-off-by: Daniel P. Berrangé 

Thanks, I think this is pretty useful.

Can you look at setup.cfg and see about adding a qmp-shell-wrap entry
point there? I had intended to wean people off of using /scripts for
things that rely on the QMP packages, because I'm gonna fork them out
and then these little forwards won't work without installing something
anyway.

Also, as an FYI: Stuff that sticks around in /python/qemu/qmp/ is
going to get forked out and uploaded to PyPI; stuff that gets added to
/python/qemu/utils is going to stay local to our tree and has more
freedom to be changed liberally. If you don't think this script
belongs on PyPI, we could always stick it in util.

--js




Re: [PATCH v2 00/13] arm gicv3 ITS: Various bug fixes and refactorings

2022-01-18 Thread Andre Przywara
On Tue, 18 Jan 2022 19:41:56 +
Peter Maydell  wrote:

Hi Peter, Alex,

thanks for the heads up!

> On Tue, 18 Jan 2022 at 17:42, Alex Bennée  wrote:
> >
> >
> > Peter Maydell  writes:
> >  
> > > I've been working on the ITS to add support for the GICv4 functionality.
> > > In the course of that I found a handful of bugs in it and also some
> > > places where the code benefited from refactoring to make it a better
> > > base to put in the GICv4 parts. This patchset is just the bugfixes
> > > and cleanups, because there are enough patches here that I figured it
> > > made sense to send them out now rather than holding on to them.
> > >
> > > Most of these patches were in v1 and have been reviewed already.  
> >
> > I've reviewed the patches and they look good to me. kvm-unit-tests is
> > still failing some tests but the ones it fails hasn't changed from
> > before this patch:
> >
> >   ✗  env QEMU=$HOME/lsrc/qemu.git/builds/arm.all/qemu-system-aarch64 
> > ./run_tests.sh -g gic
> >   PASS gicv2-ipi (3 tests)
> >   PASS gicv2-mmio (17 tests, 1 skipped)
> >   FAIL gicv2-mmio-up (17 tests, 2 unexpected failures)
> >   FAIL gicv2-mmio-3p (17 tests, 3 unexpected failures)
> >   PASS gicv3-ipi (3 tests)
> >   PASS gicv2-active (1 tests)
> >   PASS gicv3-active (1 tests)
> >
> > That said running with -d unimp,guest_errors there are some things that
> > should probably be double checked, e.g.:  
> 
> Almost all of the logging seems to be where the test code is
> doing stuff that the GIC spec says isn't valid.

That sounds like a plausible explanation for a unit test suite, but
does not seem to be actually true in this case, see below.

> Also, this
> test is gicv2, which is unrelated to either the gicv3 code
> or to the ITS...

This is true.

> 
> >   /home/alex/lsrc/qemu.git/builds/arm.all/qemu-system-aarch64 -nodefaults 
> > -machine virt -accel tcg -cpu cortex-a57 -device virtio-serial-device 
> > -device virtconsole,chardev=
> >   ctd -chardev testdev,id=ctd -device pci-testdev -display none -serial 
> > stdio -kernel arm/gic.flat -machine gic-version=2 -smp 1 -append "mmio" -d 
> > unimp,guest_errors
> >   PASS: gicv2: mmio: all CPUs have interrupts
> >   gic_dist_readb: Bad offset 8
> >   gic_dist_readb: Bad offset 9
> >   gic_dist_readb: Bad offset a
> >   gic_dist_readb: Bad offset b  
> 
> This is GICD_IIDR, which is a 32-bit register. The test looks like it's
> trying to read it as 4 separate bytes, which is out of spec, and
> is why our implementation is warning about it.

Looking at k-u-t's arm/gic.c and QEMU's hw/intc/arm_gic.c I see two
problems here: QEMU implements word accesses as four successive calls to
gic_dist_readb() - which is probably fine if that helps code design,
but it won't allow it to actually spot access size issues. I just
remember that we spent some brain cells and CPP macros on getting the
access size right in KVM - hence those tests in kvm-unit-tests.
 
But more importantly it looks like GICD_IIDR is actually not
implemented: There is a dubious "if (offset < 0x08) return 0;" line,
but IIDR (offset 0x8) would actually fall through, and hit the bad_reg
label, which would return 0 (and cause the message, if enabled).
Also the name and how it's called suggests that this deals with bytes
only, but returns uint32_t, and for instance deals with bit 10 in
TYPER. I see how this eventually falls into place magically (the upper
three bytes return 0, and get ORed into the >8 bit result of offset 8),
but those messages are definitely false alarm then.

If that helps: from a GIC MMIO perspective 8-bit accesses are actually
the exception rather than the norm (ARM IHI 0048B.b 4.1.4 GIC register
access).

> >   INFO: gicv2: mmio: IIDR: 0x
> >   gic_dist_writeb: Bad offset 4
> >   gic_dist_writeb: Bad offset 5
> >   gic_dist_writeb: Bad offset 6
> >   gic_dist_writeb: Bad offset 7
> >   gic_dist_writeb: Bad offset 4
> >   gic_dist_writeb: Bad offset 5
> >   gic_dist_writeb: Bad offset 6
> >   gic_dist_writeb: Bad offset 7
> >   gic_dist_writeb: Bad offset 4
> >   gic_dist_writeb: Bad offset 5
> >   gic_dist_writeb: Bad offset 6
> >   gic_dist_writeb: Bad offset 7  
> 
> These complaints are because the test is trying to write
> to GICD_TYPER, which is not permitted.

Writes are not permitted, yes, but k-u-t emits a proper str, so there
should be only three lines, not twelve.

> >   PASS: gicv2: mmio: GICD_TYPER is read-only
> >   gic_dist_readb: Bad offset 8
> >   gic_dist_readb: Bad offset 9
> >   gic_dist_readb: Bad offset a
> >   gic_dist_readb: Bad offset b  
> 
> More attempts to do byte accesses to a word-only register.

The messages come actually again because IIDR is not handled at all,
and there are only four of them because of the design of gic_dist_read().
k-u-t issues a proper ldr here.
I think we refrained from actually testing illegal access sizes,
because that could trigger external aborts/SErrors on real hardware.

> >   gic_dist_writeb: Bad offset 8
> >   

Re: [PATCH v2 2/2] target/riscv: Add XVentanaCondOps custom extension

2022-01-18 Thread Philipp Tomsich
Alistair,

Some of us (the merit almost exclusively goes to Kito) have been
working towards a similar policy for GCC/binutils and LLVM.
This currently lives in:
   https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/17

A few comments & a question below.

Thanks,
Philipp.

On Tue, 18 Jan 2022 at 23:53, Alistair Francis  wrote:
>
> On Fri, Jan 14, 2022 at 6:22 AM Philipp Tomsich
>  wrote:
> >
> > This adds the decoder and translation for the XVentanaCondOps custom
> > extension (vendor-defined by Ventana Micro Systems), which is
> > documented at 
> > https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf
> >
> > This commit then also adds a guard-function (has_XVentanaCondOps_p)
> > and the decoder function to the table of decoders, enabling the
> > support for the XVentanaCondOps extension.
> >
> > Signed-off-by: Philipp Tomsich 
>
> This looks reasonable to me.
>
> I'm going to leave this for a bit in case there are any more comments.
>
> I was a little worried that taking vendor extensions isn't the right
> move, as we might get stuck with a large number of them. But this is
> pretty self contained and I think with the growing RISC-V interest
> it's something we will eventually need to support.
>
> I'm going to update the QEMU RISC-V wiki page with this to make the
> position clear (comments very welcome)
>
> === RISC-V Extensions ===
> As RISC-V has a range of possible extensions, QEMU has guidelines for
> supporting them all.
>
> If an extension is frozen or ratified by the RISC-V foundation, it can
> be supported in QEMU.
>
> If an official RISC-V foundation extension is in a reasonable draft
> state, that is not too many changes are still expected, it can be
> supported experimentally by QEMU. Experimental support means it must
> be disabled by default and marked with a "x-" in the properties. QEMU
> will only support the latest version of patches submitted for a draft
> extension. A draft extension can also be removed at any time if it
> conflicts with other extensions.
>
> QEMU will also support vendor extensions. Vendor extensions must be
> disabled by default, but can be enabled for specific vendor CPUs and
> boards. Vendor extensions must be maintained and tested by the vendor.

I guess I should create a v3 with appropriate paths in the MAINTAINERS file?

> Vendor extensions can not interfere with other extensions and can not
> be obtrusive to the RISC-V target code.

I know that there is some interest to have the XtheadV (the
instructions previously known as vectors 0.7.1-draft) supported and we
have the reality of a deployed base that implements it in hardware.
This would conflict with the opcode space used by the standard RISC-V
vectors, so it makes for an interesting test case (even if just to
clarify our intent)...
Personally, I would like to avoid precluding inclusion of something
useful (of course, "Vendor extensions must be maintained and tested by
the vendor." has to apply!), if a vendor was going to step up and also
offers to maintain it.

So let's assume such a (very significant) addition were factored out
similarly, interfacing just through a hook in decode_op and
argument-parsing logic that ensures that the conflicting
standard-extension is turned off: would this still be acceptable under
this policy — or would it trip the "obtrusive" condition?

>
> Alistair
>
> >
> > ---
> >
> > Changes in v2:
> > - Split off decode table into XVentanaCondOps.decode
> > - Wire up XVentanaCondOps in the decoder-table
> >
> >  target/riscv/XVentanaCondOps.decode   | 25 
> >  target/riscv/cpu.c|  3 ++
> >  target/riscv/cpu.h|  3 ++
> >  .../insn_trans/trans_xventanacondops.inc  | 39 +++
> >  target/riscv/meson.build  |  1 +
> >  target/riscv/translate.c  | 13 +++
> >  6 files changed, 84 insertions(+)
> >  create mode 100644 target/riscv/XVentanaCondOps.decode
> >  create mode 100644 target/riscv/insn_trans/trans_xventanacondops.inc
> >
> > diff --git a/target/riscv/XVentanaCondOps.decode 
> > b/target/riscv/XVentanaCondOps.decode
> > new file mode 100644
> > index 00..5aef7c3d72
> > --- /dev/null
> > +++ b/target/riscv/XVentanaCondOps.decode
> > @@ -0,0 +1,25 @@
> > +#
> > +# RISC-V translation routines for the XVentanaCondOps extension
> > +#
> > +# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.toms...@vrull.eu
> > +#
> > +# SPDX-License-Identifier: LGPL-2.1-or-later
> > +#
> > +# Reference: VTx-family custom instructions
> > +#Custom ISA extensions for Ventana Micro Systems RISC-V cores
> > +#
> > (https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf)
> > +
> > +# Fields
> > +%rs2  20:5
> > +%rs1  15:5
> > +%rd7:5
> > +
> > +# Argument sets
> > +rd rs1 rs2  !extern
> > +
> 

Re: [PATCH v2 2/2] target/riscv: Add XVentanaCondOps custom extension

2022-01-18 Thread Alistair Francis
On Fri, Jan 14, 2022 at 6:22 AM Philipp Tomsich
 wrote:
>
> This adds the decoder and translation for the XVentanaCondOps custom
> extension (vendor-defined by Ventana Micro Systems), which is
> documented at 
> https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf
>
> This commit then also adds a guard-function (has_XVentanaCondOps_p)
> and the decoder function to the table of decoders, enabling the
> support for the XVentanaCondOps extension.
>
> Signed-off-by: Philipp Tomsich 

This looks reasonable to me.

I'm going to leave this for a bit in case there are any more comments.

I was a little worried that taking vendor extensions isn't the right
move, as we might get stuck with a large number of them. But this is
pretty self contained and I think with the growing RISC-V interest
it's something we will eventually need to support.

I'm going to update the QEMU RISC-V wiki page with this to make the
position clear (comments very welcome)

=== RISC-V Extensions ===
As RISC-V has a range of possible extensions, QEMU has guidelines for
supporting them all.

If an extension is frozen or ratified by the RISC-V foundation, it can
be supported in QEMU.

If an official RISC-V foundation extension is in a reasonable draft
state, that is not too many changes are still expected, it can be
supported experimentally by QEMU. Experimental support means it must
be disabled by default and marked with a "x-" in the properties. QEMU
will only support the latest version of patches submitted for a draft
extension. A draft extension can also be removed at any time if it
conflicts with other extensions.

QEMU will also support vendor extensions. Vendor extensions must be
disabled by default, but can be enabled for specific vendor CPUs and
boards. Vendor extensions must be maintained and tested by the vendor.
Vendor extensions can not interfere with other extensions and can not
be obtrusive to the RISC-V target code.

Alistair

>
> ---
>
> Changes in v2:
> - Split off decode table into XVentanaCondOps.decode
> - Wire up XVentanaCondOps in the decoder-table
>
>  target/riscv/XVentanaCondOps.decode   | 25 
>  target/riscv/cpu.c|  3 ++
>  target/riscv/cpu.h|  3 ++
>  .../insn_trans/trans_xventanacondops.inc  | 39 +++
>  target/riscv/meson.build  |  1 +
>  target/riscv/translate.c  | 13 +++
>  6 files changed, 84 insertions(+)
>  create mode 100644 target/riscv/XVentanaCondOps.decode
>  create mode 100644 target/riscv/insn_trans/trans_xventanacondops.inc
>
> diff --git a/target/riscv/XVentanaCondOps.decode 
> b/target/riscv/XVentanaCondOps.decode
> new file mode 100644
> index 00..5aef7c3d72
> --- /dev/null
> +++ b/target/riscv/XVentanaCondOps.decode
> @@ -0,0 +1,25 @@
> +#
> +# RISC-V translation routines for the XVentanaCondOps extension
> +#
> +# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.toms...@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# Reference: VTx-family custom instructions
> +#Custom ISA extensions for Ventana Micro Systems RISC-V cores
> +#
> (https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf)
> +
> +# Fields
> +%rs2  20:5
> +%rs1  15:5
> +%rd7:5
> +
> +# Argument sets
> +rd rs1 rs2  !extern
> +
> +# Formats
> +@r ...  . . ... . ... %rs2 
> %rs1 %rd
> +
> +# *** RV64 Custom-3 Extension ***
> +vt_maskc   000  . . 110 . 011 @r
> +vt_maskcn  000  . . 111 . 011 @r
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9bc25d3055..fc8ab1dc2b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -673,6 +673,9 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
>  DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
>
> +/* Vendor-specific custom extensions */
> +DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
> false),
> +
>  /* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
>  /* ePMP 0.9.3 */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d63086765..ffde94fd1a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -330,6 +330,9 @@ struct RISCVCPU {
>  bool ext_zfh;
>  bool ext_zfhmin;
>
> +/* Vendor-specific custom extensions */
> +bool ext_XVentanaCondOps;
> +
>  char *priv_spec;
>  char *user_spec;
>  char *bext_spec;
> diff --git a/target/riscv/insn_trans/trans_xventanacondops.inc 
> b/target/riscv/insn_trans/trans_xventanacondops.inc
> new file mode 100644
> index 00..b8a5d031b5
> --- /dev/null
> +++ 

Re: [PATCH] meson.build: Use a function from libfdt 1.5.1 for the library check

2022-01-18 Thread Alistair Francis
On Wed, Jan 19, 2022 at 3:42 AM Thomas Huth  wrote:
>
> The fdt version test in meson.build uses a function from libfdt v1.4.7,
> but we require version 1.5.1 nowadays. Thus use a function that has
> been introduced in that version instead.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/822
> Signed-off-by: Thomas Huth 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  meson.build | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/meson.build b/meson.build
> index 762d7cee85..d1cc04c7a2 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2276,7 +2276,7 @@ if have_system
>  if fdt.found() and cc.links('''
> #include 
> #include 
> -   int main(void) { fdt_check_full(NULL, 0); return 0; }''',
> +   int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
>   dependencies: fdt)
>fdt_opt = 'system'
>  elif fdt_opt == 'system'
> --
> 2.27.0
>
>



Re: [PATCH v2 2/3] hw/riscv: Remove macros for ELF BIOS image names

2022-01-18 Thread Alistair Francis
On Tue, Jan 18, 2022 at 9:18 PM Anup Patel  wrote:
>
> Now that RISC-V Spike machine can use BIN BIOS images, we remove
> the macros used for ELF BIOS image names.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/spike.c| 4 ++--
>  include/hw/riscv/boot.h | 2 --
>  2 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 597df4c288..d059a67f9b 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -260,11 +260,11 @@ static void spike_board_init(MachineState *machine)
>   */
>  if (riscv_is_32bit(>soc[0])) {
>  firmware_end_addr = riscv_find_and_load_firmware(machine,
> -RISCV32_BIOS_ELF, 
> memmap[SPIKE_DRAM].base,
> +RISCV32_BIOS_BIN, 
> memmap[SPIKE_DRAM].base,
>  htif_symbol_callback);
>  } else {
>  firmware_end_addr = riscv_find_and_load_firmware(machine,
> -RISCV64_BIOS_ELF, 
> memmap[SPIKE_DRAM].base,
> +RISCV64_BIOS_BIN, 
> memmap[SPIKE_DRAM].base,
>  htif_symbol_callback);
>  }
>
> diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
> index baff11dd8a..d486392cd0 100644
> --- a/include/hw/riscv/boot.h
> +++ b/include/hw/riscv/boot.h
> @@ -25,9 +25,7 @@
>  #include "hw/riscv/riscv_hart.h"
>
>  #define RISCV32_BIOS_BIN"opensbi-riscv32-generic-fw_dynamic.bin"
> -#define RISCV32_BIOS_ELF"opensbi-riscv32-generic-fw_dynamic.elf"
>  #define RISCV64_BIOS_BIN"opensbi-riscv64-generic-fw_dynamic.bin"
> -#define RISCV64_BIOS_ELF"opensbi-riscv64-generic-fw_dynamic.elf"
>
>  bool riscv_is_32bit(RISCVHartArrayState *harts);
>
> --
> 2.25.1
>
>



Re: [PATCH v2 3/3] roms/opensbi: Remove ELF images

2022-01-18 Thread Alistair Francis
On Tue, Jan 18, 2022 at 9:22 PM Anup Patel  wrote:
>
> Now that all RISC-V machines can use OpenSBI BIN images, we remove
> OpenSBI ELF images and also exclude these images from BIOS build.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

In future it's best to not send a large binary blob:
https://www.qemu.org/docs/master/devel/submitting-a-patch.html#avoid-posting-large-binary-blob

Alistair

> ---
>  pc-bios/meson.build|   2 --
>  pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | Bin 838904 -> 0 bytes
>  pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | Bin 934696 -> 0 bytes
>  roms/Makefile  |   2 --
>  4 files changed, 4 deletions(-)
>  delete mode 100644 pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
>  delete mode 100644 pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
>
> diff --git a/pc-bios/meson.build b/pc-bios/meson.build
> index 1812a4084f..4ac7a5509b 100644
> --- a/pc-bios/meson.build
> +++ b/pc-bios/meson.build
> @@ -80,8 +80,6 @@ blobs = files(
>'hppa-firmware.img',
>'opensbi-riscv32-generic-fw_dynamic.bin',
>'opensbi-riscv64-generic-fw_dynamic.bin',
> -  'opensbi-riscv32-generic-fw_dynamic.elf',
> -  'opensbi-riscv64-generic-fw_dynamic.elf',
>'npcm7xx_bootrom.bin',
>  )
>



Re: [PULL 00/31] ppc queue

2022-01-18 Thread Peter Maydell
On Tue, 18 Jan 2022 at 13:07, Cédric Le Goater  wrote:
>
> The following changes since commit 6621441db50d5bae7e34dbd04bf3c57a27a71b32:
>
>   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-20220115' 
> into staging (2022-01-16 20:12:23 +)
>
> are available in the Git repository at:
>
>   https://github.com/legoater/qemu/ tags/pull-ppc-20220118
>
> for you to fetch changes up to ba49190107ee9803fb2f336b15283b457384b178:
>
>   ppc/pnv: Remove PHB4 version property (2022-01-18 12:56:31 +0100)
>
> 
> ppc 7.0 queue:
>
> * More documentation updates (Leonardo)
> * Fixes for the 7448 CPU (Fabiano and Cedric)
> * Final removal of 403 CPUs and the .load_state_old handler (Cedric)
> * More cleanups of PHB4 models (Daniel and Cedric)
>


Applied, thanks.

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

-- PMM



Re: [PATCH v2 1/3] hw/riscv: spike: Allow using binary firmware as bios

2022-01-18 Thread Alistair Francis
On Tue, Jan 18, 2022 at 9:24 PM Anup Patel  wrote:
>
> Currently, we have to use OpenSBI firmware ELF as bios for the spike
> machine because the HTIF console requires ELF for parsing "fromhost"
> and "tohost" symbols.
>
> The latest OpenSBI can now optionally pick-up HTIF register address
> from HTIF DT node so using this feature spike machine can now use
> OpenSBI firmware BIN as bios.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/char/riscv_htif.c | 33 +++--
>  hw/riscv/spike.c | 41 ++--
>  include/hw/char/riscv_htif.h |  5 -
>  include/hw/riscv/spike.h |  1 +
>  4 files changed, 52 insertions(+), 28 deletions(-)
>
> diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
> index ddae738d56..729edbf968 100644
> --- a/hw/char/riscv_htif.c
> +++ b/hw/char/riscv_htif.c
> @@ -228,13 +228,25 @@ static const MemoryRegionOps htif_mm_ops = {
>  .write = htif_mm_write,
>  };
>
> +bool htif_uses_elf_symbols(void)
> +{
> +return (address_symbol_set == 3) ? true : false;
> +}
> +
>  HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
> -CPURISCVState *env, Chardev *chr)
> +CPURISCVState *env, Chardev *chr, uint64_t nonelf_base)
>  {
> -uint64_t base = MIN(tohost_addr, fromhost_addr);
> -uint64_t size = MAX(tohost_addr + 8, fromhost_addr + 8) - base;
> -uint64_t tohost_offset = tohost_addr - base;
> -uint64_t fromhost_offset = fromhost_addr - base;
> +uint64_t base, size, tohost_offset, fromhost_offset;
> +
> +if (!htif_uses_elf_symbols()) {
> +fromhost_addr = nonelf_base;
> +tohost_addr = nonelf_base + 8;
> +}
> +
> +base = MIN(tohost_addr, fromhost_addr);
> +size = MAX(tohost_addr + 8, fromhost_addr + 8) - base;
> +tohost_offset = tohost_addr - base;
> +fromhost_offset = fromhost_addr - base;
>
>  HTIFState *s = g_malloc0(sizeof(HTIFState));
>  s->address_space = address_space;
> @@ -249,12 +261,11 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
> MemoryRegion *main_mem,
>  qemu_chr_fe_init(>chr, chr, _abort);
>  qemu_chr_fe_set_handlers(>chr, htif_can_recv, htif_recv, htif_event,
>  htif_be_change, s, NULL, true);
> -if (address_symbol_set == 3) {
> -memory_region_init_io(>mmio, NULL, _mm_ops, s,
> -  TYPE_HTIF_UART, size);
> -memory_region_add_subregion_overlap(address_space, base,
> ->mmio, 1);
> -}
> +
> +memory_region_init_io(>mmio, NULL, _mm_ops, s,
> +  TYPE_HTIF_UART, size);
> +memory_region_add_subregion_overlap(address_space, base,
> +>mmio, 1);
>
>  return s;
>  }
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 288d69cd9f..597df4c288 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -42,6 +42,7 @@
>
>  static const MemMapEntry spike_memmap[] = {
>  [SPIKE_MROM] = { 0x1000, 0xf000 },
> +[SPIKE_HTIF] = {  0x100, 0x1000 },
>  [SPIKE_CLINT] ={  0x200,0x1 },
>  [SPIKE_DRAM] = { 0x8000,0x0 },
>  };
> @@ -75,6 +76,10 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>
>  qemu_fdt_add_subnode(fdt, "/htif");
>  qemu_fdt_setprop_string(fdt, "/htif", "compatible", "ucb,htif0");
> +if (!htif_uses_elf_symbols()) {
> +qemu_fdt_setprop_cells(fdt, "/htif", "reg",
> +0x0, memmap[SPIKE_HTIF].base, 0x0, memmap[SPIKE_HTIF].size);
> +}
>
>  qemu_fdt_add_subnode(fdt, "/soc");
>  qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
> @@ -172,6 +177,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>  if (cmdline) {
>  qemu_fdt_add_subnode(fdt, "/chosen");
>  qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
>  }
>  }
>
> @@ -241,10 +247,6 @@ static void spike_board_init(MachineState *machine)
>  memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
>  machine->ram);
>
> -/* create device tree */
> -create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> -   riscv_is_32bit(>soc[0]));
> -
>  /* boot rom */
>  memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
> memmap[SPIKE_MROM].size, _fatal);
> @@ -266,6 +268,7 @@ static void spike_board_init(MachineState *machine)
>  htif_symbol_callback);
>  }
>
> +/* Load kernel */
>  if (machine->kernel_filename) {
>  kernel_start_addr = riscv_calc_kernel_start_addr(>soc[0],
>   firmware_end_addr);
> @@ -273,17 +276,6 @@ static void spike_board_init(MachineState 

Re: [PATCH 21/30] bsd-user/signal.c: force_sig

2022-01-18 Thread Warner Losh
On Thu, Jan 13, 2022 at 4:04 PM Kyle Evans  wrote:

> On Thu, Jan 13, 2022 at 2:53 PM Peter Maydell 
> wrote:
> >
> > On Thu, 13 Jan 2022 at 20:29, Peter Maydell 
> wrote:
> > >
> > > On Sun, 9 Jan 2022 at 16:44, Warner Losh  wrote:
> > > >
> > > > Force delivering a signal and generating a core file.
> >
> > > > +/* Abort execution with signal. */
> > > > +void QEMU_NORETURN force_sig(int target_sig)
> > >
> > > In linux-user we call this dump_core_and_abort(), which is
> > > a name that better describes what it's actually doing.
> > >
> > > (Today's linux-user's force_sig() does what the Linux kernel's
> > > function of that name does -- it's a wrapper around
> > > queue_signal() which delivers a signal to the guest with
> > > .si_code = SI_KERNEL , si_pid = si_uid = 0.
> > > Whether you want one of those or not depends on what BSD
> > > kernels do in that kind of "we have to kill this process"
> > > situation.)
> >
> > It looks like the FreeBSD kernel uses sigexit() as its equivalent
> > function to Linux's force_sig(), incidentally. Not sure if
> > you/we would prefer the bsd-user code to follow the naming that
> > FreeBSD's kernel uses or the naming linux-user takes from
> > the Linux kernel.
> >
>
> My $.02: let's go with linux-inherited linux-user names and drop in a
> comment with the FreeBSD name, if they're functionally similar enough
> (in general, not just for this specific case). My gut feeling is that
> it'll be more useful in the long run if we can more quickly identify
> parallels between the two, so changes affecting linux-user that may
> benefit bsd-user are more easily identified and exchanged (and
> vice-versa).
>

OK. I've updated the patches to do the renaming. There was  one bad call
to force_sig (do_sigreturn should just return EFAULT instead of generating
a core). I've also fixed the SIGILL on BSD as well. The rest all look like
they
should be renamed. None look like they were copied from linux-user and
should
be the linux version :).

Warner


Re: [PATCH v2 00/17] Add RISC-V RVV Zve32f and Zve64f extensions

2022-01-18 Thread Alistair Francis
On Tue, Jan 18, 2022 at 11:50 AM  wrote:
>
> From: Frank Chang 
>
> In RVV v1.0 spec, several Zve* vector extensions for embedded processors
> are defined in Chapter 18.2:
> https://github.com/riscv/riscv-v-spec/blob/v1.0/v-spec.adoc#zve-vector-extensions-for-embedded-processors
>
> This patchset implements Zve32f and Zve64f extensions.
>
> The port is available at:
> https://github.com/sifive/qemu/tree/rvv-zve32f-zve64f-upstream-v2
>
> Zve32f can be enabled with -cpu option: Zve32f=true and
> Zve64f can be enabled with -cpu option: Zve64f=true.
> V is not required to be enabled explicitly.
>
> Here's the inclusion diagram for the six standard vector extensions
> quoted from Nick Knight :
>
>   V
>   |
> Zve64d
>   |
> Zve64f
>/  \
> Zve64x   Zve32f
>\  /
> Zve32x
>
> Changelog:
>
> v2:
>   * Replace hardcoded TARGET_RISCV32 macro with get_xl().
>
> Frank Chang (17):
>   target/riscv: rvv-1.0: Add Zve64f extension into RISC-V
>   target/riscv: rvv-1.0: Add Zve64f support for configuration insns
>   target/riscv: rvv-1.0: Add Zve64f support for load and store insns
>   target/riscv: rvv-1.0: Add Zve64f support for vmulh variant insns
>   target/riscv: rvv-1.0: Add Zve64f support for vsmul.vv and vsmul.vx
> insns
>   target/riscv: rvv-1.0: Add Zve64f support for scalar fp insns
>   target/riscv: rvv-1.0: Add Zve64f support for single-width fp
> reduction insns
>   target/riscv: rvv-1.0: Add Zve64f support for widening type-convert
> insns
>   target/riscv: rvv-1.0: Add Zve64f support for narrowing type-convert
> insns
>   target/riscv: rvv-1.0: Allow Zve64f extension to be turned on
>   target/riscv: rvv-1.0: Add Zve32f extension into RISC-V
>   target/riscv: rvv-1.0: Add Zve32f support for configuration insns
>   target/riscv: rvv-1.0: Add Zve32f support for scalar fp insns
>   target/riscv: rvv-1.0: Add Zve32f support for single-width fp
> reduction insns
>   target/riscv: rvv-1.0: Add Zve32f support for widening type-convert
> insns
>   target/riscv: rvv-1.0: Add Zve32f support for narrowing type-convert
> insns
>   target/riscv: rvv-1.0: Allow Zve32f extension to be turned on

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  target/riscv/cpu.c  |   6 +
>  target/riscv/cpu.h  |   2 +
>  target/riscv/cpu_helper.c   |   5 +-
>  target/riscv/csr.c  |   6 +-
>  target/riscv/insn_trans/trans_rvv.c.inc | 219 
>  target/riscv/translate.c|   4 +
>  6 files changed, 205 insertions(+), 37 deletions(-)
>
> --
> 2.31.1
>
>



Re: [PATCH v6 05/12] hw/dma: Add the DMA control interface

2022-01-18 Thread Luc Michel
Hi Francisco!

On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> An option on real hardware when embedding a DMA engine into a peripheral
> is to make the peripheral control the engine through a custom DMA control
> (hardware) interface between the two. Software drivers in this scenario
> configure and trigger DMA operations through the controlling peripheral's
> register API (for example, writing a specific bit in a register could
> propagate down to a transfer start signal on the DMA control interface).
> At the same time the status, results and interrupts for the transfer might
> still be intended to be read and caught through the DMA engine's register
> API (and signals).

I understand the goal you trying to achieve here. Having a generic
interface between a peripheral and the internal DMA it's using for its
memory transfers.

I wonder however how much this scenario can be generalized. I see that
you have only one method in this interface, which is basically "perform
a DMA transaction". Given the method's parameters, the peripheral can
indicate what address/length it wants to read.

IIUC this is well suited to your case (the OSPI controller), because
other DMA parameters are configured by other means (DMA or OSPI
registers I guess).

But how much this will suite the next use case for this interface? Will
the embedded DMA be configured the same way? Maybe the method will also
require e.g., the destination buffer address?

My feeling is that this interface is quite ad-hoc for your case. It is
either going to stay really simple as it is now, and won't necessarily
fit the next similar use case, or is going to get pretty complicated to
cover all cases. For an added value I'm not sure I can see because the
pair "peripheral - DMA" seems tightly coupled to me. Do you foresee a
case where you want to be able to e.g., instantiate DMA B instead of DMA
A for the same controller?

I think you could have basically the same code by having a pointer to
your XlnxCSUDMA object (instead of the iface) in the OSPI struct, and a
function like xlnx_csu_dma_start_transfer declared in xlnx_csu_dma.h,
having the same behaviour as dma_ctrl_if_read.

Maybe I'm wrong and you actually foresee cases where the genericity this
interface gives is what you want? What do you think?

Luc

> 
> This patch adds a QEMU DMA control interface that can be used for
> modelling above scenario. Through this new interface a peripheral model
> embedding a DMA engine model will be able to directly initiate transfers
> through the DMA. At the same time the transfer state, result and
> completion signaling will be read and caught through the DMA engine
> model's register API and signaling.
> 
> Signed-off-by: Francisco Iglesias 
> ---
>  hw/dma/dma-ctrl-if.c | 30 +++
>  hw/dma/meson.build   |  1 +
>  include/hw/dma/dma-ctrl-if.h | 58 
> 
>  3 files changed, 89 insertions(+)
>  create mode 100644 hw/dma/dma-ctrl-if.c
>  create mode 100644 include/hw/dma/dma-ctrl-if.h
> 
> diff --git a/hw/dma/dma-ctrl-if.c b/hw/dma/dma-ctrl-if.c
> new file mode 100644
> index 00..895edac277
> --- /dev/null
> +++ b/hw/dma/dma-ctrl-if.c
> @@ -0,0 +1,30 @@
> +/*
> + * DMA control interface.
> + *
> + * Copyright (c) 2021 Xilinx Inc.
> + * Written by Francisco Iglesias 
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#include "qemu/osdep.h"
> +#include "exec/hwaddr.h"
> +#include "hw/dma/dma-ctrl-if.h"
> +
> +MemTxResult dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr, uint32_t len)
> +{
> +DmaCtrlIfClass *dcic =  DMA_CTRL_IF_GET_CLASS(dma);
> +return dcic->read(dma, addr, len);
> +}
> +
> +static const TypeInfo dma_ctrl_if_info = {
> +.name  = TYPE_DMA_CTRL_IF,
> +.parent= TYPE_INTERFACE,
> +.class_size = sizeof(DmaCtrlIfClass),
> +};
> +
> +static void dma_ctrl_if_register_types(void)
> +{
> +type_register_static(_ctrl_if_info);
> +}
> +
> +type_init(dma_ctrl_if_register_types)
> diff --git a/hw/dma/meson.build b/hw/dma/meson.build
> index f3f0661bc3..c43c067856 100644
> --- a/hw/dma/meson.build
> +++ b/hw/dma/meson.build
> @@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
> files('pxa2xx_dma.c'))
>  softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
>  softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
> +common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('dma-ctrl-if.c'))
> diff --git a/include/hw/dma/dma-ctrl-if.h b/include/hw/dma/dma-ctrl-if.h
> new file mode 100644
> index 00..0662149e14
> --- /dev/null
> +++ b/include/hw/dma/dma-ctrl-if.h
> @@ -0,0 +1,58 @@
> +/*
> + * DMA control interface.
> + *
> + * Copyright (c) 2021 Xilinx Inc.
> + * Written by Francisco Iglesias 
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#ifndef HW_DMA_CTRL_IF_H
> +#define 

Re: [PATCH v6 01/12] hw/misc: Add a model of Versal's PMC SLCR

2022-01-18 Thread Luc Michel
On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> Add a model of Versal's PMC SLCR (system-level control registers).
> 
> Signed-off-by: Francisco Iglesias 
> Signed-off-by: Edgar E. Iglesias 
> Reviewed-by: Peter Maydell 

Reviewed-by: Luc Michel 

> ---
>  hw/misc/meson.build|5 +-
>  hw/misc/xlnx-versal-pmc-iou-slcr.c | 1446 
> 
>  include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   78 ++
>  3 files changed, 1528 insertions(+), 1 deletion(-)
>  create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
>  create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
> 
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 3f41a3a5b2..e82628a618 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
>  ))
>  softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
>  softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
> -softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
> files('xlnx-versal-xramc.c'))
> +softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
> +  'xlnx-versal-xramc.c',
> +  'xlnx-versal-pmc-iou-slcr.c',
> +))
>  softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
> files('stm32f2xx_syscfg.c'))
>  softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
> files('stm32f4xx_syscfg.c'))
>  softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
> files('stm32f4xx_exti.c'))
> diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
> b/hw/misc/xlnx-versal-pmc-iou-slcr.c
> new file mode 100644
> index 00..07b7ebc217
> --- /dev/null
> +++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
> @@ -0,0 +1,1446 @@
> +/*
> + * QEMU model of Versal's PMC IOU SLCR (system level control registers)
> + *
> + * Copyright (c) 2021 Xilinx Inc.
> + * Written by Edgar E. Iglesias 
> + *
> + * 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/sysbus.h"
> +#include "hw/register.h"
> +#include "hw/irq.h"
> +#include "qemu/bitops.h"
> +#include "qemu/log.h"
> +#include "migration/vmstate.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
> +
> +#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
> +#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
> +#endif
> +
> +REG32(MIO_PIN_0, 0x0)
> +FIELD(MIO_PIN_0, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_0, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_0, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_0, L0_SEL, 1, 2)
> +REG32(MIO_PIN_1, 0x4)
> +FIELD(MIO_PIN_1, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_1, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_1, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_1, L0_SEL, 1, 2)
> +REG32(MIO_PIN_2, 0x8)
> +FIELD(MIO_PIN_2, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_2, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_2, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_2, L0_SEL, 1, 2)
> +REG32(MIO_PIN_3, 0xc)
> +FIELD(MIO_PIN_3, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_3, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_3, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_3, L0_SEL, 1, 2)
> +REG32(MIO_PIN_4, 0x10)
> +FIELD(MIO_PIN_4, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_4, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_4, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_4, L0_SEL, 1, 2)
> +REG32(MIO_PIN_5, 0x14)
> +FIELD(MIO_PIN_5, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_5, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_5, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_5, L0_SEL, 1, 2)
> +REG32(MIO_PIN_6, 0x18)
> +FIELD(MIO_PIN_6, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_6, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_6, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_6, L0_SEL, 1, 2)
> +REG32(MIO_PIN_7, 0x1c)
> +FIELD(MIO_PIN_7, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_7, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_7, L1_SEL, 3, 2)
> +FIELD(MIO_PIN_7, L0_SEL, 1, 2)
> +REG32(MIO_PIN_8, 0x20)
> +FIELD(MIO_PIN_8, L3_SEL, 7, 3)
> +FIELD(MIO_PIN_8, L2_SEL, 5, 2)
> +FIELD(MIO_PIN_8, L1_SEL, 3, 2)
> +

Re: [PATCH v6 04/12] include/hw/dma/xlnx_csu_dma: Add in missing includes in the header

2022-01-18 Thread Luc Michel
On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> Add in the missing includes in the header for being able to build the DMA
> model when reusing it.
> 
> Signed-off-by: Francisco Iglesias 
> Reviewed-by: Peter Maydell 

Reviewed-by: Luc Michel 

> ---
>  include/hw/dma/xlnx_csu_dma.h | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
> index 9e9dc551e9..28806628b1 100644
> --- a/include/hw/dma/xlnx_csu_dma.h
> +++ b/include/hw/dma/xlnx_csu_dma.h
> @@ -21,6 +21,11 @@
>  #ifndef XLNX_CSU_DMA_H
>  #define XLNX_CSU_DMA_H
>  
> +#include "hw/sysbus.h"
> +#include "hw/register.h"
> +#include "hw/ptimer.h"
> +#include "hw/stream.h"
> +
>  #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
>  
>  #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
> -- 
> 2.11.0
> 
> 

-- 



Re: [PATCH v6 02/12] hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models

2022-01-18 Thread Luc Michel
On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> Add an orgate and 'or' the interrupts from the BBRAM and RTC models.
> 
> Signed-off-by: Francisco Iglesias 
> Reviewed-by: Peter Maydell 

Reviewed-by: Luc Michel 

> ---
>  hw/arm/xlnx-versal-virt.c|  2 +-
>  hw/arm/xlnx-versal.c | 28 ++--
>  include/hw/arm/xlnx-versal.h |  5 +++--
>  3 files changed, 30 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 0c5edc898e..8ea9979710 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -365,7 +365,7 @@ static void fdt_add_bbram_node(VersalVirt *s)
>  qemu_fdt_add_subnode(s->fdt, name);
>  
>  qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> -   GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
> +   GIC_FDT_IRQ_TYPE_SPI, VERSAL_PMC_APB_IRQ,
> GIC_FDT_IRQ_FLAGS_LEVEL_HI);
>  qemu_fdt_setprop(s->fdt, name, "interrupt-names",
>   interrupt_names, sizeof(interrupt_names));
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index b2705b6925..fefd00b57c 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -25,6 +25,8 @@
>  #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
>  #define GEM_REVISION0x40070106
>  
> +#define VERSAL_NUM_PMC_APB_IRQS 2
> +
>  static void versal_create_apu_cpus(Versal *s)
>  {
>  int i;
> @@ -260,6 +262,25 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
>  }
>  }
>  
> +static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
> +{
> +DeviceState *orgate;
> +
> +/*
> + * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
> + * models:
> + *  - RTC
> + *  - BBRAM
> + */
> +object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
> +>pmc.apb_irq_orgate, TYPE_OR_IRQ);
> +orgate = DEVICE(>pmc.apb_irq_orgate);
> +object_property_set_int(OBJECT(orgate),
> +"num-lines", VERSAL_NUM_PMC_APB_IRQS, 
> _fatal);
> +qdev_realize(orgate, NULL, _fatal);
> +qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
> +}
> +
>  static void versal_create_rtc(Versal *s, qemu_irq *pic)
>  {
>  SysBusDevice *sbd;
> @@ -277,7 +298,8 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
>   * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
>   * supports them.
>   */
> -sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
> +sysbus_connect_irq(sbd, 1,
> +   qdev_get_gpio_in(DEVICE(>pmc.apb_irq_orgate), 0));
>  }
>  
>  static void versal_create_xrams(Versal *s, qemu_irq *pic)
> @@ -328,7 +350,8 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
>  sysbus_realize(sbd, _fatal);
>  memory_region_add_subregion(>mr_ps, MM_PMC_BBRAM_CTRL,
>  sysbus_mmio_get_region(sbd, 0));
> -sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
> +sysbus_connect_irq(sbd, 0,
> +   qdev_get_gpio_in(DEVICE(>pmc.apb_irq_orgate), 1));
>  }
>  
>  static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
> @@ -455,6 +478,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
>  versal_create_gems(s, pic);
>  versal_create_admas(s, pic);
>  versal_create_sds(s, pic);
> +versal_create_pmc_apb_irq_orgate(s, pic);
>  versal_create_rtc(s, pic);
>  versal_create_xrams(s, pic);
>  versal_create_bbram(s, pic);
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index 895ba12c61..62fb6f0a68 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -85,6 +85,8 @@ struct Versal {
>  XlnxEFuse efuse;
>  XlnxVersalEFuseCtrl efuse_ctrl;
>  XlnxVersalEFuseCache efuse_cache;
> +
> +qemu_or_irq apb_irq_orgate;
>  } pmc;
>  
>  struct {
> @@ -111,8 +113,7 @@ struct Versal {
>  #define VERSAL_GEM1_WAKE_IRQ_0 59
>  #define VERSAL_ADMA_IRQ_0  60
>  #define VERSAL_XRAM_IRQ_0  79
> -#define VERSAL_BBRAM_APB_IRQ_0 121
> -#define VERSAL_RTC_APB_ERR_IRQ 121
> +#define VERSAL_PMC_APB_IRQ 121
>  #define VERSAL_SD0_IRQ_0   126
>  #define VERSAL_EFUSE_IRQ   139
>  #define VERSAL_RTC_ALARM_IRQ   142
> -- 
> 2.11.0
> 
> 

-- 



Re: [PATCH v6 03/12] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2022-01-18 Thread Luc Michel
On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> Connect Versal's PMC SLCR (system-level control registers) model.
> 
> Signed-off-by: Francisco Iglesias 

Reviewed-by: Luc Michel 

> ---
>  hw/arm/xlnx-versal.c | 71 
> +++-
>  include/hw/arm/xlnx-versal.h |  5 
>  2 files changed, 75 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index fefd00b57c..c8c0c102c7 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -21,11 +21,13 @@
>  #include "kvm_arm.h"
>  #include "hw/misc/unimp.h"
>  #include "hw/arm/xlnx-versal.h"
> +#include "qemu/log.h"
> +#include "hw/sysbus.h"
>  
>  #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
>  #define GEM_REVISION0x40070106
>  
> -#define VERSAL_NUM_PMC_APB_IRQS 2
> +#define VERSAL_NUM_PMC_APB_IRQS 3
>  
>  static void versal_create_apu_cpus(Versal *s)
>  {
> @@ -271,6 +273,7 @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, 
> qemu_irq *pic)
>   * models:
>   *  - RTC
>   *  - BBRAM
> + *  - PMC SLCR
>   */
>  object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
>  >pmc.apb_irq_orgate, TYPE_OR_IRQ);
> @@ -392,6 +395,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
>  sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
>  }
>  
> +static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
> +{
> +SysBusDevice *sbd;
> +
> +object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", 
> >pmc.iou.slcr,
> +TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
> +
> +sbd = SYS_BUS_DEVICE(>pmc.iou.slcr);
> +sysbus_realize(sbd, _fatal);
> +
> +memory_region_add_subregion(>mr_ps, MM_PMC_PMC_IOU_SLCR,
> +sysbus_mmio_get_region(sbd, 0));
> +
> +sysbus_connect_irq(sbd, 0,
> +   qdev_get_gpio_in(DEVICE(>pmc.apb_irq_orgate), 2));
> +}
> +
>  /* This takes the board allocated linear DDR memory and creates aliases
>   * for each split DDR range/aperture on the Versal address map.
>   */
> @@ -448,8 +468,31 @@ static void versal_unimp_area(Versal *s, const char 
> *name,
>  memory_region_add_subregion(mr, base, mr_dev);
>  }
>  
> +static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
> +{
> +qemu_log_mask(LOG_UNIMP,
> +  "Selecting between enabling SD mode or eMMC mode on "
> +  "controller %d is not yet implemented\n", n);
> +}
> +
> +static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
> +{
> +qemu_log_mask(LOG_UNIMP,
> +  "Selecting between enabling the QSPI or OSPI linear 
> address "
> +  "region is not yet implemented\n");
> +}
> +
> +static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
> +{
> +qemu_log_mask(LOG_UNIMP,
> +  "PMC SLCR parity interrupt behaviour "
> +  "is not yet implemented\n");
> +}
> +
>  static void versal_unimp(Versal *s)
>  {
> +qemu_irq gpio_in;
> +
>  versal_unimp_area(s, "psm", >mr_ps,
>  MM_PSM_START, MM_PSM_END - MM_PSM_START);
>  versal_unimp_area(s, "crl", >mr_ps,
> @@ -464,6 +507,31 @@ static void versal_unimp(Versal *s)
>  MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
>  versal_unimp_area(s, "iou-scntr-seucre", >mr_ps,
>  MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
> +
> +qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
> +"sd-emmc-sel-dummy", 2);
> +qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
> +"qspi-ospi-mux-sel-dummy", 1);
> +qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
> +"irq-parity-imr-dummy", 1);
> +
> +gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
> +qdev_connect_gpio_out_named(DEVICE(>pmc.iou.slcr), "sd-emmc-sel", 0,
> +gpio_in);
> +
> +gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
> +qdev_connect_gpio_out_named(DEVICE(>pmc.iou.slcr), "sd-emmc-sel", 1,
> +gpio_in);
> +
> +gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 
> 0);
> +qdev_connect_gpio_out_named(DEVICE(>pmc.iou.slcr),
> +"qspi-ospi-mux-sel", 0,
> +gpio_in);
> +
> +gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
> +qdev_connect_gpio_out_named(DEVICE(>pmc.iou.slcr),
> +SYSBUS_DEVICE_GPIO_IRQ, 0,
> +gpio_in);
>  }
>  
>  static void versal_realize(DeviceState *dev, Error **errp)
> @@ -483,6 +551,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
>  

Re: [PATCH v6 07/12] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2022-01-18 Thread Luc Michel
Hi Francisco,

Impressive beast :-) Nicely done. Maybe I would have split it in a
couple of commits to ease review. Also, you can use 

[diff]
orderFile = scripts/git.orderfile

as a local config in your QEMU git so that files are placed in a
sensible order (.h files will come first), which ease a bit the
reviewing process.

See my remarks below. My biggest concern is about the tx_sram fifo.
The rest are small suggestions here and there.

On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
[snip]
> +
> +static int ospi_stig_membank_rd_bytes(XlnxVersalOspi *s)
> +{
> +int rd_data_fld = ARRAY_FIELD_EX32(s->regs, FLASH_COMMAND_CTRL_MEM_REG,
> +   NB_OF_STIG_READ_BYTES_FLD);
> +int sizes[6] = { 16, 32, 64, 128, 256, 512 };

static const int sizes[6]

(or return (rd_data_fld < 6) ? (1 << (4 + rd_data_fld)) : 0; )

> +return (rd_data_fld < 6) ? sizes[rd_data_fld] : 0;
> +}
> +
[snip]
> +
> +static void ospi_ahb_decoder_enable_cs(XlnxVersalOspi *s, hwaddr addr)
> +{
> +int cs = ospi_ahb_decoder_cs(s, addr);
> +
> +if (cs >= 0) {
> +for (int i = 0; i < s->num_cs; i++) {
> +if (cs == i) {
> +qemu_set_irq(s->cs_lines[i], 0);
> +} else {
> +qemu_set_irq(s->cs_lines[i], 1);
> +}

Maybe `qemu_set_irq(s->cs_lines[i], cs != i);` instead of the if/else?

> +}
> +}
> +}
> +
[snip]
> +
> +static void ospi_stig_fill_membank(XlnxVersalOspi *s)
> +{
> +int num_rd_bytes = ospi_stig_membank_rd_bytes(s);
> +int idx = num_rd_bytes - 8; /* first of last 8 */
> +int i;
> +
> +for (i = 0; i < num_rd_bytes; i++) {
> +s->stig_membank[i] = fifo8_pop(>rx_fifo);
> +}
> +

Even though ospi_stig_membank_rd_bytes is safe, I would add a

g_assert((idx + 4) < ARRAY_SIZE(s->stig_membank));

here, to be future proof :-)

> +/* Fill in lower upper regs */
> +s->regs[R_FLASH_RD_DATA_LOWER_REG] = ldl_le_p(>stig_membank[idx]);
> +s->regs[R_FLASH_RD_DATA_UPPER_REG] = ldl_le_p(>stig_membank[idx + 4]);
> +}
> +
[snip]
> +
> +static void ospi_tx_sram_write(XlnxVersalOspi *s, uint64_t value,
> +   unsigned int size)
> +{
> +int i;
> +for (i = 0; i < size; i++) {
> +fifo8_push(>tx_sram, value >> 8 * i);

By tracing the callers of this function, it seems that `size' is the
size of an MMIO access. But you don't seem to check if the tx_sram fifo
can accept `size' elements (the fifo8_push doc stats it is undefined
behaviour to push on a full fifo).

> +}
> +}
> +
> +
> +static void ospi_indac_write(void *opaque, uint64_t value, unsigned int size)
> +{
> +XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
> +
> +if (s->ind_write_disabled) {
> +g_assert_not_reached();
> +}

g_assert(!s->ind_write_disabled);

> +
> +if (!ospi_ind_op_completed(s->wr_ind_op)) {
> +ospi_tx_sram_write(s, value, size);
> +ospi_do_indirect_write(s);
> +} else {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +"OSPI wr into indac area while no ongoing indac wr\n");
> +}
> +}
> +
[snip]
> diff --git a/include/hw/ssi/xlnx-versal-ospi.h 
> b/include/hw/ssi/xlnx-versal-ospi.h
> new file mode 100644
> index 00..c454ff3016
> --- /dev/null
> +++ b/include/hw/ssi/xlnx-versal-ospi.h
> @@ -0,0 +1,111 @@
> +/*
> + * Header file for the Xilinx Versal's OSPI controller
> + *
> + * Copyright (C) 2021 Xilinx Inc
> + * Written by Francisco Iglesias 
> + *
> + * 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.
> + */
> +
> +/*
> + * This is a model of Xilinx Versal's Octal SPI flash memory controller
> + * documented in Versal's Technical Reference manual [1] and the Versal ACAP
> + * Register reference [2].
> + *
> + * References:
> + *
> + * [1] Versal ACAP Technical Reference Manual,
> + * 
> 

Re: [PATCH v7 1/5] QIOChannel: Add flags on io_writev and introduce io_flush callback

2022-01-18 Thread Leonardo Bras Soares Passos
Hello Peter,

On Thu, Jan 13, 2022 at 3:28 AM Peter Xu  wrote:
>
> On Thu, Jan 06, 2022 at 07:13:38PM -0300, Leonardo Bras wrote:
> > diff --git a/io/channel.c b/io/channel.c
> > index e8b019dc36..904855e16e 100644
> > --- a/io/channel.c
> > +++ b/io/channel.c
> > @@ -67,12 +67,13 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
> >  }
> >
> >
> > -ssize_t qio_channel_writev_full(QIOChannel *ioc,
> > -const struct iovec *iov,
> > -size_t niov,
> > -int *fds,
> > -size_t nfds,
> > -Error **errp)
> > +ssize_t qio_channel_writev_full_flags(QIOChannel *ioc,
> > +  const struct iovec *iov,
> > +  size_t niov,
> > +  int *fds,
> > +  size_t nfds,
> > +  int flags,
> > +  Error **errp)
> >  {
> >  QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
> >
> > @@ -83,7 +84,7 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
> >  return -1;
> >  }
>
> Should we better also check QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY here when
> QIO_CHANNEL_WRITE_FLAG_ZERO_COPY is set?  Just like what we do with:

Yes, that's correct.
I will also test for fds + zerocopy_flag , which should also fail here.

>
> if ((fds || nfds) &&
> !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
> error_setg_errno(errp, EINVAL,
>  "Channel does not support file descriptor passing");
> return -1;
> }
>
> I still think it's better to have the caller be crystal clear when to use
> zero_copy feature because it has implication on buffer lifetime.

I don't disagree with that suggestion.

But the buffer lifetime limitation is something on the socket
implementation, right?
There could be some synchronous zerocopy implementation that does not
require flush, and thus
don't require the buffer to be treated any special. Or am I missing something?

>
> I might have commented similar things before, but I have missed a few versions
> so I could also have missed some previous discussions..
>

That's all great suggestions Peter!  Thanks for that!

Some of the previous suggestions may have been missed because a lot of
code moved.
Sorry about that.

Best regards,
Leo




[PATCH v2 5/6] tests/qtest/vhost-user-blk-test: Factorize vq setup code

2022-01-18 Thread Eric Auger
The vq setup code is repeated several times and can be
easily factorized.

Signed-off-by: Eric Auger 
Reviewed-by: Thomas Huth 
---
 tests/qtest/vhost-user-blk-test.c | 33 +++
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/tests/qtest/vhost-user-blk-test.c 
b/tests/qtest/vhost-user-blk-test.c
index 2606428df3..9567f3dc42 100644
--- a/tests/qtest/vhost-user-blk-test.c
+++ b/tests/qtest/vhost-user-blk-test.c
@@ -211,6 +211,19 @@ static void 
test_invalid_discard_write_zeroes(QVirtioDevice *dev,
 guest_free(alloc, req_addr);
 }
 
+static QVirtQueue *setup_vq(QVirtioDevice *dev, QGuestAllocator *alloc)
+{
+QVirtioPCIDevice *vpcidev = container_of(dev, QVirtioPCIDevice, vdev);
+QVirtQueue *vq;
+
+qpci_msix_enable(vpcidev->pdev);
+qvirtio_pci_set_msix_configuration_vector(vpcidev, alloc, 0);
+
+vq = qvirtqueue_setup(dev, alloc, 0);
+qvirtqueue_pci_msix_setup(vpcidev, (QVirtQueuePCI *)vq, alloc, 1);
+return vq;
+}
+
 /* Returns the request virtqueue so the caller can perform further tests */
 static QVirtQueue *test_basic(QVirtioDevice *dev, QGuestAllocator *alloc)
 {
@@ -223,10 +236,6 @@ static QVirtQueue *test_basic(QVirtioDevice *dev, 
QGuestAllocator *alloc)
 char *data;
 QTestState *qts = global_qtest;
 QVirtQueue *vq;
-QVirtioPCIDevice *vpcidev = container_of(dev, QVirtioPCIDevice, vdev);
-
-qpci_msix_enable(vpcidev->pdev);
-qvirtio_pci_set_msix_configuration_vector(vpcidev, alloc, 0);
 
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
@@ -238,8 +247,7 @@ static QVirtQueue *test_basic(QVirtioDevice *dev, 
QGuestAllocator *alloc)
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
-vq = qvirtqueue_setup(dev, alloc, 0);
-qvirtqueue_pci_msix_setup(vpcidev, (QVirtQueuePCI *)vq, alloc, 1);
+vq = setup_vq(dev, alloc);
 
 qvirtio_set_driver_ok(dev);
 
@@ -474,10 +482,6 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 uint8_t status;
 char *data;
 QTestState *qts = global_qtest;
-QVirtioPCIDevice *vpcidev = container_of(dev, QVirtioPCIDevice, vdev);
-
-qpci_msix_enable(vpcidev->pdev);
-qvirtio_pci_set_msix_configuration_vector(vpcidev, t_alloc, 0);
 
 features = qvirtio_get_features(dev);
 g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
@@ -489,8 +493,7 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
-vq = qvirtqueue_setup(dev, t_alloc, 0);
-qvirtqueue_pci_msix_setup(vpcidev, (QVirtQueuePCI *)vq, t_alloc, 1);
+vq = setup_vq(dev, t_alloc);
 
 qvirtio_set_driver_ok(dev);
 
@@ -576,9 +579,6 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 return;
 }
 
-qpci_msix_enable(pdev->pdev);
-qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
-
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
 (1u << VIRTIO_RING_F_INDIRECT_DESC) |
@@ -589,8 +589,7 @@ static void idx(void *obj, void *u_data, QGuestAllocator 
*t_alloc)
 capacity = qvirtio_config_readq(dev, 0);
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
-vq = qvirtqueue_setup(dev, t_alloc, 0);
-qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
+vq = setup_vq(dev, t_alloc);
 
 qvirtio_set_driver_ok(dev);
 
-- 
2.26.3




Re: [PATCH 6/6] tests/qtest/libqos: Add pci-arm and add a pci-arm producer in arm-virt machine

2022-01-18 Thread Eric Auger
Hi Paolo,

On 1/15/22 5:01 PM, Paolo Bonzini wrote:
> On 1/10/22 22:19, Eric Auger wrote:
>> Up to now the virt-machine node contains a virtio-mmio node.
>> However no driver produces any PCI interface node. Hence, PCI
>> tests cannot be run with aarch64 binary.
>>
>> Add a GPEX driver node that produces a pci interface node. This latter
>> then can be consumed by all the pci tests. One of the first motivation
>> was to be able to run the virtio-iommu-pci tests.
>>
>> We still face an issue with pci hotplug tests as hotplug cannot happen
>> on the pcie root bus and require a generic root port. This will be
>> addressed later on.
>>
>> Signed-off-by: Eric Auger 
>
> Hey Eric,
>
> it's great to have gpex support in libqos/qgraph!  On the next
> versions you might also Cc Emanuele since he was the author of the
> framework.
sure!
>
>> ---
>>   tests/qtest/libqos/arm-virt-machine.c |  47 +-
>>   tests/qtest/libqos/meson.build    |   3 +
>>   tests/qtest/libqos/pci-arm.c  | 219 ++
>>   tests/qtest/libqos/pci-arm.h  |  56 +++
>>   tests/qtest/libqos/pci.h  |   1 +
>>   tests/qtest/libqos/qgraph.c   |   7 +
>>   tests/qtest/libqos/qgraph.h   |  15 ++
>>   7 files changed, 344 insertions(+), 4 deletions(-)
>>   create mode 100644 tests/qtest/libqos/pci-arm.c
>>   create mode 100644 tests/qtest/libqos/pci-arm.h
>>
>> diff --git a/tests/qtest/libqos/arm-virt-machine.c
>> b/tests/qtest/libqos/arm-virt-machine.c
>> index e0f59322845..130c45c51e2 100644
>> --- a/tests/qtest/libqos/arm-virt-machine.c
>> +++ b/tests/qtest/libqos/arm-virt-machine.c
>> @@ -22,6 +22,8 @@
>>   #include "malloc.h"
>>   #include "qgraph.h"
>>   #include "virtio-mmio.h"
>> +#include "pci-arm.h"
>> +#include "hw/pci/pci_regs.h"
>>     #define ARM_PAGE_SIZE   4096
>>   #define VIRTIO_MMIO_BASE_ADDR   0x0A003E00
>> @@ -30,13 +32,40 @@
>>   #define VIRTIO_MMIO_SIZE    0x0200
>>     typedef struct QVirtMachine QVirtMachine;
>> +typedef struct QGenericPCIHost QGenericPCIHost;
>> +
>> +struct QGenericPCIHost {
>> +    QOSGraphObject obj;
>> +    QPCIBusARM pci;
>> +};
>
> You can rename QPCIBusARM to QGenericPCIBus and move QGenericPCIHost
> to the same file.  There's nothing ARM specific in either file, and
> nothing specific to -M virt in QGenericPCIHost.

done
>
>>   struct QVirtMachine {
>>   QOSGraphObject obj;
>>   QGuestAllocator alloc;
>>   QVirtioMMIODevice virtio_mmio;
>> +    QGenericPCIHost bridge;
>>   };
>>   +/* QGenericPCIHost */
>> +
>> +static QOSGraphObject *generic_pcihost_get_device(void *obj, const
>> char *device)
>> +{
>> +    QGenericPCIHost *host = obj;
>> +    if (!g_strcmp0(device, "pci-bus-arm")) {
>> +    return >pci.obj;
>> +    }
>> +    fprintf(stderr, "%s not present in generic-pcihost\n", device);
>> +    g_assert_not_reached();
>> +}
>> +
>> +static void qos_create_generic_pcihost(QGenericPCIHost *host,
>> +   QTestState *qts,
>> +   QGuestAllocator *alloc)
>> +{
>> +    host->obj.get_device = generic_pcihost_get_device;
>> +    qpci_init_arm(>pci, qts, alloc, false);
>> +}
>> +
>>   static void virt_destructor(QOSGraphObject *obj)
>>   {
>>   QVirtMachine *machine = (QVirtMachine *) obj;
>
> This should also be in the same file as the bus implementation.
done
>
>> +    qos_node_create_driver("generic-pcihost", NULL);
>> +    qos_node_contains("generic-pcihost", "pci-bus-arm", NULL);
>
> This too, with a new libqos_init.
done
>
>
>> +static uint8_t qpci_arm_config_readb(QPCIBus *bus, int devfn,
>> uint8_t offset)
>> +{
>> +    uint64_t addr = bus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12)
>> | offset);
>
> ecam_alloc_ptr should be in QPCIBusARM (to be renamed to
> QGenericPCIBus), which you can retrieve from the "bus" QPCIBus* via
> container_of.
done
>
>> diff --git a/tests/qtest/libqos/pci-arm.h b/tests/qtest/libqos/pci-arm.h
>> new file mode 100644
>> index 000..8cd49ec2969
>> --- /dev/null
>> +++ b/tests/qtest/libqos/pci-arm.h
>> @@ -0,0 +1,56 @@
>> +/*
>> + * libqos PCI bindings for ARM
>> + *
>> + * Copyright Red Hat Inc., 2021
>> + *
>> + * Authors:
>> + *  Eric Auger   
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2
>> or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#ifndef LIBQOS_PCI_ARM_H
>> +#define LIBQOS_PCI_ARM_H
>> +
>> +#include "pci.h"
>> +#include "malloc.h"
>> +#include "qgraph.h"
>> +
>> +typedef struct QPCIBusARM {
>> +    QOSGraphObject obj;
>> +    QPCIBus bus;
>> +    uint64_t gpex_pio_base;
>> +} QPCIBusARM;
>> +
>> +/*
>> + * qpci_init_arm():
>> + * @ret: A valid QPCIBusARM * pointer
>> + * @qts: The %QTestState for this ARM machine
>> + * @alloc: A previously initialized @alloc providing memory for @qts
>> + * @bool: devices can be hotplugged on this bus
>> + *
>> + * This function initializes an already allocated
>> 

[PATCH v2 3/6] tests/qtest/libqos: Skip hotplug tests if pci root bus is not hotpluggable

2022-01-18 Thread Eric Auger
ARM does not not support hotplug on pcie.0. Add a flag on the bus
which tells if devices can be hotplugged and skip hotplug tests
if the bus cannot be hotplugged. This is a temporary solution to
enable the other pci tests on aarch64.

Signed-off-by: Eric Auger 
Acked-by: Thomas Huth 

---

v1 ->v2:
- reword g_test_skip msg into "pci bus does not support hotplug"
---
 tests/qtest/e1000e-test.c |  6 ++
 tests/qtest/libqos/pci.h  |  1 +
 tests/qtest/vhost-user-blk-test.c | 10 ++
 tests/qtest/virtio-blk-test.c |  5 +
 tests/qtest/virtio-net-test.c |  5 +
 tests/qtest/virtio-rng-test.c |  5 +
 6 files changed, 32 insertions(+)

diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
index 0273fe4c15..48f3dbb0fd 100644
--- a/tests/qtest/e1000e-test.c
+++ b/tests/qtest/e1000e-test.c
@@ -235,6 +235,12 @@ static void test_e1000e_multiple_transfers(void *obj, void 
*data,
 static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc)
 {
 QTestState *qts = global_qtest;  /* TODO: get rid of global_qtest here */
+QE1000E_PCI *dev = obj;
+
+if (dev->pci_dev.bus->not_hotpluggable) {
+g_test_skip("pci bus does not support hotplug");
+return;
+}
 
 qtest_qmp_device_add(qts, "e1000e", "e1000e_net", "{'addr': '0x06'}");
 qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06);
diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
index 44f6806fe4..6a28b40522 100644
--- a/tests/qtest/libqos/pci.h
+++ b/tests/qtest/libqos/pci.h
@@ -52,6 +52,7 @@ struct QPCIBus {
 uint64_t pio_alloc_ptr, pio_limit;
 uint64_t mmio_alloc_ptr, mmio_limit;
 bool has_buggy_msi; /* TRUE for spapr, FALSE for pci */
+bool not_hotpluggable; /* TRUE if devices cannot be hotplugged */
 
 };
 
diff --git a/tests/qtest/vhost-user-blk-test.c 
b/tests/qtest/vhost-user-blk-test.c
index 62e670f39b..1316aae0fa 100644
--- a/tests/qtest/vhost-user-blk-test.c
+++ b/tests/qtest/vhost-user-blk-test.c
@@ -676,6 +676,11 @@ static void pci_hotplug(void *obj, void *data, 
QGuestAllocator *t_alloc)
 QVirtioPCIDevice *dev;
 QTestState *qts = dev1->pdev->bus->qts;
 
+if (dev1->pdev->bus->not_hotpluggable) {
+g_test_skip("pci bus does not support hotplug");
+return;
+}
+
 /* plug secondary disk */
 qtest_qmp_device_add(qts, "vhost-user-blk-pci", "drv1",
  "{'addr': %s, 'chardev': 'char2'}",
@@ -703,6 +708,11 @@ static void multiqueue(void *obj, void *data, 
QGuestAllocator *t_alloc)
 uint64_t features;
 uint16_t num_queues;
 
+if (pdev1->pdev->bus->not_hotpluggable) {
+g_test_skip("bus pci.0 does not support hotplug");
+return;
+}
+
 /*
  * The primary device has 1 queue and VIRTIO_BLK_F_MQ is not enabled. The
  * VIRTIO specification allows VIRTIO_BLK_F_MQ to be enabled when there is
diff --git a/tests/qtest/virtio-blk-test.c b/tests/qtest/virtio-blk-test.c
index 2a23698211..acb44c9fb8 100644
--- a/tests/qtest/virtio-blk-test.c
+++ b/tests/qtest/virtio-blk-test.c
@@ -701,6 +701,11 @@ static void pci_hotplug(void *obj, void *data, 
QGuestAllocator *t_alloc)
 QVirtioPCIDevice *dev;
 QTestState *qts = dev1->pdev->bus->qts;
 
+if (dev1->pdev->bus->not_hotpluggable) {
+g_test_skip("pci bus does not support hotplug");
+return;
+}
+
 /* plug secondary disk */
 qtest_qmp_device_add(qts, "virtio-blk-pci", "drv1",
  "{'addr': %s, 'drive': 'drive1'}",
diff --git a/tests/qtest/virtio-net-test.c b/tests/qtest/virtio-net-test.c
index 8bf74e516c..af3027144f 100644
--- a/tests/qtest/virtio-net-test.c
+++ b/tests/qtest/virtio-net-test.c
@@ -174,6 +174,11 @@ static void hotplug(void *obj, void *data, QGuestAllocator 
*t_alloc)
 QTestState *qts = dev->pdev->bus->qts;
 const char *arch = qtest_get_arch();
 
+if (dev->pdev->bus->not_hotpluggable) {
+g_test_skip("pci bus does not support hotplug");
+return;
+}
+
 qtest_qmp_device_add(qts, "virtio-net-pci", "net1",
  "{'addr': %s}", stringify(PCI_SLOT_HP));
 
diff --git a/tests/qtest/virtio-rng-test.c b/tests/qtest/virtio-rng-test.c
index e6b8cd8e0c..5ce444ad72 100644
--- a/tests/qtest/virtio-rng-test.c
+++ b/tests/qtest/virtio-rng-test.c
@@ -20,6 +20,11 @@ static void rng_hotplug(void *obj, void *data, 
QGuestAllocator *alloc)
 QVirtioPCIDevice *dev = obj;
 QTestState *qts = dev->pdev->bus->qts;
 
+   if (dev->pdev->bus->not_hotpluggable) {
+g_test_skip("pci bus does not support hotplug");
+return;
+}
+
 const char *arch = qtest_get_arch();
 
 qtest_qmp_device_add(qts, "virtio-rng-pci", "rng1",
-- 
2.26.3




[PATCH v2 4/6] tests/qtest/vhost-user-blk-test: Setup MSIx to avoid error on aarch64

2022-01-18 Thread Eric Auger
When run on ARM, basic and indirect tests currently fail with the
following error:

ERROR:../tests/qtest/libqos/virtio.c:224:qvirtio_wait_used_elem:
assertion failed (got_desc_idx == desc_idx): (50331648 == 0)
Bail out! ERROR:../tests/qtest/libqos/virtio.c:224: qvirtio_wait_used_elem:
assertion failed (got_desc_idx == desc_idx): (50331648 == 0)

Setting up and enabling MSIX fixes the issue.

Also remove the useless libqos/libqos-pc.h header inclusion.

Signed-off-by: Eric Auger 
Acked-by: Thomas Huth 
---
 tests/qtest/vhost-user-blk-test.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/vhost-user-blk-test.c 
b/tests/qtest/vhost-user-blk-test.c
index 1316aae0fa..2606428df3 100644
--- a/tests/qtest/vhost-user-blk-test.c
+++ b/tests/qtest/vhost-user-blk-test.c
@@ -19,7 +19,6 @@
 #include "standard-headers/linux/virtio_pci.h"
 #include "libqos/qgraph.h"
 #include "libqos/vhost-user-blk.h"
-#include "libqos/libqos-pc.h"
 
 #define TEST_IMAGE_SIZE (64 * 1024 * 1024)
 #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
@@ -224,6 +223,10 @@ static QVirtQueue *test_basic(QVirtioDevice *dev, 
QGuestAllocator *alloc)
 char *data;
 QTestState *qts = global_qtest;
 QVirtQueue *vq;
+QVirtioPCIDevice *vpcidev = container_of(dev, QVirtioPCIDevice, vdev);
+
+qpci_msix_enable(vpcidev->pdev);
+qvirtio_pci_set_msix_configuration_vector(vpcidev, alloc, 0);
 
 features = qvirtio_get_features(dev);
 features = features & ~(QVIRTIO_F_BAD_FEATURE |
@@ -236,9 +239,12 @@ static QVirtQueue *test_basic(QVirtioDevice *dev, 
QGuestAllocator *alloc)
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
 vq = qvirtqueue_setup(dev, alloc, 0);
+qvirtqueue_pci_msix_setup(vpcidev, (QVirtQueuePCI *)vq, alloc, 1);
 
 qvirtio_set_driver_ok(dev);
 
+qvirtio_wait_queue_isr(qts, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+
 /* Write and read with 3 descriptor layout */
 /* Write request */
 req.type = VIRTIO_BLK_T_OUT;
@@ -468,6 +474,10 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 uint8_t status;
 char *data;
 QTestState *qts = global_qtest;
+QVirtioPCIDevice *vpcidev = container_of(dev, QVirtioPCIDevice, vdev);
+
+qpci_msix_enable(vpcidev->pdev);
+qvirtio_pci_set_msix_configuration_vector(vpcidev, t_alloc, 0);
 
 features = qvirtio_get_features(dev);
 g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
@@ -480,8 +490,12 @@ static void indirect(void *obj, void *u_data, 
QGuestAllocator *t_alloc)
 g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
 vq = qvirtqueue_setup(dev, t_alloc, 0);
+qvirtqueue_pci_msix_setup(vpcidev, (QVirtQueuePCI *)vq, t_alloc, 1);
+
 qvirtio_set_driver_ok(dev);
 
+qvirtio_wait_queue_isr(qts, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+
 /* Write request */
 req.type = VIRTIO_BLK_T_OUT;
 req.ioprio = 1;
-- 
2.26.3




[PATCH v2 6/6] tests/qtest/libqos: Add generic pci host bridge in arm-virt machine

2022-01-18 Thread Eric Auger
Up to now the virt-machine node contains a virtio-mmio node.
However no driver produces any PCI interface node. Hence, PCI
tests cannot be run with aarch64 binary.

Add a GPEX driver node that produces a pci interface node. This latter
then can be consumed by all the pci tests. One of the first motivation
was to be able to run the virtio-iommu-pci tests.

We still face an issue with pci hotplug tests as hotplug cannot happen
on the pcie root bus and require a generic root port. This will be
addressed later on.

Signed-off-by: Eric Auger 

---
v1 -> v2:
- copyright updated to 2022
- QPCIBusARM renamed into QGenericPCIBus
- QGenericPCIHost declarations and definitions moved in the same
  place as the generic pci implementation
- rename pci-arm.c/h in generic-pcihost.c/h and remove any ref to
  ARM there
- remove qos_node_produces_opts, qpci_new_arm, qpci_free_arm
- ecam_alloc_ptr now is a field of QGenericPCIBus and not QPCIBus
- new libqos_init to create generic-pcihost driver that contains
  pci-bus-generic
- QGenericPCIHost moved in the same place as the generic pci
  bindings
---
 tests/qtest/libqos/arm-virt-machine.c |  18 +-
 tests/qtest/libqos/generic-pcihost.c  | 231 ++
 tests/qtest/libqos/generic-pcihost.h  |  54 ++
 tests/qtest/libqos/meson.build|   1 +
 4 files changed, 300 insertions(+), 4 deletions(-)
 create mode 100644 tests/qtest/libqos/generic-pcihost.c
 create mode 100644 tests/qtest/libqos/generic-pcihost.h

diff --git a/tests/qtest/libqos/arm-virt-machine.c 
b/tests/qtest/libqos/arm-virt-machine.c
index e0f5932284..a2cc1790b5 100644
--- a/tests/qtest/libqos/arm-virt-machine.c
+++ b/tests/qtest/libqos/arm-virt-machine.c
@@ -22,6 +22,8 @@
 #include "malloc.h"
 #include "qgraph.h"
 #include "virtio-mmio.h"
+#include "generic-pcihost.h"
+#include "hw/pci/pci_regs.h"
 
 #define ARM_PAGE_SIZE   4096
 #define VIRTIO_MMIO_BASE_ADDR   0x0A003E00
@@ -35,6 +37,7 @@ struct QVirtMachine {
 QOSGraphObject obj;
 QGuestAllocator alloc;
 QVirtioMMIODevice virtio_mmio;
+QGenericPCIHost bridge;
 };
 
 static void virt_destructor(QOSGraphObject *obj)
@@ -57,11 +60,13 @@ static void *virt_get_driver(void *object, const char 
*interface)
 static QOSGraphObject *virt_get_device(void *obj, const char *device)
 {
 QVirtMachine *machine = obj;
-if (!g_strcmp0(device, "virtio-mmio")) {
+if (!g_strcmp0(device, "generic-pcihost")) {
+return >bridge.obj;
+} else if (!g_strcmp0(device, "virtio-mmio")) {
 return >virtio_mmio.obj;
 }
 
-fprintf(stderr, "%s not present in arm/virtio\n", device);
+fprintf(stderr, "%s not present in arm/virt\n", device);
 g_assert_not_reached();
 }
 
@@ -76,16 +81,21 @@ static void *qos_create_machine_arm_virt(QTestState *qts)
 qvirtio_mmio_init_device(>virtio_mmio, qts, VIRTIO_MMIO_BASE_ADDR,
  VIRTIO_MMIO_SIZE);
 
+qos_create_generic_pcihost(>bridge, qts, >alloc);
+
 machine->obj.get_device = virt_get_device;
 machine->obj.get_driver = virt_get_driver;
 machine->obj.destructor = virt_destructor;
 return machine;
 }
 
-static void virtio_mmio_register_nodes(void)
+static void virt_machine_register_nodes(void)
 {
 qos_node_create_machine("arm/virt", qos_create_machine_arm_virt);
 qos_node_contains("arm/virt", "virtio-mmio", NULL);
+
+qos_node_create_machine("aarch64/virt", qos_create_machine_arm_virt);
+qos_node_contains("aarch64/virt", "generic-pcihost", NULL);
 }
 
-libqos_init(virtio_mmio_register_nodes);
+libqos_init(virt_machine_register_nodes);
diff --git a/tests/qtest/libqos/generic-pcihost.c 
b/tests/qtest/libqos/generic-pcihost.c
new file mode 100644
index 00..704bbc3473
--- /dev/null
+++ b/tests/qtest/libqos/generic-pcihost.c
@@ -0,0 +1,231 @@
+/*
+ * libqos PCI bindings for generic PCI
+ *
+ * Copyright Red Hat Inc., 2022
+ *
+ * Authors:
+ *  Eric Auger   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "generic-pcihost.h"
+#include "qapi/qmp/qdict.h"
+#include "hw/pci/pci_regs.h"
+
+#include "qemu/module.h"
+
+/* QGenericPCIHost */
+
+QOSGraphObject *generic_pcihost_get_device(void *obj, const char *device)
+{
+QGenericPCIHost *host = obj;
+if (!g_strcmp0(device, "pci-bus-generic")) {
+return >pci.obj;
+}
+fprintf(stderr, "%s not present in generic-pcihost\n", device);
+g_assert_not_reached();
+}
+
+void qos_create_generic_pcihost(QGenericPCIHost *host,
+QTestState *qts,
+QGuestAllocator *alloc)
+{
+host->obj.get_device = generic_pcihost_get_device;
+qpci_init_generic(>pci, qts, alloc, false);
+}
+
+static uint8_t qpci_generic_pio_readb(QPCIBus *bus, uint32_t addr)
+{
+QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+

[PATCH v2 2/6] tests/qtest/libqos/pci: Introduce pio_limit

2022-01-18 Thread Eric Auger
At the moment the IO space limit is hardcoded to
QPCI_PIO_LIMIT = 0x1. When accesses are performed to a bar,
the base address of this latter is compared against the limit
to decide whether we perform an IO or a memory access.

On ARM, we cannot keep this PIO limit as the arm-virt machine
uses [0x3eff, 0x3f00 ] for the IO space map and we
are mandated to allocate at 0x0.

Add a new flag in QPCIBar indicating whether it is an IO bar
or a memory bar. This flag is set on QPCIBar allocation and
provisionned based on the BAR configuration. Then the new flag
is used in access functions and in iomap() function.

Signed-off-by: Eric Auger 
Reviewed-by: Thomas Huth 
---
 tests/qtest/libqos/pci-pc.c|  1 +
 tests/qtest/libqos/pci-spapr.c |  1 +
 tests/qtest/libqos/pci.c   | 78 ++
 tests/qtest/libqos/pci.h   |  5 +--
 4 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/tests/qtest/libqos/pci-pc.c b/tests/qtest/libqos/pci-pc.c
index f97844289f..8051a0881a 100644
--- a/tests/qtest/libqos/pci-pc.c
+++ b/tests/qtest/libqos/pci-pc.c
@@ -150,6 +150,7 @@ void qpci_init_pc(QPCIBusPC *qpci, QTestState *qts, 
QGuestAllocator *alloc)
 
 qpci->bus.qts = qts;
 qpci->bus.pio_alloc_ptr = 0xc000;
+qpci->bus.pio_limit = 0x1;
 qpci->bus.mmio_alloc_ptr = 0xE000;
 qpci->bus.mmio_limit = 0x1ULL;
 
diff --git a/tests/qtest/libqos/pci-spapr.c b/tests/qtest/libqos/pci-spapr.c
index 262226985f..870ffdd8b5 100644
--- a/tests/qtest/libqos/pci-spapr.c
+++ b/tests/qtest/libqos/pci-spapr.c
@@ -197,6 +197,7 @@ void qpci_init_spapr(QPCIBusSPAPR *qpci, QTestState *qts,
 
 qpci->bus.qts = qts;
 qpci->bus.pio_alloc_ptr = 0xc000;
+qpci->bus.pio_limit = 0x1;
 qpci->bus.mmio_alloc_ptr = qpci->mmio32.pci_base;
 qpci->bus.mmio_limit = qpci->mmio32.pci_base + qpci->mmio32.size;
 
diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
index 3a9076ae58..b23d72346b 100644
--- a/tests/qtest/libqos/pci.c
+++ b/tests/qtest/libqos/pci.c
@@ -398,44 +398,56 @@ void qpci_config_writel(QPCIDevice *dev, uint8_t offset, 
uint32_t value)
 
 uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-return dev->bus->pio_readb(dev->bus, token.addr + off);
+QPCIBus *bus = dev->bus;
+
+if (token.is_io) {
+return bus->pio_readb(bus, token.addr + off);
 } else {
 uint8_t val;
-dev->bus->memread(dev->bus, token.addr + off, , sizeof(val));
+
+bus->memread(dev->bus, token.addr + off, , sizeof(val));
 return val;
 }
 }
 
 uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-return dev->bus->pio_readw(dev->bus, token.addr + off);
+QPCIBus *bus = dev->bus;
+
+if (token.is_io) {
+return bus->pio_readw(bus, token.addr + off);
 } else {
 uint16_t val;
-dev->bus->memread(dev->bus, token.addr + off, , sizeof(val));
+
+bus->memread(bus, token.addr + off, , sizeof(val));
 return le16_to_cpu(val);
 }
 }
 
 uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-return dev->bus->pio_readl(dev->bus, token.addr + off);
+QPCIBus *bus = dev->bus;
+
+if (token.is_io) {
+return bus->pio_readl(bus, token.addr + off);
 } else {
 uint32_t val;
-dev->bus->memread(dev->bus, token.addr + off, , sizeof(val));
+
+bus->memread(dev->bus, token.addr + off, , sizeof(val));
 return le32_to_cpu(val);
 }
 }
 
 uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-return dev->bus->pio_readq(dev->bus, token.addr + off);
+QPCIBus *bus = dev->bus;
+
+if (token.is_io) {
+return bus->pio_readq(bus, token.addr + off);
 } else {
 uint64_t val;
-dev->bus->memread(dev->bus, token.addr + off, , sizeof(val));
+
+bus->memread(bus, token.addr + off, , sizeof(val));
 return le64_to_cpu(val);
 }
 }
@@ -443,57 +455,65 @@ uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, 
uint64_t off)
 void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off,
 uint8_t value)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-dev->bus->pio_writeb(dev->bus, token.addr + off, value);
+QPCIBus *bus = dev->bus;
+
+if (token.is_io) {
+bus->pio_writeb(bus, token.addr + off, value);
 } else {
-dev->bus->memwrite(dev->bus, token.addr + off, , sizeof(value));
+bus->memwrite(bus, token.addr + off, , sizeof(value));
 }
 }
 
 void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off,
 uint16_t value)
 {
-if (token.addr < QPCI_PIO_LIMIT) {
-dev->bus->pio_writew(dev->bus, token.addr + off, value);
+QPCIBus *bus = dev->bus;
+
+if 

[PATCH v2 1/6] tests/qtest/vhost-user-test.c: Use vhostforce=on

2022-01-18 Thread Eric Auger
-netdev vhost-user,vhostforce is deprecated and vhostforce=on
should be used instead.

Signed-off-by: Eric Auger 
Reviewed-by: Thomas Huth 
---
 tests/qtest/vhost-user-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
index 3d6337fb5c..6e79935c47 100644
--- a/tests/qtest/vhost-user-test.c
+++ b/tests/qtest/vhost-user-test.c
@@ -42,7 +42,7 @@
 #define QEMU_CMD_MEMFD  " -m %d -object memory-backend-memfd,id=mem,size=%dM," 
\
 " -numa node,memdev=mem"
 #define QEMU_CMD_CHR" -chardev socket,id=%s,path=%s%s"
-#define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce"
+#define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce=on"
 
 #define HUGETLBFS_MAGIC   0x958458f6
 
-- 
2.26.3




[PATCH v2 0/6] qtests/libqos: Allow PCI tests to be run with virt-machine

2022-01-18 Thread Eric Auger
Up to now the virt-machine node only contains a virtio-mmio
driver node but no driver that eventually produces any pci-bus
interface.

Hence, PCI libqos tests cannot be run with aarch64 binary.

This series brings the pieces needed to be able to run PCI tests
with the aarch64 binary: a generic-pcihost driver node gets
instantiated by the machine. This later contains a pci-bus-generic
driver which produces a pci-bus interface. Then all tests
consuming the pci-bus interface can be run with the libqos arm
virt machine.

One of the first goal was to be able to run the virtio-iommu-pci
tests as the virtio-iommu was initially targetting ARM and it
was awkard to be run the test with the pc machine. This is now
possible.

Only the tests doing hotplug cannot be run yet as hotplug is
not possible on the root bus. This will be dealt with separately
by adding a root port to the object tree.

Best Regards

Eric

This series can be found at:
https://github.com/eauger/qemu/tree/libqos-pci-arm-v2

History

v1 -> v2:
- copyright updated to 2022
- QPCIBusARM renamed into QGenericPCIBus
- QGenericPCIHost declarations and definitions moved in the same
  place as the generic pci implementation
- rename pci-arm.c/h in generic-pcihost.c/h and remove any ref to
  ARM there
- remove qos_node_produces_opts, qpci_new_arm, qpci_free_arm
- ecam_alloc_ptr now is a field of QGenericPCIBus and not QPCIBus
- new libqos_init to create generic-pcihost driver that contains
  pci-bus-generic
- QGenericPCIHost moved in the same place as the generic pci
  bindings
- collected Thomas A-b/R-b


Eric Auger (6):
  tests/qtest/vhost-user-test.c: Use vhostforce=on
  tests/qtest/libqos/pci: Introduce pio_limit
  tests/qtest/libqos: Skip hotplug tests if pci root bus is not
hotpluggable
  tests/qtest/vhost-user-blk-test: Setup MSIx to avoid error on aarch64
  tests/qtest/vhost-user-blk-test: Factorize vq setup code
  tests/qtest/libqos: Add generic pci host bridge in arm-virt machine

 tests/qtest/e1000e-test.c |   6 +
 tests/qtest/libqos/arm-virt-machine.c |  18 +-
 tests/qtest/libqos/generic-pcihost.c  | 231 ++
 tests/qtest/libqos/generic-pcihost.h  |  54 ++
 tests/qtest/libqos/meson.build|   1 +
 tests/qtest/libqos/pci-pc.c   |   1 +
 tests/qtest/libqos/pci-spapr.c|   1 +
 tests/qtest/libqos/pci.c  |  78 +
 tests/qtest/libqos/pci.h  |   6 +-
 tests/qtest/vhost-user-blk-test.c |  39 -
 tests/qtest/vhost-user-test.c |   2 +-
 tests/qtest/virtio-blk-test.c |   5 +
 tests/qtest/virtio-net-test.c |   5 +
 tests/qtest/virtio-rng-test.c |   5 +
 14 files changed, 408 insertions(+), 44 deletions(-)
 create mode 100644 tests/qtest/libqos/generic-pcihost.c
 create mode 100644 tests/qtest/libqos/generic-pcihost.h

-- 
2.26.3




Re: [RESEND] target/riscv: Enable bitmanip Zicbo[m,z,p] instructions

2022-01-18 Thread Atish Patra
On Tue, Jan 18, 2022 at 8:48 AM Christoph Muellner  wrote:
>
> The RISC-V base cache management operation ISA extension has been
> ratified [1]. This patch adds support for the defined instructions
> and CSRs.
>
> [1] https://wiki.riscv.org/display/TECH/Recently+Ratified+Extensions
>
> Co-developed-by: Philipp Tomsich 
> Signed-off-by: Philipp Tomsich 
> Signed-off-by: Christoph Muellner 
> ---
>  target/riscv/cpu.c|  4 +
>  target/riscv/cpu.h|  9 +++
>  target/riscv/cpu_bits.h   | 10 +++
>  target/riscv/csr.c| 47 
>  target/riscv/helper.h |  5 ++
>  target/riscv/insn32.decode| 20 -
>  target/riscv/insn_trans/trans_zicbo.c.inc | 72 ++
>  target/riscv/op_helper.c  | 89 +++
>  target/riscv/translate.c  |  1 +
>  9 files changed, 256 insertions(+), 1 deletion(-)
>  create mode 100644 target/riscv/insn_trans/trans_zicbo.c.inc
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9bc25d3055..b4a87cfcdc 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -660,6 +660,10 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
>  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
>  DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
> +DEFINE_PROP_BOOL("Zicbom", RISCVCPU, cfg.ext_zicbom, false),
> +DEFINE_PROP_BOOL("Zicbop", RISCVCPU, cfg.ext_zicbop, false),
> +DEFINE_PROP_BOOL("Zicboz", RISCVCPU, cfg.ext_zicboz, false),
> +DEFINE_PROP_UINT16("cbolen", RISCVCPU, cfg.cbolen, 64),
>  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
>  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d63086765..acfe21cb75 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -263,6 +263,11 @@ struct CPURISCVState {
>  target_ulong spmbase;
>  target_ulong upmmask;
>  target_ulong upmbase;
> +
> +/* [mhs]envcfg CSRs */
> +target_ulong menvcfg;
> +target_ulong henvcfg;
> +target_ulong senvcfg;
>  #endif
>
>  float_status fp_status;
> @@ -329,6 +334,9 @@ struct RISCVCPU {
>  bool ext_icsr;
>  bool ext_zfh;
>  bool ext_zfhmin;
> +bool ext_zicbom;
> +bool ext_zicbop;
> +bool ext_zicboz;
>
>  char *priv_spec;
>  char *user_spec;
> @@ -336,6 +344,7 @@ struct RISCVCPU {
>  char *vext_spec;
>  uint16_t vlen;
>  uint16_t elen;
> +uint16_t cbolen;
>  bool mmu;
>  bool pmp;
>  bool epmp;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 5a6d49aa64..38c529b493 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -217,6 +217,11 @@
>  #define CSR_MTINST  0x34a
>  #define CSR_MTVAL2  0x34b
>
> +/* Environment configuration */
> +#define CSR_SENVCFG 0x10a
> +#define CSR_MENVCFG 0x30a
> +#define CSR_HENVCFG 0x60a
> +
>  /* Enhanced Physical Memory Protection (ePMP) */
>  #define CSR_MSECCFG 0x747
>  #define CSR_MSECCFGH0x757
> @@ -449,6 +454,11 @@ typedef enum {
>  #define COUNTEREN_IR (1 << 2)
>  #define COUNTEREN_HPM3   (1 << 3)
>
> +/* [msh]envcfg CSR bits */
> +#define ENVCFG_CBIE  (0b11 << 4)
> +#define ENVCFG_CBCFE (1 << 6)
> +#define ENVCFG_CBZE  (1 << 7)
> +
>  /* Privilege modes */
>  #define PRV_U 0
>  #define PRV_S 1
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index adb3d4381d..6693f695e4 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1478,6 +1478,48 @@ static RISCVException write_mtinst(CPURISCVState *env, 
> int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
> +   target_ulong *val)
> +{
> +*val = env->menvcfg;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
> +target_ulong val)
> +{
> +env->menvcfg = val;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
> +   target_ulong *val)
> +{
> +*val = env->henvcfg;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
> +target_ulong val)
> +{
> +env->henvcfg = val;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
> +   target_ulong *val)
> +{
> +*val = env->senvcfg;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
> +  

Re: [PATCH v4 20/23] multifd: Support for zero pages transmission

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> This patch adds counters and similar.  Logic will be added on the
> following patch.
> 
> Signed-off-by: Juan Quintela 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  migration/multifd.h| 13 -
>  migration/multifd.c| 22 +++---
>  migration/trace-events |  2 +-
>  3 files changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 4dda900a0b..4c6d29c954 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -49,7 +49,10 @@ typedef struct {
>  /* size of the next packet that contains pages */
>  uint32_t next_packet_size;
>  uint64_t packet_num;
> -uint64_t unused[4];/* Reserved for future use */
> +/* zero pages */
> +uint32_t zero_pages;
> +uint32_t unused32[1];/* Reserved for future use */
> +uint64_t unused64[3];/* Reserved for future use */
>  char ramblock[256];
>  uint64_t offset[];
>  } __attribute__((packed)) MultiFDPacket_t;
> @@ -117,6 +120,10 @@ typedef struct {
>  ram_addr_t *normal;
>  /* num of non zero pages */
>  uint32_t normal_num;
> +/* Pages that are  zero */
> +ram_addr_t *zero;
> +/* num of zero pages */
> +uint32_t zero_num;
>  /* used for compression methods */
>  void *data;
>  }  MultiFDSendParams;
> @@ -162,6 +169,10 @@ typedef struct {
>  ram_addr_t *normal;
>  /* num of non zero pages */
>  uint32_t normal_num;
> +/* Pages that are  zero */
> +ram_addr_t *zero;
> +/* num of zero pages */
> +uint32_t zero_num;
>  /* used for de-compression methods */
>  void *data;
>  } MultiFDRecvParams;
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 76b57a7177..cfa9f75d13 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -265,6 +265,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
>  packet->normal_pages = cpu_to_be32(p->normal_num);
>  packet->next_packet_size = cpu_to_be32(p->next_packet_size);
>  packet->packet_num = cpu_to_be64(p->packet_num);
> +packet->zero_pages = cpu_to_be32(p->zero_num);
>  
>  if (p->pages->block) {
>  strncpy(packet->ramblock, p->pages->block->idstr, 256);
> @@ -327,7 +328,15 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams 
> *p, Error **errp)
>  p->next_packet_size = be32_to_cpu(packet->next_packet_size);
>  p->packet_num = be64_to_cpu(packet->packet_num);
>  
> -if (p->normal_num == 0) {
> +p->zero_num = be32_to_cpu(packet->zero_pages);
> +if (p->zero_num > packet->pages_alloc - p->normal_num) {
> +error_setg(errp, "multifd: received packet "
> +   "with %u zero pages and expected maximum pages are %u",
> +   p->zero_num, packet->pages_alloc - p->normal_num) ;
> +return -1;
> +}
> +
> +if (p->normal_num == 0 && p->zero_num == 0) {
>  return 0;
>  }
>  
> @@ -553,6 +562,8 @@ void multifd_save_cleanup(void)
>  p->iov = NULL;
>  g_free(p->normal);
>  p->normal = NULL;
> +g_free(p->zero);
> +p->zero = NULL;
>  multifd_send_state->ops->send_cleanup(p, _err);
>  if (local_err) {
>  migrate_set_error(migrate_get_current(), local_err);
> @@ -641,6 +652,7 @@ static void *multifd_send_thread(void *opaque)
>  uint32_t flags = p->flags;
>  p->iovs_num = 1;
>  p->normal_num = 0;
> +p->zero_num = 0;
>  
>  for (int i = 0; i < p->pages->num; i++) {
>  p->normal[p->normal_num] = p->pages->offset[i];
> @@ -662,8 +674,8 @@ static void *multifd_send_thread(void *opaque)
>  p->pages->block = NULL;
>  qemu_mutex_unlock(>mutex);
>  
> -trace_multifd_send(p->id, packet_num, p->normal_num, flags,
> -   p->next_packet_size);
> +trace_multifd_send(p->id, packet_num, p->normal_num, p->zero_num,
> +   flags, p->next_packet_size);
>  
>  p->iov[0].iov_len = p->packet_len;
>  p->iov[0].iov_base = p->packet;
> @@ -913,6 +925,7 @@ int multifd_save_setup(Error **errp)
>  /* We need one extra place for the packet header */
>  p->iov = g_new0(struct iovec, page_count + 1);
>  p->normal = g_new0(ram_addr_t, page_count);
> +p->zero = g_new0(ram_addr_t, page_count);
>  socket_send_channel_create(multifd_new_send_channel_async, p);
>  }
>  
> @@ -1014,6 +1027,8 @@ int multifd_load_cleanup(Error **errp)
>  p->iov = NULL;
>  g_free(p->normal);
>  p->normal = NULL;
> +g_free(p->zero);
> +p->zero = NULL;
>  multifd_recv_state->ops->recv_cleanup(p);
>  }
>  qemu_sem_destroy(_recv_state->sem_sync);
> @@ -1153,6 +1168,7 @@ int multifd_load_setup(Error **errp)
>  p->name = 

Re: [PATCH v4 23/23] migration: Export ram_release_page()

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> Signed-off-by: Juan Quintela 

Erm, why?

Dave

> ---
>  migration/ram.h | 2 ++
>  migration/ram.c | 2 +-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/ram.h b/migration/ram.h
> index c515396a9a..6dca396a6b 100644
> --- a/migration/ram.h
> +++ b/migration/ram.h
> @@ -66,6 +66,8 @@ int ram_postcopy_incoming_init(MigrationIncomingState *mis);
>  
>  void ram_handle_compressed(void *host, uint8_t ch, uint64_t size);
>  
> +void ram_release_page(const char *rbname, uint64_t offset);
> +
>  int ramblock_recv_bitmap_test(RAMBlock *rb, void *host_addr);
>  bool ramblock_recv_bitmap_test_byte_offset(RAMBlock *rb, uint64_t 
> byte_offset);
>  void ramblock_recv_bitmap_set(RAMBlock *rb, void *host_addr);
> diff --git a/migration/ram.c b/migration/ram.c
> index bdc7cec4cd..5404431c71 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -1161,7 +1161,7 @@ static void migration_bitmap_sync_precopy(RAMState *rs)
>  }
>  }
>  
> -static void ram_release_page(const char *rbname, uint64_t offset)
> +void ram_release_page(const char *rbname, uint64_t offset)
>  {
>  if (!migrate_release_ram() || !migration_in_postcopy()) {
>  return;
> -- 
> 2.34.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v4 18/23] migration: Make ram_save_target_page() a pointer

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> We are going to create a new function for multifd latest in the series.
^^ 'later'



Reviewed-by: Dr. David Alan Gilbert 

> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/ram.c | 12 
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index e9dcd3ca4e..3536778e19 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -294,6 +294,9 @@ struct RAMSrcPageRequest {
>  QSIMPLEQ_ENTRY(RAMSrcPageRequest) next_req;
>  };
>  
> +typedef struct RAMState RAMState;
> +typedef struct PageSearchStatus PageSearchStatus;
> +
>  /* State of RAM for migration */
>  struct RAMState {
>  /* QEMUFile used for this migration */
> @@ -348,8 +351,8 @@ struct RAMState {
>  /* Queue of outstanding page requests from the destination */
>  QemuMutex src_page_req_mutex;
>  QSIMPLEQ_HEAD(, RAMSrcPageRequest) src_page_requests;
> +int (*ram_save_target_page)(RAMState *rs, PageSearchStatus *pss);
>  };
> -typedef struct RAMState RAMState;
>  
>  static RAMState *ram_state;
>  
> @@ -2117,14 +2120,14 @@ static bool save_compress_page(RAMState *rs, RAMBlock 
> *block, ram_addr_t offset)
>  }
>  
>  /**
> - * ram_save_target_page: save one target page
> + * ram_save_target_page_legacy: save one target page
>   *
>   * Returns the number of pages written
>   *
>   * @rs: current RAM state
>   * @pss: data about the page we want to send
>   */
> -static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss)
> +static int ram_save_target_page_legacy(RAMState *rs, PageSearchStatus *pss)
>  {
>  RAMBlock *block = pss->block;
>  ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
> @@ -2200,7 +2203,7 @@ static int ram_save_host_page(RAMState *rs, 
> PageSearchStatus *pss)
>  do {
>  /* Check the pages is dirty and if it is send it */
>  if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) {
> -tmppages = ram_save_target_page(rs, pss);
> +tmppages = rs->ram_save_target_page(rs, pss);
>  if (tmppages < 0) {
>  return tmppages;
>  }
> @@ -3008,6 +3011,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>  ram_control_before_iterate(f, RAM_CONTROL_SETUP);
>  ram_control_after_iterate(f, RAM_CONTROL_SETUP);
>  
> +(*rsp)->ram_save_target_page = ram_save_target_page_legacy;
>  multifd_send_sync_main(f);
>  qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
>  qemu_fflush(f);
> -- 
> 2.34.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v4 22/23] migration: Use multifd before we check for the zero page

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> So we use multifd to transmit zero pages.
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/ram.c | 32 +++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index 3536778e19..bdc7cec4cd 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -2168,6 +2168,32 @@ static int ram_save_target_page_legacy(RAMState *rs, 
> PageSearchStatus *pss)
>  return ram_save_page(rs, pss);
>  }
>  
> +/**
> + * ram_save_target_page_multifd: save one target page
> + *
> + * Returns the number of pages written
> + *
> + * @rs: current RAM state
> + * @pss: data about the page we want to send
> + */
> +static int ram_save_target_page_multifd(RAMState *rs, PageSearchStatus *pss)
> +{
> +RAMBlock *block = pss->block;
> +ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
> +int res;
> +
> +if (!migration_in_postcopy()) {
> +return ram_save_multifd_page(rs, block, offset);
> +}
> +
> +res = save_zero_page(rs, block, offset);

I'm confused; I think I was expecting to see in this patch, the one that
would check the parameter you added and do something different - where
did that go?

Note I think this is quite subtle that the difference here is really
just the ordering rather than adding a zero page test.

Dave

> +if (res > 0) {
> +return res;
> +}
> +
> +return ram_save_page(rs, pss);
> +}
> +
>  /**
>   * ram_save_host_page: save a whole host page
>   *
> @@ -3011,7 +3037,11 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>  ram_control_before_iterate(f, RAM_CONTROL_SETUP);
>  ram_control_after_iterate(f, RAM_CONTROL_SETUP);
>  
> -(*rsp)->ram_save_target_page = ram_save_target_page_legacy;
> +if (migrate_use_multifd()) {
> +(*rsp)->ram_save_target_page = ram_save_target_page_multifd;
> +} else {
> +(*rsp)->ram_save_target_page = ram_save_target_page_legacy;
> +}
>  multifd_send_sync_main(f);
>  qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
>  qemu_fflush(f);
> -- 
> 2.34.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v4 19/23] multifd: Add property to enable/disable zero_page

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> Signed-off-by: Juan Quintela 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  migration/migration.h |  3 +++
>  hw/core/machine.c |  4 +++-
>  migration/migration.c | 11 +++
>  3 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/migration.h b/migration/migration.h
> index 8130b703eb..638cd89b6c 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -296,6 +296,8 @@ struct MigrationState {
>   * This save hostname when out-going migration starts
>   */
>  char *hostname;
> +/* Use multifd channel to send zero pages */
> +bool multifd_zero_pages;
>  };
>  
>  void migrate_set_state(int *state, int old_state, int new_state);
> @@ -338,6 +340,7 @@ int migrate_multifd_channels(void);
>  MultiFDCompression migrate_multifd_compression(void);
>  int migrate_multifd_zlib_level(void);
>  int migrate_multifd_zstd_level(void);
> +bool migrate_use_multifd_zero_page(void);
>  
>  int migrate_use_xbzrle(void);
>  uint64_t migrate_xbzrle_cache_size(void);
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index debcdc0e70..fc303cb707 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -37,7 +37,9 @@
>  #include "hw/virtio/virtio.h"
>  #include "hw/virtio/virtio-pci.h"
>  
> -GlobalProperty hw_compat_6_2[] = {};
> +GlobalProperty hw_compat_6_2[] = {
> +{ "migration", "multifd-zero-page", "false" },
> +};
>  const size_t hw_compat_6_2_len = G_N_ELEMENTS(hw_compat_6_2);
>  
>  GlobalProperty hw_compat_6_1[] = {
> diff --git a/migration/migration.c b/migration/migration.c
> index 0652165610..ff39f07fc5 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -2502,6 +2502,15 @@ bool migrate_use_multifd(void)
>  return s->enabled_capabilities[MIGRATION_CAPABILITY_MULTIFD];
>  }
>  
> +bool migrate_use_multifd_zero_page(void)
> +{
> +MigrationState *s;
> +
> +s = migrate_get_current();
> +
> +return s->multifd_zero_pages;
> +}
> +
>  bool migrate_pause_before_switchover(void)
>  {
>  MigrationState *s;
> @@ -4158,6 +4167,8 @@ static Property migration_properties[] = {
>clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
>  
>  /* Migration parameters */
> +DEFINE_PROP_BOOL("multifd-zero-pages", MigrationState,
> +  multifd_zero_pages, true),
>  DEFINE_PROP_UINT8("x-compress-level", MigrationState,
>parameters.compress_level,
>DEFAULT_MIGRATE_COMPRESS_LEVEL),
> -- 
> 2.34.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v4 15/23] multifd: Use normal pages array on the recv side

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> Signed-off-by: Juan Quintela 

Reviewed-by: Dr. David Alan Gilbert 

> 
> ---
> 
> Rename num_normal_pages to total_normal_pages (peter)
> ---
>  migration/multifd.h  |  8 +--
>  migration/multifd-zlib.c |  8 +++
>  migration/multifd-zstd.c |  6 +++---
>  migration/multifd.c  | 45 ++--
>  4 files changed, 33 insertions(+), 34 deletions(-)
> 
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 7823199dbe..850889c5d8 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -151,12 +151,16 @@ typedef struct {
>  uint32_t next_packet_size;
>  /* packets sent through this channel */
>  uint64_t num_packets;
> -/* pages sent through this channel */
> -uint64_t num_pages;
> +/* non zero pages recv through this channel */
> +uint64_t total_normal_pages;
>  /* syncs main thread and channels */
>  QemuSemaphore sem_sync;
>  /* buffers to recv */
>  struct iovec *iov;
> +/* Pages that are not zero */
> +ram_addr_t *normal;
> +/* num of non zero pages */
> +uint32_t normal_num;
>  /* used for de-compression methods */
>  void *data;
>  } MultiFDRecvParams;
> diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c
> index 7f4fbef2c9..8239c840d3 100644
> --- a/migration/multifd-zlib.c
> +++ b/migration/multifd-zlib.c
> @@ -225,7 +225,7 @@ static int zlib_recv_pages(MultiFDRecvParams *p, Error 
> **errp)
>  uint32_t in_size = p->next_packet_size;
>  /* we measure the change of total_out */
>  uint32_t out_size = zs->total_out;
> -uint32_t expected_size = p->pages->num * qemu_target_page_size();
> +uint32_t expected_size = p->normal_num * page_size;
>  uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK;
>  int ret;
>  int i;
> @@ -244,16 +244,16 @@ static int zlib_recv_pages(MultiFDRecvParams *p, Error 
> **errp)
>  zs->avail_in = in_size;
>  zs->next_in = z->zbuff;
>  
> -for (i = 0; i < p->pages->num; i++) {
> +for (i = 0; i < p->normal_num; i++) {
>  int flush = Z_NO_FLUSH;
>  unsigned long start = zs->total_out;
>  
> -if (i == p->pages->num - 1) {
> +if (i == p->normal_num - 1) {
>  flush = Z_SYNC_FLUSH;
>  }
>  
>  zs->avail_out = page_size;
> -zs->next_out = p->pages->block->host + p->pages->offset[i];
> +zs->next_out = p->pages->block->host + p->normal[i];
>  
>  /*
>   * Welcome to inflate semantics
> diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c
> index 907d07805c..c5ed72ddcd 100644
> --- a/migration/multifd-zstd.c
> +++ b/migration/multifd-zstd.c
> @@ -242,7 +242,7 @@ static int zstd_recv_pages(MultiFDRecvParams *p, Error 
> **errp)
>  uint32_t in_size = p->next_packet_size;
>  uint32_t out_size = 0;
>  size_t page_size = qemu_target_page_size();
> -uint32_t expected_size = p->pages->num * page_size;
> +uint32_t expected_size = p->normal_num * page_size;
>  uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK;
>  struct zstd_data *z = p->data;
>  int ret;
> @@ -263,8 +263,8 @@ static int zstd_recv_pages(MultiFDRecvParams *p, Error 
> **errp)
>  z->in.size = in_size;
>  z->in.pos = 0;
>  
> -for (i = 0; i < p->pages->num; i++) {
> -z->out.dst = p->pages->block->host + p->pages->offset[i];
> +for (i = 0; i < p->normal_num; i++) {
> +z->out.dst = p->pages->block->host + p->normal[i];
>  z->out.size = page_size;
>  z->out.pos = 0;
>  
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 7b804928a2..e362b1bb89 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -146,11 +146,11 @@ static int nocomp_recv_pages(MultiFDRecvParams *p, 
> Error **errp)
> p->id, flags, MULTIFD_FLAG_NOCOMP);
>  return -1;
>  }
> -for (int i = 0; i < p->pages->num; i++) {
> -p->iov[i].iov_base = p->pages->block->host + p->pages->offset[i];
> +for (int i = 0; i < p->normal_num; i++) {
> +p->iov[i].iov_base = p->pages->block->host + p->normal[i];
>  p->iov[i].iov_len = page_size;
>  }
> -return qio_channel_readv_all(p->c, p->iov, p->pages->num, errp);
> +return qio_channel_readv_all(p->c, p->iov, p->normal_num, errp);
>  }
>  
>  static MultiFDMethods multifd_nocomp_ops = {
> @@ -282,7 +282,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams 
> *p, Error **errp)
>  {
>  MultiFDPacket_t *packet = p->packet;
>  size_t page_size = qemu_target_page_size();
> -uint32_t pages_max = MULTIFD_PACKET_SIZE / page_size;
> +uint32_t page_count = MULTIFD_PACKET_SIZE / page_size;
>  RAMBlock *block;
>  int i;
>  
> @@ -309,33 +309,25 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams 
> *p, Error **errp)
>   * If we received a packet that is 100 times bigger than 

Re: [PATCH v4 21/23] multifd: Zero pages transmission

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> This implements the zero page dection and handling.
> 
> Signed-off-by: Juan Quintela 
> 
> ---
> 
> Add comment for offset (dave)
> ---
>  migration/multifd.h |  4 
>  migration/multifd.c | 36 ++--
>  2 files changed, 38 insertions(+), 2 deletions(-)
> 
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 4c6d29c954..d014747122 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -54,6 +54,10 @@ typedef struct {
>  uint32_t unused32[1];/* Reserved for future use */
>  uint64_t unused64[3];/* Reserved for future use */
>  char ramblock[256];
> +/* This array contains the pointers to:
> +   - normal pages (initial normal_pages entries)
> +   - zero pages (following zero_pages entries)
> +*/
>  uint64_t offset[];
>  } __attribute__((packed)) MultiFDPacket_t;
>  
> diff --git a/migration/multifd.c b/migration/multifd.c
> index cfa9f75d13..ded13289e7 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -11,6 +11,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/cutils.h"
>  #include "qemu/rcu.h"
>  #include "exec/target_page.h"
>  #include "sysemu/sysemu.h"
> @@ -277,6 +278,12 @@ static void multifd_send_fill_packet(MultiFDSendParams 
> *p)
>  
>  packet->offset[i] = cpu_to_be64(temp);
>  }
> +for (i = 0; i < p->zero_num; i++) {
> +/* there are architectures where ram_addr_t is 32 bit */
> +uint64_t temp = p->zero[i];
> +
> +packet->offset[p->normal_num + i] = cpu_to_be64(temp);
> +}
>  }
>  
>  static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
> @@ -362,6 +369,18 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams 
> *p, Error **errp)
>  p->normal[i] = offset;
>  }
>  
> +for (i = 0; i < p->zero_num; i++) {
> +uint64_t offset = be64_to_cpu(packet->offset[p->normal_num + i]);
> +
> +if (offset > (block->used_length - page_size)) {
> +error_setg(errp, "multifd: offset too long %" PRIu64
> +   " (max " RAM_ADDR_FMT ")",
> +   offset, block->used_length);
> +return -1;
> +}
> +p->zero[i] = offset;
> +}
> +
>  return 0;
>  }
>  
> @@ -627,6 +646,8 @@ static void *multifd_send_thread(void *opaque)
>  {
>  MultiFDSendParams *p = opaque;
>  Error *local_err = NULL;
> +/* qemu older than 7.0 don't understand zero page on multifd channel */
> +bool use_zero_page = migrate_use_multifd_zero_page();
>  int ret = 0;
>  
>  trace_multifd_send_thread_start(p->id);
> @@ -655,8 +676,15 @@ static void *multifd_send_thread(void *opaque)
>  p->zero_num = 0;
>  
>  for (int i = 0; i < p->pages->num; i++) {
> -p->normal[p->normal_num] = p->pages->offset[i];
> -p->normal_num++;
> +if (use_zero_page &&
> +buffer_is_zero(p->pages->block->host + 
> p->pages->offset[i],
> +   qemu_target_page_size())) {
> +p->zero[p->zero_num] = p->pages->offset[i];
> +p->zero_num++;
> +} else {
> +p->normal[p->normal_num] = p->pages->offset[i];
> +p->normal_num++;
> +}
>  }
>  
>  if (p->normal_num) {
> @@ -1115,6 +1143,10 @@ static void *multifd_recv_thread(void *opaque)
>  }
>  }
>  
> +for (int i = 0; i < p->zero_num; i++) {
> +memset(p->host + p->zero[i], 0, qemu_target_page_size());
> +}
> +

On the existing code, it tries to avoid doing the memset if the target
page size matches; that avoids allocating the zero pages on the
destination host; should we try and do the same here?

Dave

>  if (flags & MULTIFD_FLAG_SYNC) {
>  qemu_sem_post(_recv_state->sem_sync);
>  qemu_sem_wait(>sem_sync);
> -- 
> 2.34.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PULL 00/19] Memory API patches for 2022-01-18

2022-01-18 Thread Peter Maydell
On Tue, 18 Jan 2022 at 12:18, Philippe Mathieu-Daudé via
 wrote:
>
> The following changes since commit 6621441db50d5bae7e34dbd04bf3c57a27a71b32:
>
>   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-20220115' 
> into staging (2022-01-16 20:12:23 +)
>
> are available in the Git repository at:
>
>   https://github.com/philmd/qemu.git tags/memory-api-20220118
>
> for you to fetch changes up to 9d696cd50442327fd71ec7309e7b0c6fee693b1d:
>
>   docs/devel: add some clarifying text for aliases (2022-01-18 12:56:29 +0100)
>
> 
> Memory API patches
>
> - Directly dispatch MemoryRegion alias accesses
> - Remove duplicated Address Space information in 'info mtree'
> - Cleanups around memory_region_is_mapped()
> - Fix incorrect calls of log_global_start/stop()
> - Use dma_addr_t type definition when relevant
> - Let dma_buf_read() / dma_buf_write() propagate MemTxResult
> - Clarify MemoryRegion aliases documentation
>


Applied, thanks.

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

-- PMM



[PATCH v2 13/14] target/ppc: 405: Program exception cleanup

2022-01-18 Thread Fabiano Rosas
The 405 Program Interrupt does not set SRR1 with any diagnostic bits,
just a clean copy of the MSR.

We're using the BookE Exception Syndrome Register which is different
from the 405.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 13674a102f..2efec6d13b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -484,30 +484,14 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 env->error_code = 0;
 return;
 }
-
-/*
- * FP exceptions always have NIP pointing to the faulting
- * instruction, so always use store_next and claim we are
- * precise in the MSR.
- */
-msr |= 0x0010;
-env->spr[SPR_BOOKE_ESR] = ESR_FP;
 break;
 case POWERPC_EXCP_INVAL:
 trace_ppc_excp_inval(env->nip);
-msr |= 0x0008;
-env->spr[SPR_BOOKE_ESR] = ESR_PIL;
 break;
 case POWERPC_EXCP_PRIV:
-msr |= 0x0004;
-env->spr[SPR_BOOKE_ESR] = ESR_PPR;
-break;
 case POWERPC_EXCP_TRAP:
-msr |= 0x0002;
-env->spr[SPR_BOOKE_ESR] = ESR_PTR;
 break;
 default:
-/* Should never occur */
 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
   env->error_code);
 break;
-- 
2.33.1




[PATCH v2 14/14] target/ppc: 405: Watchdog timer exception cleanup

2022-01-18 Thread Fabiano Rosas
Remove references to BookE.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2efec6d13b..a22b783ecb 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -396,7 +396,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
-int excp_model = env->excp_model;
 target_ulong msr, new_msr, vector;
 int srr0, srr1;
 
@@ -511,14 +510,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 break;
 case POWERPC_EXCP_WDT:   /* Watchdog timer interrupt */
 trace_ppc_excp_print("WDT");
-switch (excp_model) {
-case POWERPC_EXCP_BOOKE:
-srr0 = SPR_BOOKE_CSRR0;
-srr1 = SPR_BOOKE_CSRR1;
-break;
-default:
-break;
-}
 break;
 case POWERPC_EXCP_DTLB:  /* Data TLB error   */
 case POWERPC_EXCP_ITLB:  /* Instruction TLB error*/
-- 
2.33.1




Re: [PATCH v2 00/13] arm gicv3 ITS: Various bug fixes and refactorings

2022-01-18 Thread Peter Maydell
On Tue, 18 Jan 2022 at 17:42, Alex Bennée  wrote:
>
>
> Peter Maydell  writes:
>
> > I've been working on the ITS to add support for the GICv4 functionality.
> > In the course of that I found a handful of bugs in it and also some
> > places where the code benefited from refactoring to make it a better
> > base to put in the GICv4 parts. This patchset is just the bugfixes
> > and cleanups, because there are enough patches here that I figured it
> > made sense to send them out now rather than holding on to them.
> >
> > Most of these patches were in v1 and have been reviewed already.
>
> I've reviewed the patches and they look good to me. kvm-unit-tests is
> still failing some tests but the ones it fails hasn't changed from
> before this patch:
>
>   ✗  env QEMU=$HOME/lsrc/qemu.git/builds/arm.all/qemu-system-aarch64 
> ./run_tests.sh -g gic
>   PASS gicv2-ipi (3 tests)
>   PASS gicv2-mmio (17 tests, 1 skipped)
>   FAIL gicv2-mmio-up (17 tests, 2 unexpected failures)
>   FAIL gicv2-mmio-3p (17 tests, 3 unexpected failures)
>   PASS gicv3-ipi (3 tests)
>   PASS gicv2-active (1 tests)
>   PASS gicv3-active (1 tests)
>
> That said running with -d unimp,guest_errors there are some things that
> should probably be double checked, e.g.:

Almost all of the logging seems to be where the test code is
doing stuff that the GIC spec says isn't valid. Also, this
test is gicv2, which is unrelated to either the gicv3 code
or to the ITS...

>   /home/alex/lsrc/qemu.git/builds/arm.all/qemu-system-aarch64 -nodefaults 
> -machine virt -accel tcg -cpu cortex-a57 -device virtio-serial-device -device 
> virtconsole,chardev=
>   ctd -chardev testdev,id=ctd -device pci-testdev -display none -serial stdio 
> -kernel arm/gic.flat -machine gic-version=2 -smp 1 -append "mmio" -d 
> unimp,guest_errors
>   PASS: gicv2: mmio: all CPUs have interrupts
>   gic_dist_readb: Bad offset 8
>   gic_dist_readb: Bad offset 9
>   gic_dist_readb: Bad offset a
>   gic_dist_readb: Bad offset b

This is GICD_IIDR, which is a 32-bit register. The test looks like it's
trying to read it as 4 separate bytes, which is out of spec, and
is why our implementation is warning about it.

>   INFO: gicv2: mmio: IIDR: 0x
>   gic_dist_writeb: Bad offset 4
>   gic_dist_writeb: Bad offset 5
>   gic_dist_writeb: Bad offset 6
>   gic_dist_writeb: Bad offset 7
>   gic_dist_writeb: Bad offset 4
>   gic_dist_writeb: Bad offset 5
>   gic_dist_writeb: Bad offset 6
>   gic_dist_writeb: Bad offset 7
>   gic_dist_writeb: Bad offset 4
>   gic_dist_writeb: Bad offset 5
>   gic_dist_writeb: Bad offset 6
>   gic_dist_writeb: Bad offset 7

These complaints are because the test is trying to write
to GICD_TYPER, which is not permitted.

>   PASS: gicv2: mmio: GICD_TYPER is read-only
>   gic_dist_readb: Bad offset 8
>   gic_dist_readb: Bad offset 9
>   gic_dist_readb: Bad offset a
>   gic_dist_readb: Bad offset b

More attempts to do byte accesses to a word-only register.

>   gic_dist_writeb: Bad offset 8
>   gic_dist_writeb: Bad offset 9
>   gic_dist_writeb: Bad offset a
>   gic_dist_writeb: Bad offset b
>   gic_dist_readb: Bad offset 8
>   gic_dist_readb: Bad offset 9
>   gic_dist_readb: Bad offset a
>   gic_dist_readb: Bad offset b
>   gic_dist_writeb: Bad offset 8
>   gic_dist_writeb: Bad offset 9
>   gic_dist_writeb: Bad offset a
>   gic_dist_writeb: Bad offset b
>   gic_dist_readb: Bad offset 8
>   gic_dist_readb: Bad offset 9
>   gic_dist_readb: Bad offset a
>   gic_dist_readb: Bad offset b
>   PASS: gicv2: mmio: GICD_IIDR is read-only
>   gic_dist_writeb: Bad offset fe8
>   gic_dist_writeb: Bad offset fe9
>   gic_dist_writeb: Bad offset fea
>   gic_dist_writeb: Bad offset feb
>   gic_dist_writeb: Bad offset fe8
>   gic_dist_writeb: Bad offset fe9
>   gic_dist_writeb: Bad offset fea
>   gic_dist_writeb: Bad offset feb
>   gic_dist_writeb: Bad offset fe8
>   gic_dist_writeb: Bad offset fe9
>   gic_dist_writeb: Bad offset fea
>   gic_dist_writeb: Bad offset feb

Writing bytes to a register that is both read-only and also 32-bit only.

>   PASS: gicv2: mmio: ICPIDR2 is read-only
>   INFO: gicv2: mmio: value of ICPIDR2: 0x002b
>   PASS: gicv2: mmio: IPRIORITYR: consistent priority masking
>   INFO: gicv2: mmio: IPRIORITYR: priority mask is 0x
>   PASS: gicv2: mmio: IPRIORITYR: implements at least 4 priority bits
>   INFO: gicv2: mmio: IPRIORITYR: 8 priority bits implemented
>   PASS: gicv2: mmio: IPRIORITYR: clearing priorities
>   gic_dist_readb: Bad offset 520
>   gic_dist_readb: Bad offset 521
>   gic_dist_readb: Bad offset 522
>   gic_dist_readb: Bad offset 523
>   gic_dist_writeb: Bad offset 520
>   gic_dist_writeb: Bad offset 521
>   gic_dist_writeb: Bad offset 522
>   gic_dist_writeb: Bad offset 523
>   gic_dist_readb: Bad offset 520
>   gic_dist_readb: Bad offset 521
>   gic_dist_readb: Bad offset 522
>   gic_dist_readb: Bad offset 523
>   gic_dist_writeb: Bad offset 520
>   gic_dist_writeb: Bad offset 521
>   gic_dist_writeb: Bad offset 522
>   

[PATCH v2 11/14] target/ppc: 405: Data Storage exception cleanup

2022-01-18 Thread Fabiano Rosas
The 405 has no DSISR or DAR, so convert the trace entry to
trace_ppc_excp_print.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 84ec7e094a..e4e513322c 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -465,7 +465,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 srr1 = SPR_40x_SRR3;
 break;
 case POWERPC_EXCP_DSI:   /* Data storage exception   */
-trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
+trace_ppc_excp_print("DSI");
 break;
 case POWERPC_EXCP_ISI:   /* Instruction storage exception*/
 trace_ppc_excp_isi(msr, env->nip);
-- 
2.33.1




[PATCH v2 12/14] target/ppc: 405: Instruction storage interrupt cleanup

2022-01-18 Thread Fabiano Rosas
The 405 ISI does not set SRR1 with any exception syndrome bits, only a
clean copy of the MSR.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index e4e513322c..13674a102f 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -715,7 +715,6 @@ static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int 
excp)
 break;
 case POWERPC_EXCP_ISI:   /* Instruction storage exception*/
 trace_ppc_excp_isi(msr, env->nip);
-msr |= env->error_code;
 break;
 case POWERPC_EXCP_EXTERNAL:  /* External input   */
 {
-- 
2.33.1




[PATCH v2 07/14] target/ppc: 405: External exception cleanup

2022-01-18 Thread Fabiano Rosas
405 has no MSR_HV and EPR is BookE only so we can remove it all.

Signed-off-by: Fabiano Rosas 
Reviewed-by: David Gibson 
---
 target/ppc/excp_helper.c | 37 -
 1 file changed, 37 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index e98d783ecd..8fae8aa0be 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -472,44 +472,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 msr |= env->error_code;
 break;
 case POWERPC_EXCP_EXTERNAL:  /* External input   */
-{
-bool lpes0;
-
-cs = CPU(cpu);
-
-/*
- * Exception targeting modifiers
- *
- * LPES0 is supported on POWER7/8/9
- * LPES1 is not supported (old iSeries mode)
- *
- * On anything else, we behave as if LPES0 is 1
- * (externals don't alter MSR:HV)
- */
-#if defined(TARGET_PPC64)
-if (excp_model == POWERPC_EXCP_POWER7 ||
-excp_model == POWERPC_EXCP_POWER8 ||
-excp_model == POWERPC_EXCP_POWER9 ||
-excp_model == POWERPC_EXCP_POWER10) {
-lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
-} else
-#endif /* defined(TARGET_PPC64) */
-{
-lpes0 = true;
-}
-
-if (!lpes0) {
-new_msr |= (target_ulong)MSR_HVB;
-new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
-srr0 = SPR_HSRR0;
-srr1 = SPR_HSRR1;
-}
-if (env->mpic_proxy) {
-/* IACK the IRQ on delivery */
-env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
-}
 break;
-}
 case POWERPC_EXCP_ALIGN: /* Alignment exception  */
 /* Get rS/rD and rA from faulting opcode */
 /*
-- 
2.33.1




[PATCH v2 08/14] target/ppc: 405: System call exception cleanup

2022-01-18 Thread Fabiano Rosas
There's no sc 1.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 21 ++---
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 8fae8aa0be..9a6f8365d6 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -398,7 +398,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 CPUPPCState *env = >env;
 int excp_model = env->excp_model;
 target_ulong msr, new_msr, vector;
-int srr0, srr1, lev = -1;
+int srr0, srr1;
 
 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
@@ -521,30 +521,13 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 }
 break;
 case POWERPC_EXCP_SYSCALL:   /* System call exception*/
-lev = env->error_code;
-
-if ((lev == 1) && cpu->vhyp) {
-dump_hcall(env);
-} else {
-dump_syscall(env);
-}
+dump_syscall(env);
 
 /*
  * We need to correct the NIP which in this case is supposed
  * to point to the next instruction
  */
 env->nip += 4;
-
-/* "PAPR mode" built-in hypercall emulation */
-if ((lev == 1) && cpu->vhyp) {
-PPCVirtualHypervisorClass *vhc =
-PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
-vhc->hypercall(cpu->vhyp, cpu);
-return;
-}
-if (lev == 1) {
-new_msr |= (target_ulong)MSR_HVB;
-}
 break;
 case POWERPC_EXCP_FIT:   /* Fixed-interval timer interrupt   */
 trace_ppc_excp_print("FIT");
-- 
2.33.1




Cross Architecture Kernel Modules?

2022-01-18 Thread Kenneth Adam Miller
Hello all,

I just want to pose the following problem:

There is a kernel module for a non-native architecture, say, arch 1. For
performance reasons, the rest of all of the software needs to run natively
on a different arch, arch 2. Is there any way to perhaps run multiple QEMU
instances for the different architectures in such a way to minimize the
cross architecture performance penalty? For example, I would like the
kernel module in one (non-native) QEMU instance to be made available,
literally equivalently, in the second (native) QEMU instance. Would there
be any API or way to map across the QEMU instances so that the non native
arch kernel module could be mapped to the native QEMU instance?


[PATCH v2 00/14] target/ppc: powerpc_excp improvements [40x] (3/n)

2022-01-18 Thread Fabiano Rosas
changes from v1:

- New patch that renames MSR_POW to MSR_WE for the 405.

- New patch that adds just MSR_ME to the msr_mask.

- New patches to cleanup exceptions I missed the first time around.

- Dropped the patch that added all the missing MSR bits. We have an
  issue when two different MSR bits share the same number in different
  CPUs. Described in v1 here:

  https://lists.nongnu.org/archive/html/qemu-ppc/2022-01/msg00503.html

- Dropped the patch that adds missing exception vectors because Linux
  clearly cannot handle them. And I don't have access to real hardware
  to confirm some of the questions raised, so let's keep things as they
  are.

- Kept the split in two patches. One that copies powerpc_excp_legacy
  and other that does the changes.

Based on legoater/ppc-7.0

With only the fixes from the above branch, the ref405ep machine boots
until the shell. This series doesn't change that.

v1:
https://lists.nongnu.org/archive/html/qemu-ppc/2022-01/msg00300.html

Fabiano Rosas (14):
  target/ppc: 405: Rename MSR_POW to MSR_WE
  target/ppc: 405: Add missing MSR_ME bit
  target/ppc: Introduce powerpc_excp_40x
  target/ppc: Simplify powerpc_excp_40x
  target/ppc: 405: Critical exceptions cleanup
  target/ppc: 405: Machine check exception cleanup
  target/ppc: 405: External exception cleanup
  target/ppc: 405: System call exception cleanup
  target/ppc: 405: Alignment exception cleanup
  target/ppc: 405: Debug exception cleanup
  target/ppc: 405: Data Storage exception cleanup
  target/ppc: 405: Instruction storage interrupt cleanup
  target/ppc: 405: Program exception cleanup
  target/ppc: 405: Watchdog timer exception cleanup

 target/ppc/cpu.h |   1 +
 target/ppc/cpu_init.c|   3 +-
 target/ppc/excp_helper.c | 159 ++-
 3 files changed, 161 insertions(+), 2 deletions(-)

-- 
2.33.1




[PATCH v2 05/14] target/ppc: 405: Critical exceptions cleanup

2022-01-18 Thread Fabiano Rosas
In powerpc_excp_40x the Critical exception is now for 405 only, so we
can remove the BookE and G2 blocks.

Signed-off-by: Fabiano Rosas 
Reviewed-by: David Gibson 
---
 target/ppc/excp_helper.c | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index b5975dff3e..bddea702be 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -439,20 +439,8 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 
 switch (excp) {
 case POWERPC_EXCP_CRITICAL:/* Critical input */
-switch (excp_model) {
-case POWERPC_EXCP_40x:
-srr0 = SPR_40x_SRR2;
-srr1 = SPR_40x_SRR3;
-break;
-case POWERPC_EXCP_BOOKE:
-srr0 = SPR_BOOKE_CSRR0;
-srr1 = SPR_BOOKE_CSRR1;
-break;
-case POWERPC_EXCP_G2:
-break;
-default:
-goto excp_invalid;
-}
+srr0 = SPR_40x_SRR2;
+srr1 = SPR_40x_SRR3;
 break;
 case POWERPC_EXCP_MCHECK:/* Machine check exception  */
 if (msr_me == 0) {
@@ -652,7 +640,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 trace_ppc_excp_print("PIT");
 break;
 default:
-excp_invalid:
 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
 break;
 }
-- 
2.33.1




[PATCH v2 06/14] target/ppc: 405: Machine check exception cleanup

2022-01-18 Thread Fabiano Rosas
powerpc_excp_40x applies only to the 405, so remove HV code and
references to BookE.

Signed-off-by: Fabiano Rosas 
Reviewed-by: David Gibson 
---
 target/ppc/excp_helper.c | 26 ++
 1 file changed, 2 insertions(+), 24 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index bddea702be..e98d783ecd 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -457,34 +457,12 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 cs->halted = 1;
 cpu_interrupt_exittb(cs);
 }
-if (env->msr_mask & MSR_HVB) {
-/*
- * ISA specifies HV, but can be delivered to guest with HV
- * clear (e.g., see FWNMI in PAPR).
- */
-new_msr |= (target_ulong)MSR_HVB;
-}
 
 /* machine check exceptions don't have ME set */
 new_msr &= ~((target_ulong)1 << MSR_ME);
 
-/* XXX: should also have something loaded in DAR / DSISR */
-switch (excp_model) {
-case POWERPC_EXCP_40x:
-srr0 = SPR_40x_SRR2;
-srr1 = SPR_40x_SRR3;
-break;
-case POWERPC_EXCP_BOOKE:
-/* FIXME: choose one or the other based on CPU type */
-srr0 = SPR_BOOKE_MCSRR0;
-srr1 = SPR_BOOKE_MCSRR1;
-
-env->spr[SPR_BOOKE_CSRR0] = env->nip;
-env->spr[SPR_BOOKE_CSRR1] = msr;
-break;
-default:
-break;
-}
+srr0 = SPR_40x_SRR2;
+srr1 = SPR_40x_SRR3;
 break;
 case POWERPC_EXCP_DSI:   /* Data storage exception   */
 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
-- 
2.33.1




[PULL v2 00/31] testing/next and other misc fixes

2022-01-18 Thread Alex Bennée
The following changes since commit 6621441db50d5bae7e34dbd04bf3c57a27a71b32:

  Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-20220115' 
into staging (2022-01-16 20:12:23 +)

are available in the Git repository at:

  https://github.com/stsquad/qemu.git tags/pull-for-7.0-180122-2

for you to fetch changes up to 3265d1fc77eb5da522accb37e50053dfdfda7e8f:

  docker: include bison in debian-tricore-cross (2022-01-18 16:44:16 +)


Various testing and other misc updates:

  - fix compiler warnings with ui and sdl
  - update QXL/spice dependancy
  - skip I/O tests on Alpine
  - update fedora image to latest version
  - integrate lcitool and regenerate docker images
  - favour CONFIG_LINUX_USER over CONFIG_LINUX
  - add libfuse3 dependencies to docker images
  - add dtb-kaslr-seed control knob to virt machine
  - fix build breakage from HMP update
  - update docs for C standard and suffix usage
  - add more logging for debugging user hole finding
  - expand reserve for brk() for static 64 bit programs
  - fix bug with linux-user hole calculation
  - avoid affecting flags when printing results in float tests
  - add float reference files for ppc64
  - update FreeBSD to 12.3
  - add bison dependancy to tricore images


Alex Bennée (7):
  hw/arm: add control knob to disable kaslr_seed via DTB
  monitor: move x-query-profile into accel/tcg to fix build
  docs/devel: update C standard to C11
  docs/devel: more documentation on the use of suffixes
  linux-user: expand reserved brk space for 64bit guests
  linux-user/elfload: add extra logging for hole finding
  linux-user: don't adjust base of found hole

Brad Smith (1):
  FreeBSD: Upgrade to 12.3 release

Daniel P. Berrangé (17):
  ui: avoid compiler warnings from unused clipboard info variable
  meson: require liburing >= 0.3
  ui: avoid warnings about directdb on Alpine / musl libc
  ci: explicitly skip I/O tests on alpine
  tests/docker: switch fedora image to release 35
  tests: integrate lcitool for generating build env manifests
  tests/docker: auto-generate centos8.docker with lcitool
  tests/docker: auto-generate fedora.docker with lcitool
  tests/docker: auto-generate ubuntu1804.docker with lcitool
  tests/docker: auto-generate ubuntu2004.docker with lcitool
  tests/docker: auto-generate opensuse-leap.docker with lcitool
  tests/docker: remove ubuntu.docker container
  .gitlab-ci.d/cirrus: auto-generate variables with lcitool
  tests/docker: updates to alpine package list
  tests/docker: fix sorting of alpine image package lists
  tests/docker: fully expand the alpine package list
  tests/docker: auto-generate alpine.docker with lcitool

John Snow (1):
  spice: Update QXLInterface for spice >= 0.15.0

Paolo Bonzini (2):
  tests/tcg: use CONFIG_LINUX_USER, not CONFIG_LINUX
  docker: include bison in debian-tricore-cross

Richard Henderson (2):
  tests/tcg/multiarch: Read fp flags before printf
  test/tcg/ppc64le: Add float reference files

Stefan Hajnoczi (1):
  tests/docker: add libfuse3 development headers

 docs/devel/style.rst   |  14 +-
 docs/devel/testing.rst | 104 ++-
 docs/system/arm/virt.rst   |   8 +
 Makefile   |   2 +
 meson.build|   3 +-
 qapi/machine.json  |   1 +
 include/glib-compat.h  |   6 +-
 include/hw/arm/virt.h  |   1 +
 include/ui/qemu-spice.h|   6 +
 include/ui/sdl2.h  |  11 +
 accel/tcg/cpu-exec.c   |  31 +
 hw/arm/virt.c  |  32 +-
 hw/display/qxl.c   |  14 +-
 linux-user/elfload.c   |  35 +-
 monitor/qmp-cmds.c |  31 -
 tests/tcg/multiarch/float_convs.c  |   2 +-
 tests/tcg/multiarch/float_madds.c  |   2 +-
 ui/clipboard.c |   4 +-
 ui/spice-display.c |  11 +
 .gitlab-ci.d/buildtest.yml |   2 +-
 .gitlab-ci.d/cirrus.yml|   5 +-
 .gitlab-ci.d/cirrus/freebsd-12.vars|  11 +-
 .gitlab-ci.d/cirrus/freebsd-13.vars|  11 +-
 .gitlab-ci.d/cirrus/macos-11.vars  |  11 +-
 .gitlab-ci.d/containers.yml|   5 -
 .gitmodules|   3 +
 hmp-commands-info.hx   |   2 +
 tests/docker/dockerfiles/alpine.docker | 176 +++--
 

[PATCH v2 09/14] target/ppc: 405: Alignment exception cleanup

2022-01-18 Thread Fabiano Rosas
There is no DSISR in the 405. It uses DEAR which we already set
earlier at ppc_cpu_do_unaligned_access.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 9a6f8365d6..d263f20002 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -474,13 +474,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 case POWERPC_EXCP_EXTERNAL:  /* External input   */
 break;
 case POWERPC_EXCP_ALIGN: /* Alignment exception  */
-/* Get rS/rD and rA from faulting opcode */
-/*
- * Note: the opcode fields will not be set properly for a
- * direct store load/store, but nobody cares as nobody
- * actually uses direct store segments.
- */
-env->spr[SPR_DSISR] |= (env->error_code & 0x03FF) >> 16;
 break;
 case POWERPC_EXCP_PROGRAM:   /* Program exception*/
 switch (env->error_code & ~0xF) {
-- 
2.33.1




[PATCH v2 01/14] target/ppc: 405: Rename MSR_POW to MSR_WE

2022-01-18 Thread Fabiano Rosas
Bit 13 is the Wait State Enable bit. Give it its proper name.

As far as I can see we don't do anything with MSR_POW for the 405, so
this change has no effect.

Suggested-by: David Gibson 
Signed-off-by: Fabiano Rosas 
---
 target/ppc/cpu.h  | 1 +
 target/ppc/cpu_init.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2560b70c5f..66e13075c3 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -327,6 +327,7 @@ typedef enum {
 #define MSR_S22 /* Secure state  */
 #define MSR_KEY  19 /* key bit on 603e   */
 #define MSR_POW  18 /* Power management  */
+#define MSR_WE   18 /* Wait State Enable on 405  */
 #define MSR_TGPR 17 /* TGPR usage on 602/603x*/
 #define MSR_CE   17 /* Critical interrupt enable on embedded PowerPC x   */
 #define MSR_ILE  16 /* Interrupt little-endian mode  */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index e30e86fe9d..e63705b1c6 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2535,7 +2535,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
PPC_MEM_SYNC | PPC_MEM_EIEIO |
PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
-pcc->msr_mask = (1ull << MSR_POW) |
+pcc->msr_mask = (1ull << MSR_WE) |
 (1ull << MSR_CE) |
 (1ull << MSR_EE) |
 (1ull << MSR_PR) |
-- 
2.33.1




Re: [PATCH v4 14/23] multifd: Use normal pages array on the send side

2022-01-18 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> We are only sending normal pages through multifd channels.
> Later on this series, we are going to also send zero pages.
> We are going to dectect if a page is zero or non zero in the multifd
^ typo
> channel thread, not on the main thread.
> 
> So we receive an array of pages page->offset[N]
> 
> And we will end with:
> 
> p->normal[N - zero_pages]
> p->zero[zero_pages].
> 
> In this patch, we just copy all the pages in offset to normal.
> 
> for (i = 0; i < pages->num; i++) {
> p->narmal[p->normal_num] = pages->offset[i];
  ^
> p->normal_num++:
> }
> 
> Later in the series this becomes:
> 
> for (i = 0; i < pages->num; i++) {
> if (buffer_is_zero(page->offset[i])) {
> p->zerol[p->zero_num] = pages->offset[i];
 ^
> p->zero_num++:
> } else {
> p->narmal[p->normal_num] = pages->offset[i];
  ^
> p->normal_num++:
> }
> }
> 
> Signed-off-by: Juan Quintela 
> 

Other than typo's:

Reviewed-by: Dr. David Alan Gilbert 

> ---
> 
> Improving comment (dave)
> Renaming num_normal_pages to total_normal_pages (peter)
> ---
>  migration/multifd.h  |  8 ++--
>  migration/multifd-zlib.c |  6 +++---
>  migration/multifd-zstd.c |  6 +++---
>  migration/multifd.c  | 30 +++---
>  migration/trace-events   |  4 ++--
>  5 files changed, 33 insertions(+), 21 deletions(-)
> 
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 7496f951a7..7823199dbe 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -104,14 +104,18 @@ typedef struct {
>  /* thread local variables */
>  /* packets sent through this channel */
>  uint64_t num_packets;
> -/* pages sent through this channel */
> -uint64_t num_pages;
> +/* non zero pages sent through this channel */
> +uint64_t total_normal_pages;
>  /* syncs main thread and channels */
>  QemuSemaphore sem_sync;
>  /* buffers to send */
>  struct iovec *iov;
>  /* number of iovs used */
>  uint32_t iovs_num;
> +/* Pages that are not zero */
> +ram_addr_t *normal;
> +/* num of non zero pages */
> +uint32_t normal_num;
>  /* used for compression methods */
>  void *data;
>  }  MultiFDSendParams;
> diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c
> index ba90f1aaf4..7f4fbef2c9 100644
> --- a/migration/multifd-zlib.c
> +++ b/migration/multifd-zlib.c
> @@ -106,16 +106,16 @@ static int zlib_send_prepare(MultiFDSendParams *p, 
> Error **errp)
>  int ret;
>  uint32_t i;
>  
> -for (i = 0; i < p->pages->num; i++) {
> +for (i = 0; i < p->normal_num; i++) {
>  uint32_t available = z->zbuff_len - out_size;
>  int flush = Z_NO_FLUSH;
>  
> -if (i == p->pages->num - 1) {
> +if (i == p->normal_num - 1) {
>  flush = Z_SYNC_FLUSH;
>  }
>  
>  zs->avail_in = page_size;
> -zs->next_in = p->pages->block->host + p->pages->offset[i];
> +zs->next_in = p->pages->block->host + p->normal[i];
>  
>  zs->avail_out = available;
>  zs->next_out = z->zbuff + out_size;
> diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c
> index 757434d1ee..907d07805c 100644
> --- a/migration/multifd-zstd.c
> +++ b/migration/multifd-zstd.c
> @@ -121,13 +121,13 @@ static int zstd_send_prepare(MultiFDSendParams *p, 
> Error **errp)
>  z->out.size = z->zbuff_len;
>  z->out.pos = 0;
>  
> -for (i = 0; i < p->pages->num; i++) {
> +for (i = 0; i < p->normal_num; i++) {
>  ZSTD_EndDirective flush = ZSTD_e_continue;
>  
> -if (i == p->pages->num - 1) {
> +if (i == p->normal_num - 1) {
>  flush = ZSTD_e_flush;
>  }
> -z->in.src = p->pages->block->host + p->pages->offset[i];
> +z->in.src = p->pages->block->host + p->normal[i];
>  z->in.size = page_size;
>  z->in.pos = 0;
>  
> diff --git a/migration/multifd.c b/migration/multifd.c
> index e5b1fa5015..7b804928a2 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -89,13 +89,13 @@ static int nocomp_send_prepare(MultiFDSendParams *p, 
> Error **errp)
>  MultiFDPages_t *pages = p->pages;
>  size_t page_size = qemu_target_page_size();
>  
> -for (int i = 0; i < p->pages->num; i++) {
> -p->iov[p->iovs_num].iov_base = pages->block->host + pages->offset[i];
> +for (int i = 0; i < p->normal_num; i++) {
> +p->iov[p->iovs_num].iov_base = pages->block->host + p->normal[i];
>  p->iov[p->iovs_num].iov_len = page_size;
>  p->iovs_num++;
>  }
>  
> -p->next_packet_size = p->pages->num * page_size;
> +p->next_packet_size = p->normal_num * page_size;
>  p->flags |= MULTIFD_FLAG_NOCOMP;
>  return 0;
>  }
> @@ -262,7 +262,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
>  
>  packet->flags = 

[PATCH v2 10/14] target/ppc: 405: Debug exception cleanup

2022-01-18 Thread Fabiano Rosas
The current Debug exception dispatch is the BookE one, so it is
different from the 405. We effectively don't support the 405 Debug
exception.

This patch removes the BookE code and moves the DEBUG into the "not
implemented" block.

Note that there is in theory a functional change here since we now
abort when a Debug exception happens. However, given how it was never
implemented, I don't believe this to have ever been dispatched for the
405.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 18 --
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d263f20002..84ec7e094a 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -539,23 +539,13 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 case POWERPC_EXCP_DTLB:  /* Data TLB error   */
 case POWERPC_EXCP_ITLB:  /* Instruction TLB error*/
 break;
-case POWERPC_EXCP_DEBUG: /* Debug interrupt  */
-if (env->flags & POWERPC_FLAG_DE) {
-/* FIXME: choose one or the other based on CPU type */
-srr0 = SPR_BOOKE_DSRR0;
-srr1 = SPR_BOOKE_DSRR1;
-
-env->spr[SPR_BOOKE_CSRR0] = env->nip;
-env->spr[SPR_BOOKE_CSRR1] = msr;
-
-/* DBSR already modified by caller */
-} else {
-cpu_abort(cs, "Debug exception triggered on unsupported model\n");
-}
-break;
 case POWERPC_EXCP_PIT:   /* Programmable interval timer interrupt*/
 trace_ppc_excp_print("PIT");
 break;
+case POWERPC_EXCP_DEBUG: /* Debug interrupt  */
+cpu_abort(cs, "%s exception not implemented\n",
+  powerpc_excp_name(excp));
+break;
 default:
 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
 break;
-- 
2.33.1




[PATCH v2 02/14] target/ppc: 405: Add missing MSR_ME bit

2022-01-18 Thread Fabiano Rosas
The 405 MSR has the Machine Check Enable bit. We're making use of it
when dispatching Machine Check, so add the bit to the msr_mask.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/cpu_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index e63705b1c6..23a13036b2 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -2540,6 +2540,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
 (1ull << MSR_EE) |
 (1ull << MSR_PR) |
 (1ull << MSR_FP) |
+(1ull << MSR_ME) |
 (1ull << MSR_DWE) |
 (1ull << MSR_DE) |
 (1ull << MSR_IR) |
-- 
2.33.1




[PATCH v2 04/14] target/ppc: Simplify powerpc_excp_40x

2022-01-18 Thread Fabiano Rosas
Differences from the generic powerpc_excp code:

- Not BookE, so some MSR bits are cleared at interrupt dispatch;
- No MSR_HV or MSR_LE;
- No power saving states;
- No Hypervisor Emulation Assistance;
- Not 64 bits;
- No System call vectored;
- No Interrupts Little Endian;
- No Alternate Interrupt Location.

Exceptions used:

POWERPC_EXCP_ALIGN
POWERPC_EXCP_CRITICAL
POWERPC_EXCP_DEBUG
POWERPC_EXCP_DSI
POWERPC_EXCP_DTLB
POWERPC_EXCP_EXTERNAL
POWERPC_EXCP_FIT
POWERPC_EXCP_ISI
POWERPC_EXCP_ITLB
POWERPC_EXCP_MCHECK
POWERPC_EXCP_PIT
POWERPC_EXCP_PROGRAM
POWERPC_EXCP_SYSCALL
POWERPC_EXCP_WDT

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 205 ++-
 1 file changed, 10 insertions(+), 195 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 12ab5e1b34..b5975dff3e 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -409,54 +409,26 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
   excp, env->error_code);
 
 /* new srr1 value excluding must-be-zero bits */
-if (excp_model == POWERPC_EXCP_BOOKE) {
-msr = env->msr;
-} else {
-msr = env->msr & ~0x783fULL;
-}
+msr = env->msr & ~0x783fULL;
 
 /*
- * new interrupt handler msr preserves existing HV and ME unless
- * explicitly overriden
+ * new interrupt handler msr preserves existing ME unless
+ * explicitly overriden.
  */
-new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
+new_msr = env->msr & (((target_ulong)1 << MSR_ME));
 
 /* target registers */
 srr0 = SPR_SRR0;
 srr1 = SPR_SRR1;
 
-/*
- * check for special resume at 0x100 from doze/nap/sleep/winkle on
- * P7/P8/P9
- */
-if (env->resume_as_sreset) {
-excp = powerpc_reset_wakeup(cs, env, excp, );
-}
-
 /*
  * Hypervisor emulation assistance interrupt only exists on server
- * arch 2.05 server or later. We also don't want to generate it if
- * we don't have HVB in msr_mask (PAPR mode).
+ * arch 2.05 server or later.
  */
-if (excp == POWERPC_EXCP_HV_EMU
-#if defined(TARGET_PPC64)
-&& !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
-#endif /* defined(TARGET_PPC64) */
-
-) {
+if (excp == POWERPC_EXCP_HV_EMU) {
 excp = POWERPC_EXCP_PROGRAM;
 }
 
-#ifdef TARGET_PPC64
-/*
- * SPEU and VPU share the same IVOR but they exist in different
- * processors. SPEU is e500v1/2 only and VPU is e6500 only.
- */
-if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) {
-excp = POWERPC_EXCP_SPEU;
-}
-#endif
-
 vector = env->excp_vectors[excp];
 if (vector == (target_ulong)-1ULL) {
 cpu_abort(cs, "Raised an exception without defined vector %d\n",
@@ -645,24 +617,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 new_msr |= (target_ulong)MSR_HVB;
 }
 break;
-case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
-lev = env->error_code;
-dump_syscall(env);
-env->nip += 4;
-new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
-new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
-
-vector += lev * 0x20;
-
-env->lr = env->nip;
-env->ctr = msr;
-break;
-case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception */
-case POWERPC_EXCP_APU:   /* Auxiliary processor unavailable  */
-case POWERPC_EXCP_DECR:  /* Decrementer exception*/
-break;
 case POWERPC_EXCP_FIT:   /* Fixed-interval timer interrupt   */
-/* FIT on 4xx */
 trace_ppc_excp_print("FIT");
 break;
 case POWERPC_EXCP_WDT:   /* Watchdog timer interrupt */
@@ -693,119 +648,9 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
 cpu_abort(cs, "Debug exception triggered on unsupported model\n");
 }
 break;
-case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  
*/
-env->spr[SPR_BOOKE_ESR] = ESR_SPV;
-break;
-case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt  */
-break;
-case POWERPC_EXCP_DOORCI:/* Embedded doorbell critical interrupt */
-srr0 = SPR_BOOKE_CSRR0;
-srr1 = SPR_BOOKE_CSRR1;
-break;
-case POWERPC_EXCP_RESET: /* System reset exception   */
-/* A power-saving exception sets ME, otherwise it is unchanged */
-if (msr_pow) {
-/* indicate that we resumed from power save mode */
-msr |= 0x1;
-new_msr |= ((target_ulong)1 << MSR_ME);
-}
-if (env->msr_mask & MSR_HVB) {
-/*
- * ISA specifies HV, but can be delivered to guest with HV
- * clear (e.g., see FWNMI in PAPR, NMI 

[PATCH v2 03/14] target/ppc: Introduce powerpc_excp_40x

2022-01-18 Thread Fabiano Rosas
Introduce a new powerpc_excp function specific for 40x CPUs. This
commit copies powerpc_excp_legacy verbatim so the next one has a clean
diff.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 474 +++
 1 file changed, 474 insertions(+)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index bc646c67a0..12ab5e1b34 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -392,6 +392,477 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu,
 check_tlb_flush(env, false);
 }
 
+static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
+{
+CPUState *cs = CPU(cpu);
+CPUPPCState *env = >env;
+int excp_model = env->excp_model;
+target_ulong msr, new_msr, vector;
+int srr0, srr1, lev = -1;
+
+if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
+cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
+}
+
+qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
+  " => %s (%d) error=%02x\n", env->nip, 
powerpc_excp_name(excp),
+  excp, env->error_code);
+
+/* new srr1 value excluding must-be-zero bits */
+if (excp_model == POWERPC_EXCP_BOOKE) {
+msr = env->msr;
+} else {
+msr = env->msr & ~0x783fULL;
+}
+
+/*
+ * new interrupt handler msr preserves existing HV and ME unless
+ * explicitly overriden
+ */
+new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
+
+/* target registers */
+srr0 = SPR_SRR0;
+srr1 = SPR_SRR1;
+
+/*
+ * check for special resume at 0x100 from doze/nap/sleep/winkle on
+ * P7/P8/P9
+ */
+if (env->resume_as_sreset) {
+excp = powerpc_reset_wakeup(cs, env, excp, );
+}
+
+/*
+ * Hypervisor emulation assistance interrupt only exists on server
+ * arch 2.05 server or later. We also don't want to generate it if
+ * we don't have HVB in msr_mask (PAPR mode).
+ */
+if (excp == POWERPC_EXCP_HV_EMU
+#if defined(TARGET_PPC64)
+&& !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
+#endif /* defined(TARGET_PPC64) */
+
+) {
+excp = POWERPC_EXCP_PROGRAM;
+}
+
+#ifdef TARGET_PPC64
+/*
+ * SPEU and VPU share the same IVOR but they exist in different
+ * processors. SPEU is e500v1/2 only and VPU is e6500 only.
+ */
+if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) {
+excp = POWERPC_EXCP_SPEU;
+}
+#endif
+
+vector = env->excp_vectors[excp];
+if (vector == (target_ulong)-1ULL) {
+cpu_abort(cs, "Raised an exception without defined vector %d\n",
+  excp);
+}
+
+vector |= env->excp_prefix;
+
+switch (excp) {
+case POWERPC_EXCP_CRITICAL:/* Critical input */
+switch (excp_model) {
+case POWERPC_EXCP_40x:
+srr0 = SPR_40x_SRR2;
+srr1 = SPR_40x_SRR3;
+break;
+case POWERPC_EXCP_BOOKE:
+srr0 = SPR_BOOKE_CSRR0;
+srr1 = SPR_BOOKE_CSRR1;
+break;
+case POWERPC_EXCP_G2:
+break;
+default:
+goto excp_invalid;
+}
+break;
+case POWERPC_EXCP_MCHECK:/* Machine check exception  */
+if (msr_me == 0) {
+/*
+ * Machine check exception is not enabled.  Enter
+ * checkstop state.
+ */
+fprintf(stderr, "Machine check while not allowed. "
+"Entering checkstop state\n");
+if (qemu_log_separate()) {
+qemu_log("Machine check while not allowed. "
+"Entering checkstop state\n");
+}
+cs->halted = 1;
+cpu_interrupt_exittb(cs);
+}
+if (env->msr_mask & MSR_HVB) {
+/*
+ * ISA specifies HV, but can be delivered to guest with HV
+ * clear (e.g., see FWNMI in PAPR).
+ */
+new_msr |= (target_ulong)MSR_HVB;
+}
+
+/* machine check exceptions don't have ME set */
+new_msr &= ~((target_ulong)1 << MSR_ME);
+
+/* XXX: should also have something loaded in DAR / DSISR */
+switch (excp_model) {
+case POWERPC_EXCP_40x:
+srr0 = SPR_40x_SRR2;
+srr1 = SPR_40x_SRR3;
+break;
+case POWERPC_EXCP_BOOKE:
+/* FIXME: choose one or the other based on CPU type */
+srr0 = SPR_BOOKE_MCSRR0;
+srr1 = SPR_BOOKE_MCSRR1;
+
+env->spr[SPR_BOOKE_CSRR0] = env->nip;
+env->spr[SPR_BOOKE_CSRR1] = msr;
+break;
+default:
+break;
+}
+break;
+case POWERPC_EXCP_DSI:   /* Data storage exception   */
+trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
+break;
+case 

Re: [PATCH v3 09/19] block: introduce FleecingState class

2022-01-18 Thread Vladimir Sementsov-Ogievskiy

18.01.2022 19:37, Hanna Reitz wrote:

On 22.12.21 18:40, Vladimir Sementsov-Ogievskiy wrote:

FleecingState represents state shared between copy-before-write filter
and upcoming fleecing block driver.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block/fleecing.h  | 135 ++
  block/fleecing.c  | 182 ++
  MAINTAINERS   |   2 +
  block/meson.build |   1 +
  4 files changed, 320 insertions(+)
  create mode 100644 block/fleecing.h
  create mode 100644 block/fleecing.c

diff --git a/block/fleecing.h b/block/fleecing.h
new file mode 100644
index 00..fb7b2f86c4
--- /dev/null
+++ b/block/fleecing.h
@@ -0,0 +1,135 @@
+/*
+ * FleecingState
+ *
+ * The common state of image fleecing, shared between copy-before-write filter
+ * and fleecing block driver.


 From this documentation, it’s unclear to me who owns the FleecingState object. 
 I would have assumed it’s the fleecing node, and if it is, I wonder why we 
even have this external interface instead of considering FleecingState a helper 
object for the fleecing block driver (or rather the block driver’s opaque 
state, which it basically is, as far as I can see from peeking into the next 
patch), and putting both into a single file with no external interface except 
for fleecing_mark_done_and_wait_readers().


FleecingState object is owned by copy-before-write node. copy-before-write has 
the whole information, and it owns BlockCopyState object, which is used to 
create FleecingState. copy-before-write node can easily detect that its target 
is fleecing filter, and initialize FleecingState in this case.

On the other hand, if we want to create FleecingState from fleecing filter (or 
even merge the state into its driver state), we'll have to search through 
parents to find copy-before-write, which may be not trivial. Moreover, at time 
of open() we may have no parents yet.


Hmm, but may be just pass bcs to fleecing-node by activate(), like we are going 
to do with fleecing state?  I'll give it a try.




+ *
+ * Copyright (c) 2021 Virtuozzo International GmbH.
+ *
+ * Author:
+ *  Sementsov-Ogievskiy Vladimir 
+ *
+ * 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 .
+ *
+ *
+ * Fleecing scheme looks as follows:
+ *
+ * [guest blk]   [nbd export]
+ *    |  |
+ *    |root  |
+ *    v  v
+ * [copy-before-write]--target-->[fleecing drv]
+ *    |  /   |
+ *    |file /    |file
+ *    v    / v
+ * [active disk]<--source-/  [temp disk]
+ *
+ * Note that "active disk" is also called just "source" and "temp disk" is also
+ * called "target".
+ *
+ * What happens here:
+ *
+ * copy-before-write filter performs copy-before-write operations: on guest
+ * write we should copy old data to target child before rewriting. Note that we
+ * write this data through fleecing driver: it saves a possibility to implement
+ * a kind of cache in fleecing driver in future.


I don’t understand why this explanation is the first one given (and the only 
one given explicitly as a reason) for why we want a fleecing block driver.


Actually, benefits are given in the next commit message.



(1) If we implement caching later, I have a feeling that we’ll want new options 
for this.  So a management layer that wants caching will need to be updated at 
that point anyway (to specify these new options), so I don’t understand how 
adding a fleecing block driver now would make it easier later on to introduce 
caching.

(1b) It’s actually entirely possible that we will not want to use the fleecing 
driver for caching, because we decide that caching is much more useful as its 
own dedicated block driver.

(2) There are much better arguments below.  This FleecingState you introduce 
here makes it clear why we need a fleecing block driver; it helps with 
synchronization, and it provides the “I’m done with this bit, I don’t care 
about it anymore” discard interface.


+ *
+ * Fleecing user is nbd export: it can read from fleecing node, which 
guarantees
+ * a snapshot-view for fleecing user. Fleecing user may also do discard
+ * operations.
+ *
+ * FleecingState is responsible for most of the fleecing logic:
+ *
+ * 1. Fleecing read. Handle reads of fleecing 

Re: iotest 040, 041, intermittent failure in netbsd VM

2022-01-18 Thread John Snow
On Tue, Jan 18, 2022 at 7:13 AM Peter Maydell  wrote:
>
> On Mon, 17 Jan 2022 at 20:35, John Snow  wrote:
> > I do expect this to print more information on failure than it
> > currently is, though (bug somewhere in machine.py, I think).
> > Can you please try applying this temporary patch and running `./check
> > -qcow2 040 041` until you see a breakage and show me the output from
> > that?
>

Thanks for playing tele-debug.

> Having fixed my setup to not use an ancient host QEMU, here's
> the relevant bit of the log:
>
>   TEST   iotest-qcow2: 037
>   TEST   iotest-qcow2: 038 [not run]
>   TEST   iotest-qcow2: 039 [not run]
>   TEST   iotest-qcow2: 040 [fail]
> QEMU  --
> "/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/../../qemu-system-aarch64"
> -nodefaults -display none -accel qtest -machine virt
> QEMU_IMG  --
> "/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/../../qemu-img"
> QEMU_IO   --
> "/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/../../qemu-io"
> --cache writeback --aio threads -f qcow2
> QEMU_NBD  --
> "/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/../../qemu-nbd"
> IMGFMT-- qcow2
> IMGPROTO  -- file
> PLATFORM  -- NetBSD/amd64 localhost 9.2
> TEST_DIR  -- /home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/scratch
> SOCK_DIR  -- /tmp/tmp1h12r7ev
> GDB_OPTIONS   --
> VALGRIND_QEMU --
> PRINT_QEMU_OUTPUT --
>
> --- /home/qemu/qemu-test.vdrI02/src/tests/qemu-iotests/040.out
> +++ 040.out.bad
> @@ -1,5 +1,95 @@
> -.
> +...ERROR:qemu.aqmp.qmp_client.qemu-12407:Failed to establish
> connection: concurrent.futures._base.CancelledError
> +ERROR:qemu.machine.machine:Error launching VM
> +ERROR:qemu.machine.machine:Process was forked, waiting on it
> +ERROR:qemu.machine.machine:Command:
> '/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/../../qemu-system-aarch64
> -display none -vga none -chardev
> socket,id=mon,path=/tmp/tmp1h12r7ev/qemu-12407-monitor.sock -mon
> chardev=mon,mode=control -qtest
> unix:path=/tmp/tmp1h12r7ev/qemu-12407-qtest.sock -accel qtest
> -nodefaults -display none -accel qtest -machine virt -drive
> if=none,id=drive0,file=/home/qemu/qemu-test.vdrI02/build/tests/qemu-iotests/scratch/test.img,format=qcow2,cache=writeback,aio=threads,node-name=top,backing.node-name=mid,backing.backing.node-name=base
> -device virtio-scsi -device scsi-hd,id=scsi0,drive=drive0'

> +ERROR:qemu.machine.machine:Output: "qemu-system-aarch64: -chardev
> socket,id=mon,path=/tmp/tmp1h12r7ev/qemu-12407-monitor.sock: Failed to
> connect to '/tmp/tmp1h12r7ev/qemu-12407-monitor.sock': No such file or
> directory\n"

... Oh. That's unpleasant. My guess is that we aren't listening on the
socket before the QEMU process gets far enough to want to connect to
it. The change to an asynchronous backend must have jostled the
timing.

> +ERROR:qemu.machine.machine:exitcode: 1

And, oh: The VM launching library only chirps about *negative* error
codes. That's why it wasn't printing anything more useful. I suppose
the thinking was that we use the VM launch utility to knowingly launch
bad command lines, so we only wanted to see failure notifications on
-errno style codes, but that obviously makes debugging unintentional
failures a lot more awful. I'll try to improve the usability and
legibility of the errors here.

Thanks,
--js




  1   2   3   4   >