Re: [Qemu-devel] [PATCH v5 00/30] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine

2019-08-23 Thread Bin Meng
Hi Alistair,

On Sat, Aug 24, 2019 at 1:29 AM Alistair Francis  wrote:
>
> On Thu, Aug 22, 2019 at 10:15 PM Bin Meng  wrote:
> >
> > As of today, the QEMU 'sifive_u' machine is a special target that does
> > not boot the upstream OpenSBI/U-Boot firmware images built for the real
> > SiFive HiFive Unleashed board. Hence OpenSBI supports a special platform
> > "qemu/sifive_u". For U-Boot, the sifive_fu540_defconfig is referenced
> > in the OpenSBI doc as its payload, but that does not boot at all due
> > to various issues in current QEMU 'sifive_u' machine codes.
> >
> > This series aims to improve the emulation fidelity of sifive_u machine,
> > so that the upstream OpenSBI, U-Boot and kernel images built for the
> > SiFive HiFive Unleashed board can be used out of the box without any
> > special hack.
> >
> > The major changes include:
> > - Heterogeneous harts creation supported, so that we can create a CPU
> >   that exactly mirrors the real hardware: 1 E51 + 4 U54.
> > - Implemented a PRCI model for FU540
> > - Implemented an OTP model for FU540, primarily used for storing serial
> >   number of the board
> > - Fixed GEM support that was seriously broken on sifive_u
> > - Synced device tree with upstream Linux kernel on sifive_u
> >
> > OpenSBI v0.4 image built for sifive/fu540 is included as the default
> > bios image for 'sifive_u' machine.
> >
> > The series is tested against OpenSBI v0.4 image for sifive/fu540
> > paltform, U-Boot v2019.10-rc1 image for sifive_fu540_defconfig,
> > and Linux kernel v5.3-rc3 image with the following patch:
> >
> > macb: Update compatibility string for SiFive FU540-C000 [1]
> >
> > OpenSBI + U-Boot, ping/tftpboot with U-Boot MACB driver works well.
> > Boot Linux 64-bit defconfig image, verified that system console on
> > the serial 0 and ping host work pretty well.
> >
> > An OpenSBI patch [2] was sent to drop the special "qemu/sifive_u" platform
> > support in OpenSBI. The original plan was to get the drop patch applied
> > after this QEMU series is merged. However after discussion in the OpenSBI
> > mailing list, it seems the best option for us is to let OpenSBI continue
> > shipping the special "qemu/sifive_u" platform support to work with QEMU
> > version <= 4.1 and deprecate the support sometime in the future. A patch
> > will need to be sent to OpenSBI mailing list to update its document.
> >
> > v4 is now rebased on Palmer's QEMU RISC-V repo "for-master" branch.
> > Dropped the following v3 patch that was already done by someone else.
> > - riscv: sifive_u: Generate an aliases node in the device tree
> > - riscv: sifive_u: Support loading initramfs
> >
> > The following v3 patch was dropped too due to a different cluster approach
> > suggested by Richard Henderson is used in v4:
> > - riscv: hart: Support heterogeneous harts population
> >
> > [1]: https://patchwork.kernel.org/patch/11050003/
> > [2]: http://lists.infradead.org/pipermail/opensbi/2019-August/000335.html
> >
> > Changes in v5:
> > - new patch to change to use qemu_log_mask(LOG_GUEST_ERROR,...) instead
> >   in various sifive models
> > - new patch to remove the unnecessary include of target/riscv/cpu.h
> > - change to use defines instead of enums
> > - change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci
> > - creating a 32-bit val variable and using that instead of casting
> >   everywhere in sifive_u_prci_write()
> > - move all register initialization to sifive_u_prci_reset() function
> > - drop sifive_u_prci_create()
> > - s/codes that worked/code that works/g
> > - create sifive_u_prci block directly in the machine codes, instead
> >   of calling sifive_u_prci_create()
> > - change to use defines instead of enums
> > - change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_otp
> > - creating a 32-bit val variable and using that instead of casting
> >   everywhere in sifive_u_otp_write()
> > - move all register initialization to sifive_u_otp_reset() function
> > - drop sifive_u_otp_create()
> > - create sifive_u_otp block directly in the machine codes, instead
> >   of calling sifive_u_otp_create()
> > - add the missing "local-mac-address" property in the ethernet node
> >
> > Changes in v4:
> > - remove 2 more "linux,phandle" instances in sifive_u.c and spike.c
> >   after rebasing on Palmer's QEMU RISC-V tree
> > - change create_fdt() to return void in sifive_u.c too, after rebasing
> >   on Palmer's QEMU RISC-V tree
> > - new patch to remove executable attribute of opensbi images
> > - prefix all macros/variables/functions with SIFIVE_E/sifive_e
> >   in the sifive_e_prci driver
> > - new patch to add a "hartid-base" property to RISC-V hart array
> > - changed to create clusters for each cpu type
> > - prefix all macros/variables/functions with SIFIVE_U/sifive_u
> >   in the sifive_u_prci driver
> > - prefix all macros/variables/functions with SIFIVE_U/sifive_u
> >   in the sifive_u_otp driver
> > - new patch to remove handcrafted clock nodes for UART and ethernet
> >
> > 

Re: [Qemu-devel] [edk2-rfc] [edk2-devel] CPU hotplug using SMM with QEMU+OVMF

2019-08-23 Thread Yao, Jiewen
I give my thought.
Paolo may add more.

> -Original Message-
> From: Kinney, Michael D
> Sent: Friday, August 23, 2019 11:25 PM
> To: Yao, Jiewen ; Paolo Bonzini
> ; Laszlo Ersek ;
> r...@edk2.groups.io; Kinney, Michael D 
> Cc: Alex Williamson ; de...@edk2.groups.io;
> qemu devel list ; Igor Mammedov
> ; Chen, Yingwen ;
> Nakajima, Jun ; Boris Ostrovsky
> ; Joao Marcal Lemos Martins
> ; Phillip Goerl 
> Subject: RE: [edk2-rfc] [edk2-devel] CPU hotplug using SMM with
> QEMU+OVMF
> 
> Hi Jiewen,
> 
> If a hot add CPU needs to run any code before the
> first SMI, I would recommend is only executes code
> from a write protected FLASH range without a stack
> and then wait for the first SMI.
[Jiewen] Right.

Another option from Paolo, the new CPU will not run until 0x7b.
To mitigate DMA threat, someone need guarantee the low memory SIPI vector is 
DMA protected.

NOTE: The LOW memory *could* be mapped to write protected FLASH AREA via PAM 
register. The Host CPU may setup that in SMM.
If that is the case, we don’t need worry DMA.

I copied the detail step here, because I found it is hard to dig them out again.

(01a) QEMU: create new CPU.  The CPU already exists, but it does not
 start running code until unparked by the CPU hotplug controller.

(01b) QEMU: trigger SCI

(02-03) no equivalent

(04) Host CPU: (OS) execute GPE handler from DSDT

(05) Host CPU: (OS) Port 0xB2 write, all CPUs enter SMM (NOTE: New CPU
 will not enter CPU because SMI is disabled)

(06) Host CPU: (SMM) Save 38000, Update 38000 -- fill simple SMM
 rebase code.

(07a) Host CPU: (SMM) Write to CPU hotplug controller to enable
 new CPU

(07b) Host CPU: (SMM) Send INIT/SIPI/SIPI to new CPU.

(08a) New CPU: (Low RAM) Enter protected mode.

(08b) New CPU: (Flash) Signals host CPU to proceed and enter cli;hlt loop.

(09) Host CPU: (SMM) Send SMI to the new CPU only.

(10) New CPU: (SMM) Run SMM code at 38000, and rebase SMBASE to
 TSEG.

(11) Host CPU: (SMM) Restore 38000.

(12) Host CPU: (SMM) Update located data structure to add the new CPU
 information. (This step will involve CPU_SERVICE protocol)

(13) New CPU: (Flash) do whatever other initialization is needed

(14) New CPU: (Flash) Deadloop, and wait for INIT-SIPI-SIPI.

(15) Host CPU: (OS) Send INIT-SIPI-SIPI to pull new CPU in..


> 
> For this OVMF use case, is any CPU init required
> before the first SMI?
[Jiewen] I am sure what is the detail action in 08b.
And I am not sure what your "init" means here?
Personally, I don’t think we need too much init work, such as Microcode or MTRR.
But we need detail info.



> From Paolo's list of steps are steps (8a) and (8b)
> really required?  Can the SMI monarch use the Local
> APIC to send a directed SMI to the hot added CPU?
> The SMI monarch needs to know the APIC ID of the
> hot added CPU.  
[Jiewen] I think it depend upon virtual hardware design.
Leave question to Paolo.



Do we also need to handle the case
> where multiple CPUs are added at once?  I think we
> would need to serialize the use of 3000:8000 for the
> SMM rebase operation on each hot added CPU.
> It would be simpler if we can guarantee that only
> one CPU can be added or removed at a time and the
> complete flow of adding a CPU to SMM and the OS
> needs to be completed before another add/remove
> event needs to be processed.
[Jiewen] Right.
I treat the multiple CPU hot-add at same time as a potential threat.
We don’t want to trust end user.
The solution could be:
1) Let trusted hardware guarantee hot-add one by one.
2) Let trusted software (SMM and init code) guarantee SMREBASE one by one 
(include any code runs before SMREBASE)
3) Let trusted software (SMM and init code) support SMREBASE simultaneously 
(include any code runs before SMREBASE).
Solution #1 or #2 are simple solution.


> Mike
> 
> > -Original Message-
> > From: Yao, Jiewen
> > Sent: Thursday, August 22, 2019 10:00 PM
> > To: Kinney, Michael D ;
> > Paolo Bonzini ; Laszlo Ersek
> > ; r...@edk2.groups.io
> > Cc: Alex Williamson ;
> > de...@edk2.groups.io; qemu devel list  > de...@nongnu.org>; Igor Mammedov ;
> > Chen, Yingwen ; Nakajima, Jun
> > ; Boris Ostrovsky
> > ; Joao Marcal Lemos Martins
> > ; Phillip Goerl
> > 
> > Subject: RE: [edk2-rfc] [edk2-devel] CPU hotplug using
> > SMM with QEMU+OVMF
> >
> > Thank you Mike!
> >
> > That is good reference on the real hardware behavior.
> > (Glad it is public.)
> >
> > For threat model, the unique part in virtual environment
> > is temp RAM.
> > The temp RAM in real platform is per CPU cache, while
> > the temp RAM in virtual platform is global memory.
> > That brings one more potential attack surface in virtual
> > environment, if hot-added CPU need run code with stack
> > or heap before SMI rebase.
> >
> > Other threats, such as SMRAM or DMA, are same.
> >
> > Thank you
> > Yao Jiewen
> >
> >
> > > -Original Message-
> > > From: Kinney, Michael D
> > > Sent: Friday, August 

Re: [Qemu-devel] [PATCH v3] RISC-V: Select FPU gdb xml file based on the supported extensions

2019-08-23 Thread Alistair Francis
On Wed, Aug 21, 2019 at 9:36 AM Georg Kotheimer
 wrote:
>
> The size of the FPU registers depends solely on the floating point
> extensions supported by the target architecture.
> However, in the previous implementation the floating point register
> size was derived from whether the target architecture is 32-bit or
> 64-bit.
>
> To allow RVF without RVD, changes to riscv_gdb_get_fpu() and
> riscv_gdb_set_fpu() were necessary.
>
> Signed-off-by: Georg Kotheimer 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  configure  |  4 ++--
>  target/riscv/gdbstub.c | 45 --
>  2 files changed, 28 insertions(+), 21 deletions(-)
>
> diff --git a/configure b/configure
> index 714e7fb6a1..44ee953022 100755
> --- a/configure
> +++ b/configure
> @@ -7596,14 +7596,14 @@ case "$target_name" in
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-32bit-csr.xml"
> +gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-32bit-csr.xml"
>  target_compiler=$cross_cc_riscv32
>;;
>riscv64)
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml 
> riscv-64bit-csr.xml"
> +gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-64bit-csr.xml"
>  target_compiler=$cross_cc_riscv64
>;;
>sh4|sh4eb)
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 27be93279b..89b2543c9d 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -303,19 +303,22 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
>  {
>  if (n < 32) {
> -return gdb_get_reg64(mem_buf, env->fpr[n]);
> +if (env->misa & RVD) {
> +return gdb_get_reg64(mem_buf, env->fpr[n]);
> +}
> +return gdb_get_reg32(mem_buf, env->fpr[n]);
>  /* there is hole between ft11 and fflags in fpu.xml */
>  } else if (n < 36 && n > 32) {
>  target_ulong val = 0;
>  int result;
>  /*
> - * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
> - * register 33, so we recalculate the map index.
> + * CSR_FFLAGS is at index 1 in the csr space, and gdb says it is FP
> + * register 33, so we recalculate the csr index.
>   * This also works for CSR_FRM and CSR_FCSR.
>   */
> -result = riscv_csrrw_debug(env, n - 33 +  8, , 0, 0);
> +result = riscv_csrrw_debug(env, n - 33 + CSR_FFLAGS, , 0, 0);
>  if (result == 0) {
> -return gdb_get_regl(mem_buf, val);
> +return gdb_get_reg32(mem_buf, val);
>  }
>  }
>  return 0;
> @@ -324,20 +327,25 @@ static int riscv_gdb_get_fpu(CPURISCVState *env, 
> uint8_t *mem_buf, int n)
>  static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
>  {
>  if (n < 32) {
> -env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
> -return sizeof(uint64_t);
> +if (env->misa & RVD) {
> +env->fpr[n] = ldq_p(mem_buf);
> +return sizeof(uint64_t);
> +} else {
> +env->fpr[n] = ldl_p(mem_buf);
> +return sizeof(uint32_t);
> +}
>  /* there is hole between ft11 and fflags in fpu.xml */
>  } else if (n < 36 && n > 32) {
> -target_ulong val = ldtul_p(mem_buf);
> +target_ulong val = ldl_p(mem_buf);
>  int result;
>  /*
> - * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
> - * register 33, so we recalculate the map index.
> + * CSR_FFLAGS is at index 1 in the csr space, and gdb says it is FP
> + * register 33, so we recalculate the csr index.
>   * This also works for CSR_FRM and CSR_FCSR.
>   */
> -result = riscv_csrrw_debug(env, n - 33 + 8, NULL, val, -1);
> +result = riscv_csrrw_debug(env, n - 33 + CSR_FFLAGS, NULL, val, -1);
>  if (result == 0) {
> -return sizeof(target_ulong);
> +return sizeof(uint32_t);
>  }
>  }
>  return 0;
> @@ -375,20 +383,19 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>  {
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  CPURISCVState *env = >env;
> -#if defined(TARGET_RISCV32)
> -if (env->misa & RVF) {
> +
> +if (env->misa & RVD) {
> +gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> + 36, "riscv-64bit-fpu.xml", 0);
> +} else if (env->misa & RVF) {
>  gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
>   36, "riscv-32bit-fpu.xml", 0);
>  }
>
> +#if defined(TARGET_RISCV32)
>  gdb_register_coprocessor(cs, 

Re: [Qemu-devel] [PATCH v5 21/30] riscv: sifive_u: Add PRCI block to the SoC

2019-08-23 Thread Alistair Francis
On Thu, Aug 22, 2019 at 10:35 PM Bin Meng  wrote:
>
> Add PRCI mmio base address and size mappings to sifive_u machine,
> and generate the corresponding device tree node.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> Changes in v5:
> - create sifive_u_prci block directly in the machine codes, instead
>   of calling sifive_u_prci_create()
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  hw/riscv/sifive_u.c | 24 +++-
>  include/hw/riscv/sifive_u.h |  3 +++
>  2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 08db741..c777d41 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -9,6 +9,7 @@
>   * 0) UART
>   * 1) CLINT (Core Level Interruptor)
>   * 2) PLIC (Platform Level Interrupt Controller)
> + * 3) PRCI (Power, Reset, Clock, Interrupt)
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -61,6 +62,7 @@ static const struct MemmapEntry {
>  [SIFIVE_U_MROM] = { 0x1000,0x11000 },
>  [SIFIVE_U_CLINT] ={  0x200,0x1 },
>  [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
> +[SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
>  [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
>  [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
>  [SIFIVE_U_DRAM] = { 0x8000,0x0 },
> @@ -78,7 +80,7 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  uint32_t *cells;
>  char *nodename;
>  char ethclk_names[] = "pclk\0hclk\0tx_clk";
> -uint32_t plic_phandle, ethclk_phandle, phandle = 1;
> +uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
>  uint32_t uartclk_phandle;
>  uint32_t hfclk_phandle, rtcclk_phandle;
>
> @@ -189,6 +191,21 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  g_free(cells);
>  g_free(nodename);
>
> +prci_phandle = phandle++;
> +nodename = g_strdup_printf("/soc/clock-controller@%lx",
> +(long)memmap[SIFIVE_U_PRCI].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_cell(fdt, nodename, "phandle", prci_phandle);
> +qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x1);
> +qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +hfclk_phandle, rtcclk_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_PRCI].base,
> +0x0, memmap[SIFIVE_U_PRCI].size);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible",
> +"sifive,fu540-c000-prci");
> +g_free(nodename);
> +
>  plic_phandle = phandle++;
>  cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
>  for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> @@ -411,6 +428,8 @@ static void riscv_sifive_u_soc_init(Object *obj)
>  "cpu-type", _abort);
>  }
>
> +sysbus_init_child_obj(obj, "prci", >prci, sizeof(s->prci),
> +  TYPE_SIFIVE_U_PRCI);
>  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
>TYPE_CADENCE_GEM);
>  }
> @@ -484,6 +503,9 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
> Error **errp)
>  memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
>  SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
>
> +object_property_set_bool(OBJECT(>prci), true, "realized", );
> +sysbus_mmio_map(SYS_BUS_DEVICE(>prci), 0, memmap[SIFIVE_U_PRCI].base);
> +
>  for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
>  plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
>  }
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index debbf28..2a023be 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -21,6 +21,7 @@
>
>  #include "hw/net/cadence_gem.h"
>  #include "hw/riscv/sifive_cpu.h"
> +#include "hw/riscv/sifive_u_prci.h"
>
>  #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
>  #define RISCV_U_SOC(obj) \
> @@ -36,6 +37,7 @@ typedef struct SiFiveUSoCState {
>  RISCVHartArrayState e_cpus;
>  RISCVHartArrayState u_cpus;
>  DeviceState *plic;
> +SiFiveUPRCIState prci;
>  CadenceGEMState gem;
>  } SiFiveUSoCState;
>
> @@ -54,6 +56,7 @@ enum {
>  SIFIVE_U_MROM,
>  SIFIVE_U_CLINT,
>  SIFIVE_U_PLIC,
> +SIFIVE_U_PRCI,
>  SIFIVE_U_UART0,
>  SIFIVE_U_UART1,
>  SIFIVE_U_DRAM,
> --
> 2.7.4
>
>



Re: [Qemu-devel] [PATCH v5 19/30] riscv: sifive: Implement PRCI model for FU540

2019-08-23 Thread Alistair Francis
On Thu, Aug 22, 2019 at 10:21 PM Bin Meng  wrote:
>
> This adds a simple PRCI model for FU540 (sifive_u). It has different
> register layout from the existing PRCI model for FE310 (sifive_e).
>
> Signed-off-by: Bin Meng 
>
> ---
>
> Changes in v5:
> - change to use defines instead of enums
> - change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci
> - creating a 32-bit val variable and using that instead of casting
>   everywhere in sifive_u_prci_write()
> - move all register initialization to sifive_u_prci_reset() function
> - drop sifive_u_prci_create()
> - s/codes that worked/code that works/g
>
> Changes in v4:
> - prefix all macros/variables/functions with SIFIVE_U/sifive_u
>   in the sifive_u_prci driver
>
> Changes in v3: None
> Changes in v2: None
>
>  hw/riscv/Makefile.objs   |   1 +
>  hw/riscv/sifive_u_prci.c | 171 
> +++
>  include/hw/riscv/sifive_u_prci.h |  81 +++
>  3 files changed, 253 insertions(+)
>  create mode 100644 hw/riscv/sifive_u_prci.c
>  create mode 100644 include/hw/riscv/sifive_u_prci.h
>
> diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
> index c859697..b95bbd5 100644
> --- a/hw/riscv/Makefile.objs
> +++ b/hw/riscv/Makefile.objs
> @@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
>  obj-$(CONFIG_SIFIVE) += sifive_plic.o
>  obj-$(CONFIG_SIFIVE) += sifive_test.o
>  obj-$(CONFIG_SIFIVE_U) += sifive_u.o
> +obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
>  obj-$(CONFIG_SIFIVE) += sifive_uart.o
>  obj-$(CONFIG_SPIKE) += spike.o
>  obj-$(CONFIG_RISCV_VIRT) += virt.o
> diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c
> new file mode 100644
> index 000..c6438fb
> --- /dev/null
> +++ b/hw/riscv/sifive_u_prci.c
> @@ -0,0 +1,171 @@
> +/*
> + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt)
> + *
> + * Copyright (c) 2019 Bin Meng 
> + *
> + * Simple model of the PRCI to emulate register reads made by the SDK BSP
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/sysbus.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "hw/riscv/sifive_u_prci.h"
> +
> +static uint64_t sifive_u_prci_read(void *opaque, hwaddr addr, unsigned int 
> size)
> +{
> +SiFiveUPRCIState *s = opaque;
> +
> +switch (addr) {
> +case SIFIVE_U_PRCI_HFXOSCCFG:
> +return s->hfxosccfg;
> +case SIFIVE_U_PRCI_COREPLLCFG0:
> +return s->corepllcfg0;
> +case SIFIVE_U_PRCI_DDRPLLCFG0:
> +return s->ddrpllcfg0;
> +case SIFIVE_U_PRCI_DDRPLLCFG1:
> +return s->ddrpllcfg1;
> +case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
> +return s->gemgxlpllcfg0;
> +case SIFIVE_U_PRCI_GEMGXLPLLCFG1:
> +return s->gemgxlpllcfg1;
> +case SIFIVE_U_PRCI_CORECLKSEL:
> +return s->coreclksel;
> +case SIFIVE_U_PRCI_DEVICESRESET:
> +return s->devicesreset;
> +case SIFIVE_U_PRCI_CLKMUXSTATUS:
> +return s->clkmuxstatus;
> +}
> +
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n",
> +  __func__, (int)addr);
> +
> +return 0;
> +}
> +
> +static void sifive_u_prci_write(void *opaque, hwaddr addr,
> +uint64_t val64, unsigned int size)
> +{
> +SiFiveUPRCIState *s = opaque;
> +uint32_t val32 = (uint32_t)val64;
> +
> +switch (addr) {
> +case SIFIVE_U_PRCI_HFXOSCCFG:
> +s->hfxosccfg = val32;
> +/* OSC stays ready */
> +s->hfxosccfg |= SIFIVE_U_PRCI_HFXOSCCFG_RDY;
> +break;
> +case SIFIVE_U_PRCI_COREPLLCFG0:
> +s->corepllcfg0 = val32;
> +/* internal feedback */
> +s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
> +/* PLL stays locked */
> +s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
> +break;
> +case SIFIVE_U_PRCI_DDRPLLCFG0:
> +s->ddrpllcfg0 = val32;
> +/* internal feedback */
> +s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
> +/* PLL stays locked */
> +s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
> +break;
> +case SIFIVE_U_PRCI_DDRPLLCFG1:
> +s->ddrpllcfg1 = val32;
> +break;
> +case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
> +s->gemgxlpllcfg0 = val32;
> + /* internal feedback */
> +s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
> +   /* PLL stays 

[Qemu-devel] [PATCH v1 27/28] target/riscv: Add the MSTATUS_MPV_ISSET helper macro

2019-08-23 Thread Alistair Francis
Add a helper macro MSTATUS_MPV_ISSET() which will determine if the
MSTATUS_MPV bit is set for both 32-bit and 64-bit RISC-V.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_bits.h   | 11 +++
 target/riscv/cpu_helper.c |  4 ++--
 target/riscv/op_helper.c  |  2 +-
 target/riscv/translate.c  |  2 +-
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 55e20af6d9..7056d9218b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -365,8 +365,19 @@
 #define MSTATUS_TVM 0x0010 /* since: priv-1.10 */
 #define MSTATUS_TW  0x2000 /* since: priv-1.10 */
 #define MSTATUS_TSR 0x4000 /* since: priv-1.10 */
+#if defined(TARGET_RISCV64)
 #define MSTATUS_MTL 0x40ULL
 #define MSTATUS_MPV 0x80ULL
+#elif defined(TARGET_RISCV32)
+#define MSTATUS_MTL 0x0040
+#define MSTATUS_MPV 0x0080
+#endif
+
+#ifdef TARGET_RISCV32
+# define MSTATUS_MPV_ISSET(env)  get_field(*env->mstatush, MSTATUS_MPV)
+#else
+# define MSTATUS_MPV_ISSET(env)  get_field(*env->mstatus, MSTATUS_MPV)
+#endif
 
 #define MSTATUS64_UXL   0x0003ULL
 #define MSTATUS64_SXL   0x000CULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8c80486dd0..2b88f756bb 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -351,7 +351,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 mode = get_field(*env->mstatus, MSTATUS_MPP);
 
 if (riscv_has_ext(env, RVH) &&
-get_field(*env->mstatus, MSTATUS_MPV)) {
+MSTATUS_MPV_ISSET(env)) {
 use_background = true;
 }
 }
@@ -730,7 +730,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 m_mode_two_stage = env->priv == PRV_M &&
access_type != MMU_INST_FETCH &&
get_field(*env->mstatus, MSTATUS_MPRV) &&
-   get_field(*env->mstatus, MSTATUS_MPV);
+   MSTATUS_MPV_ISSET(env);
 
 hs_mode_two_stage = env->priv == PRV_S &&
 !riscv_cpu_virt_enabled(env) &&
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 8dec1aee99..6149cd9c15 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -146,7 +146,7 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 
 target_ulong mstatus = *env->mstatus;
 target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
-target_ulong prev_virt = get_field(mstatus, MSTATUS_MPV);
+target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
 mstatus = set_field(mstatus,
 env->priv_ver >= PRIV_VERSION_1_10_0 ?
 MSTATUS_MIE : MSTATUS_UIE << prev_priv,
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea19ba9c5d..f0d9860429 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -754,7 +754,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->virt_enabled = riscv_cpu_virt_enabled(env);
 if (env->priv_ver == PRV_M &&
 get_field(*env->mstatus, MSTATUS_MPRV) &&
-get_field(*env->mstatus, MSTATUS_MPV)) {
+MSTATUS_MPV_ISSET(env)) {
 ctx->virt_enabled = true;
 } else if (env->priv == PRV_S &&
!riscv_cpu_virt_enabled(env) &&
-- 
2.22.0




[Qemu-devel] [PATCH v1 28/28] target/riscv: Allow enabling the Hypervisor extension

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

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 06ee551ebe..39e1c130df 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -447,6 +447,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 if (cpu->cfg.ext_u) {
 target_misa |= RVU;
 }
+if (cpu->cfg.ext_h) {
+target_misa |= RVH;
+}
 
 set_misa(env, RVXLEN | target_misa);
 }
@@ -493,6 +496,8 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
+/* This is experimental so mark with 'x-' */
+DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b63f1f3cdc..500496a3be 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -268,6 +268,7 @@ typedef struct RISCVCPU {
 bool ext_c;
 bool ext_s;
 bool ext_u;
+bool ext_h;
 bool ext_counters;
 bool ext_ifencei;
 bool ext_icsr;
-- 
2.22.0




[Qemu-devel] [PATCH v1 21/28] target/riscv: Respect MPRV and SPRV for floating point ops

2019-08-23 Thread Alistair Francis
Respect the contents of MSTATUS.MPRV and HSTATUS.SPRV when performing
floating point operations when V=0.

Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 19771904f4..ea19ba9c5d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -750,7 +750,21 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS;
 ctx->priv_ver = env->priv_ver;
 #if !defined(CONFIG_USER_ONLY)
-ctx->virt_enabled = riscv_cpu_virt_enabled(env);
+if (riscv_has_ext(env, RVH)) {
+ctx->virt_enabled = riscv_cpu_virt_enabled(env);
+if (env->priv_ver == PRV_M &&
+get_field(*env->mstatus, MSTATUS_MPRV) &&
+get_field(*env->mstatus, MSTATUS_MPV)) {
+ctx->virt_enabled = true;
+} else if (env->priv == PRV_S &&
+   !riscv_cpu_virt_enabled(env) &&
+   get_field(env->hstatus, HSTATUS_SPRV) &&
+   get_field(env->hstatus, HSTATUS_SPV)) {
+ctx->virt_enabled = true;
+}
+} else {
+ctx->virt_enabled = false;
+}
 #else
 ctx->virt_enabled = false;
 #endif
-- 
2.22.0




Re: [Qemu-devel] [PATCH 0/3] mailmap: Clean up

2019-08-23 Thread Aleksandar Markovic
23.08.2019. 08.13, "Markus Armbruster"  је написао/ла:
>
> Philippe Mathieu-Daudé  writes:
>
> > Trivial cleanup of .mailmap to have a nice 'git shortlog' output.
> >
> > Philippe Mathieu-Daudé (3):
> >   mailmap: Reorder by sections
> >   mailmap: Update philmd email address
> >   mailmap: Add many entries to improve 'git shortlog' statistics
> >
> >  .mailmap | 123 +++
> >  1 file changed, 115 insertions(+), 8 deletions(-)
>
> Series
> Reviewed-by: Markus Armbruster 
>
> However, it increases the difference to contrib/gitdm/aliases.

Alex' initial gitdm effort, as I understood it, was not meant to cover all
history from 2007 or so, but just to give reasonable statistics for 2018
(amd future years).

In that light, .mailmap and gitdm aliases do not need to be equivalent.

But perhaps Alex would now want gitdm to be used for all QEMU history? Is
this desirable?

Aleksandar

> I'm just
> as guilty; my recent "[PATCH 2/2] contrib/gitdm: Add arm...@pond.sub.org
> to group-map-redhat" updates only that. and not .mailmap.
>
> Perhaps we want to keep the two in sync manually.  We should then add
> suitable comments to each file.
>
> Could we instead teach gitdm to use .mailmap, and ditch
> contrib/gitdm/aliases?
>
> aliases' format is documented in gitdm's README.  Each line maps a
> non-canonical e-mail address to a canonical one.
>
> .mailmap's format is documented in git-shortlog(1).  It can do a bit
> more.  Even the common part differs: it has two addresses in different
> order *boggle*.
>


[Qemu-devel] [PATCH v1 20/28] target/riscv: Mark both sstatus and vsstatus as dirty

2019-08-23 Thread Alistair Francis
Mark both sstatus and vsstatus as dirty (3).

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

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8ac72c6470..19771904f4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -44,6 +44,7 @@ typedef struct DisasContext {
 /* pc_succ_insn points to the instruction following base.pc_next */
 target_ulong pc_succ_insn;
 target_ulong priv_ver;
+bool virt_enabled;
 uint32_t opcode;
 uint32_t mstatus_fs;
 uint32_t misa;
@@ -398,6 +399,12 @@ static void mark_fs_dirty(DisasContext *ctx)
 tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
 tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+
+if (ctx->virt_enabled) {
+tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, vsstatus));
+tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
+tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, vsstatus));
+}
 tcg_temp_free(tmp);
 }
 #else
@@ -742,6 +749,11 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
 ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS;
 ctx->priv_ver = env->priv_ver;
+#if !defined(CONFIG_USER_ONLY)
+ctx->virt_enabled = riscv_cpu_virt_enabled(env);
+#else
+ctx->virt_enabled = false;
+#endif
 ctx->misa = env->misa;
 ctx->frm = -1;  /* unknown rounding mode */
 ctx->ext_ifencei = cpu->cfg.ext_ifencei;
-- 
2.22.0




[Qemu-devel] [PATCH v1 26/28] target/riscv: Add support for the 32-bit MSTATUSH CSR

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c|  6 ++
 target/riscv/cpu.h|  7 +++
 target/riscv/cpu_bits.h   |  3 +++
 target/riscv/cpu_helper.c |  7 +++
 target/riscv/csr.c| 23 +++
 target/riscv/op_helper.c  |  4 
 6 files changed, 50 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 371d5845af..06ee551ebe 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -229,6 +229,9 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 #ifndef CONFIG_USER_ONLY
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", *env->mstatus);
+#ifdef TARGET_RISCV32
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", *env->mstatush);
+#endif
 if (riscv_has_ext(env, RVH)) {
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "bstatus ", env->vsstatus);
@@ -468,6 +471,9 @@ static void riscv_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 env->mie = >mie_novirt;
 env->mstatus = >mstatus_novirt;
+# ifdef TARGET_RISCV32
+env->mstatush = >mstatush_novirt;
+# endif
 #endif
 }
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 05957f32a8..b63f1f3cdc 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -124,6 +124,10 @@ struct CPURISCVState {
 target_ulong mhartid;
 target_ulong *mstatus;
 
+#ifdef TARGET_RISCV32
+target_ulong *mstatush;
+#endif
+
 /*
  * CAUTION! Unlike the rest of this struct, mip and mip_novirt is accessed
  * asynchonously by I/O threads. It should be read with atomic_read. It 
should
@@ -164,6 +168,9 @@ struct CPURISCVState {
  */
 target_ulong mie_novirt;
 target_ulong mstatus_novirt;
+#ifdef TARGET_RISCV32
+target_ulong mstatush_novirt;
+#endif
 
 /* Hypervisor CSRs */
 target_ulong hstatus;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 353fc9a24a..55e20af6d9 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -135,6 +135,9 @@
 #define CSR_MTVEC   0x305
 #define CSR_MCOUNTEREN  0x306
 
+/* 32-bit only */
+#define CSR_MSTATUSH0x310
+
 /* Legacy Counter Setup (priv v1.9.1) */
 /* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
 #define CSR_MUCOUNTEREN 0x320
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 0761191f11..8c80486dd0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -949,10 +949,17 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 if (riscv_cpu_virt_enabled(env)) {
 riscv_cpu_swap_hypervisor_regs(env);
 }
+#ifdef TARGET_RISCV32
+*env->mstatush = set_field(*env->mstatush, MSTATUS_MPV,
+   riscv_cpu_virt_enabled(env));
+*env->mstatush = set_field(*env->mstatush, MSTATUS_MTL,
+   riscv_cpu_force_hs_excep_enabled(env));
+#else
 *env->mstatus = set_field(*env->mstatus, MSTATUS_MPV,
   riscv_cpu_virt_enabled(env));
 *env->mstatus = set_field(*env->mstatus, MSTATUS_MTL,
   riscv_cpu_force_hs_excep_enabled(env));
+#endif
 
 /* Trapping to M mode, virt is disabled */
 riscv_cpu_set_virt_enabled(env, VIRT_OFF);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 47be4b1d42..b7d6d009dc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -364,6 +364,25 @@ static int write_mstatus(CPURISCVState *env, int csrno, 
target_ulong val)
 return 0;
 }
 
+#ifdef TARGET_RISCV32
+static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = *env->mstatush;
+return 0;
+}
+
+static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
+{
+if ((val ^ *env->mstatush) & (MSTATUS_MPV)) {
+tlb_flush(env_cpu(env));
+}
+
+*env->mstatush = val;
+
+return 0;
+}
+#endif
+
 static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
 {
 *val = env->misa;
@@ -1095,6 +1114,10 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_MTVEC] =   { any,  read_mtvec,   write_mtvec   },
 [CSR_MCOUNTEREN] =  { any,  read_mcounteren,  write_mcounteren  },
 
+#if defined(TARGET_RISCV32)
+[CSR_MSTATUSH] ={ any,  read_mstatush,write_mstatush},
+#endif
+
 /* Legacy Counter Setup (priv v1.9.1) */
 [CSR_MUCOUNTEREN] = { any,  read_mucounteren, write_mucounteren },
 [CSR_MSCOUNTEREN] = { any,  read_mscounteren, write_mscounteren },
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 5bcf5d2ff7..8dec1aee99 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -153,7 +153,11 @@ target_ulong 

Re: [Qemu-devel] [PATCH] migrtion: define MigrationState/MigrationIncomingState.state as MigrationStatus

2019-08-23 Thread Wei Yang
On Fri, Aug 23, 2019 at 11:21:50AM -0500, Eric Blake wrote:
>On 8/19/19 9:08 AM, Wei Yang wrote:
>> On Mon, Aug 19, 2019 at 12:26:32PM +0100, Dr. David Alan Gilbert wrote:
>>> * Wei Yang (richardw.y...@linux.intel.com) wrote:
>
>Typo in the subject line: migrtion should be migration
>
 No functional change. Add default case to fix warning.
>>>
>>> I think the problem with this is that migrate_set_state uses an
>>> atomic_cmpxchg and so we have to be careful that the type we use
>>> is compatible with that.
>>> MigrationStatus is an enum and I think compilers are allowed to
>>> choose the types of that;  so I'm not sure we're guaranteed
>>> that an enum is always OK for the atomic_cmpxchg, and if it is
>> 
>> Took a look into the definition of atomic_cmpxchg, which finally calls
>> 
>>   * __atomic_compare_exchange_n for c++11
>>   * __sync_val_compare_and_swap
>
>Those are compiler-defined macros, so you have to consult the compiler
>documentation to see if they state what happens when invoked on an enum
>type.  You also have to check whether our macro
>typeof_strip_qual(enum_type) produces 'int' or something else.
>
>C99 doesn't specify _Atomic at all (which is why we handrolled our own
>atomic.h built on top of compiler primitives, instead of using
>).  But reading C11, I see that 6.7.2.4 states that
>_Atomic(type) is okay except for:
>
>"The type name in an atomic type specifier shall not refer to an array
>type, a function type, an atomic type, or a qualified type."
>
>which does NOT preclude the use of _Atomic(enum_type), so presumably
>compilers have to be prepared to handle an atomic enum type.  Still,
>it's rather shaky ground if you can't prove compilers handle it correctly.
>

Sounds this is a dark area for all those compilers. I would keep the code
untouched now.

Thanks

>
>> 
>> Both of them take two pointers to compare and exchange its content.
>> 
>> Per C99 standard, http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf,
>> it mentioned:
>> 
>>   Each enumerated type shall be compatible with char, a signed integer type,
>>   or an unsigned integer type. The choice of type is implementation-defined,
>>   but shall be capable of representing the values of all the members of the
>>   enumeration.
>> 
>> Based on this, I think atomic_cmpxchg should work fine with enum.
>
>What C99 says is rather weak; you really want to be basing your
>decisions on atomics based on C11 or later.
>
>
>-- 
>Eric Blake, Principal Software Engineer
>Red Hat, Inc.   +1-919-301-3226
>Virtualization:  qemu.org | libvirt.org
>




-- 
Wei Yang
Help you, Help me



[Qemu-devel] [PATCH v1 19/28] target/riscv: Disable guest FP support based on virtual status

2019-08-23 Thread Alistair Francis
When the Hypervisor extension is in use we only enable floating point
support when both status and vsstatus have enabled floating point
support.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 17eec6217b..098873c83e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -90,6 +90,9 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 bool riscv_cpu_fp_enabled(CPURISCVState *env)
 {
 if (*env->mstatus & MSTATUS_FS) {
+if (riscv_cpu_virt_enabled(env) && !(env->vsstatus & MSTATUS_FS)) {
+return false;
+}
 return true;
 }
 
-- 
2.22.0




[Qemu-devel] [PATCH v1 23/28] target/riscv: Allow specifying number of MMU stages

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9aa6906acd..8b9871f9ea 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -330,7 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
 static int get_physical_address(CPURISCVState *env, hwaddr *physical,
 int *prot, target_ulong addr,
 int access_type, int mmu_idx,
-bool first_stage)
+bool first_stage, bool two_stage)
 {
 /* NOTE: the env->pc value visible here will not be
  * correct, but the value visible to the exception handler
@@ -571,9 +571,10 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 int mmu_idx = cpu_mmu_index(>env, false);
 
 if (get_physical_address(>env, _addr, , addr, 0, mmu_idx,
- true)) {
+ true, false)) {
 return -1;
 }
+
 return phys_addr;
 }
 
@@ -634,7 +635,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
   __func__, address, access_type, mmu_idx);
 
 ret = get_physical_address(env, , , address, access_type, mmu_idx,
-   true);
+   true, false);
 
 if (mode == PRV_M && access_type != MMU_INST_FETCH) {
 if (get_field(*env->mstatus, MSTATUS_MPRV)) {
-- 
2.22.0




[Qemu-devel] [PATCH v1 17/28] target/riscv: Add Hypervisor trap return support

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 66 
 1 file changed, 54 insertions(+), 12 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index beb34e705b..5bcf5d2ff7 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -73,6 +73,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong 
src,
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
+target_ulong prev_priv, prev_virt, mstatus;
+
 if (!(env->priv >= PRV_S)) {
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
 }
@@ -87,16 +89,46 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
 }
 
-target_ulong mstatus = *env->mstatus;
-target_ulong prev_priv = get_field(mstatus, MSTATUS_SPP);
-mstatus = set_field(mstatus,
-env->priv_ver >= PRIV_VERSION_1_10_0 ?
-MSTATUS_SIE : MSTATUS_UIE << prev_priv,
-get_field(mstatus, MSTATUS_SPIE));
-mstatus = set_field(mstatus, MSTATUS_SPIE, 0);
-mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+mstatus = *env->mstatus;
+
+if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
+/* We support Hypervisor extensions and virtulisation is disabled */
+target_ulong hstatus = env->hstatus;
+
+prev_priv = get_field(mstatus, MSTATUS_SPP);
+prev_virt = get_field(hstatus, HSTATUS_SPV);
+
+hstatus = set_field(hstatus, HSTATUS_SPV,
+ get_field(hstatus, HSTATUS_SP2V));
+mstatus = set_field(mstatus, MSTATUS_SPP,
+get_field(hstatus, HSTATUS_SP2P));
+hstatus = set_field(hstatus, HSTATUS_SP2V, 0);
+hstatus = set_field(hstatus, HSTATUS_SP2P, 0);
+mstatus = set_field(mstatus, SSTATUS_SIE,
+get_field(mstatus, SSTATUS_SPIE));
+mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
+
+*env->mstatus = mstatus;
+env->hstatus = hstatus;
+
+if (prev_virt == VIRT_ON) {
+riscv_cpu_swap_hypervisor_regs(env);
+}
+
+riscv_cpu_set_virt_enabled(env, prev_virt);
+} else {
+prev_priv = get_field(mstatus, MSTATUS_SPP);
+
+mstatus = set_field(mstatus,
+env->priv_ver >= PRIV_VERSION_1_10_0 ?
+MSTATUS_SIE : MSTATUS_UIE << prev_priv,
+get_field(mstatus, MSTATUS_SPIE));
+mstatus = set_field(mstatus, MSTATUS_SPIE, 0);
+mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+*env->mstatus = mstatus;
+}
+
 riscv_cpu_set_mode(env, prev_priv);
-*env->mstatus = mstatus;
 
 return retpc;
 }
@@ -114,14 +146,24 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 
 target_ulong mstatus = *env->mstatus;
 target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+target_ulong prev_virt = get_field(mstatus, MSTATUS_MPV);
 mstatus = set_field(mstatus,
 env->priv_ver >= PRIV_VERSION_1_10_0 ?
 MSTATUS_MIE : MSTATUS_UIE << prev_priv,
 get_field(mstatus, MSTATUS_MPIE));
-mstatus = set_field(mstatus, MSTATUS_MPIE, 0);
-mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
-riscv_cpu_set_mode(env, prev_priv);
+mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
+mstatus = set_field(mstatus, MSTATUS_MPP, 0);
+mstatus = set_field(mstatus, MSTATUS_MPV, 0);
 *env->mstatus = mstatus;
+riscv_cpu_set_mode(env, prev_priv);
+
+if (riscv_has_ext(env, RVH)) {
+if (prev_virt == VIRT_ON) {
+riscv_cpu_swap_hypervisor_regs(env);
+}
+
+riscv_cpu_set_virt_enabled(env, prev_virt);
+}
 
 return retpc;
 }
-- 
2.22.0




[Qemu-devel] [PATCH v1 25/28] target/riscv: Call the second stage MMU in virtualisation mode

2019-08-23 Thread Alistair Francis
The qemu_log_mask(CPU_LOG_MMU,... calls trigger false positive
checkpatch errors which are being ignored.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 94 +++
 1 file changed, 86 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 188d5cb39f..0761191f11 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -642,15 +642,23 @@ static void raise_mmu_exception(CPURISCVState *env, 
target_ulong address,
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
 hwaddr phys_addr;
 int prot;
 int mmu_idx = cpu_mmu_index(>env, false);
 
-if (get_physical_address(>env, _addr, , addr, 0, mmu_idx,
- true, false)) {
+if (get_physical_address(env, _addr, , addr, 0, mmu_idx,
+ true, riscv_cpu_virt_enabled(env))) {
 return -1;
 }
 
+if (riscv_cpu_virt_enabled(env)) {
+if (get_physical_address(env, _addr, , phys_addr,
+ 0, mmu_idx, false, true)) {
+return -1;
+}
+}
+
 return phys_addr;
 }
 
@@ -701,17 +709,35 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 #ifndef CONFIG_USER_ONLY
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
+vaddr im_address;
 hwaddr pa = 0;
 int prot;
 bool pmp_violation = false;
+bool m_mode_two_stage = false;
+bool hs_mode_two_stage = false;
+bool first_stage_error = true;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
 
 qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
   __func__, address, access_type, mmu_idx);
 
-ret = get_physical_address(env, , , address, access_type, mmu_idx,
-   true, false);
+/*
+ * Determine if we are in M mode and MPRV is set or in HS mode and SPRV is
+ * set and we want to access a virtulisation address.
+ */
+if (riscv_has_ext(env, RVH)) {
+m_mode_two_stage = env->priv == PRV_M &&
+   access_type != MMU_INST_FETCH &&
+   get_field(*env->mstatus, MSTATUS_MPRV) &&
+   get_field(*env->mstatus, MSTATUS_MPV);
+
+hs_mode_two_stage = env->priv == PRV_S &&
+!riscv_cpu_virt_enabled(env) &&
+access_type != MMU_INST_FETCH &&
+get_field(env->hstatus, HSTATUS_SPRV) &&
+get_field(env->hstatus, HSTATUS_SPV);
+}
 
 if (mode == PRV_M && access_type != MMU_INST_FETCH) {
 if (get_field(*env->mstatus, MSTATUS_MPRV)) {
@@ -719,10 +745,58 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 
-qemu_log_mask(CPU_LOG_MMU,
-  "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
-  " prot %d\n", __func__, address, ret, pa, prot);
+if (riscv_cpu_virt_enabled(env) || m_mode_two_stage || hs_mode_two_stage) {
+/* Two stage lookup */
+ret = get_physical_address(env, , , address, access_type,
+   mmu_idx, true, true);
+
+qemu_log_mask(CPU_LOG_MMU,
+  "%s 1st-stage address=%" VADDR_PRIx " ret %d physical "
+  TARGET_FMT_plx " prot %d\n",
+  __func__, address, ret, pa, prot);
+
+if (ret == TRANSLATE_FAIL) {
+goto tlb_lookup_done;
+}
+
+/* Second stage lookup */
+im_address = pa;
 
+ret = get_physical_address(env, , , im_address, access_type, 
mmu_idx,
+   false, true);
+
+qemu_log_mask(CPU_LOG_MMU,
+"%s 2nd-stage address=%" VADDR_PRIx " ret %d physical "
+TARGET_FMT_plx " prot %d\n",
+__func__, im_address, ret, pa, prot);
+
+if (riscv_feature(env, RISCV_FEATURE_PMP) &&
+(ret == TRANSLATE_SUCCESS) &&
+!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
+ret = TRANSLATE_PMP_FAIL;
+}
+
+if (ret != TRANSLATE_SUCCESS) {
+/*
+ * Guest physical address translation failed, this is a HS
+ * level exception
+ */
+first_stage_error = false;
+address = im_address | (address & (TARGET_PAGE_SIZE - 1));
+goto tlb_lookup_done;
+}
+} else {
+/* Single stage lookup */
+ret = get_physical_address(env, , , address, access_type,
+   mmu_idx, true, false);
+
+qemu_log_mask(CPU_LOG_MMU,
+  "%s address=%" VADDR_PRIx " ret %d physical "
+  TARGET_FMT_plx " prot %d\n",
+  __func__, 

[Qemu-devel] [PATCH v1 22/28] target/riscv: Allow specifying MMU stage

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 39 ++-
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 098873c83e..9aa6906acd 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -318,10 +318,19 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
  *
  * Adapted from Spike's mmu_t::translate and mmu_t::walk
  *
+ * @env: CPURISCVState
+ * @physical: This will be set to the calculated physical address
+ * @prot: The returned protection attributes
+ * @addr: The virtual address to be translated
+ * @access_type: The type of MMU access
+ * @mmu_idx: Indicates current privilege level
+ * @first_stage: Are we in first stage translation?
+ *   Second stage is used for hypervisor guest translation
  */
 static int get_physical_address(CPURISCVState *env, hwaddr *physical,
 int *prot, target_ulong addr,
-int access_type, int mmu_idx)
+int access_type, int mmu_idx,
+bool first_stage)
 {
 /* NOTE: the env->pc value visible here will not be
  * correct, but the value visible to the exception handler
@@ -518,13 +527,23 @@ restart:
 }
 
 static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
-MMUAccessType access_type, bool pmp_violation)
+MMUAccessType access_type, bool pmp_violation,
+bool first_stage)
 {
 CPUState *cs = env_cpu(env);
-int page_fault_exceptions =
-(env->priv_ver >= PRIV_VERSION_1_10_0) &&
-get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
-!pmp_violation;
+int page_fault_exceptions;
+if (first_stage) {
+page_fault_exceptions =
+(env->priv_ver >= PRIV_VERSION_1_10_0) &&
+get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
+!pmp_violation;
+riscv_cpu_set_force_hs_excep(env, CLEAR_HS_EXCEP);
+} else {
+page_fault_exceptions =
+get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE &&
+!pmp_violation;
+riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP);
+}
 switch (access_type) {
 case MMU_INST_FETCH:
 cs->exception_index = page_fault_exceptions ?
@@ -551,7 +570,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 int prot;
 int mmu_idx = cpu_mmu_index(>env, false);
 
-if (get_physical_address(>env, _addr, , addr, 0, mmu_idx)) {
+if (get_physical_address(>env, _addr, , addr, 0, mmu_idx,
+ true)) {
 return -1;
 }
 return phys_addr;
@@ -613,7 +633,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
   __func__, address, access_type, mmu_idx);
 
-ret = get_physical_address(env, , , address, access_type, mmu_idx);
+ret = get_physical_address(env, , , address, access_type, mmu_idx,
+   true);
 
 if (mode == PRV_M && access_type != MMU_INST_FETCH) {
 if (get_field(*env->mstatus, MSTATUS_MPRV)) {
@@ -640,7 +661,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 } else if (probe) {
 return false;
 } else {
-raise_mmu_exception(env, address, access_type, pmp_violation);
+raise_mmu_exception(env, address, access_type, pmp_violation, true);
 riscv_raise_exception(env, cs->exception_index, retaddr);
 }
 #else
-- 
2.22.0




[Qemu-devel] [PATCH v1 09/28] target/riscv: Add Hypervisor virtual CSRs accesses

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_bits.h |  11 
 target/riscv/csr.c  | 119 
 2 files changed, 130 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 204d9d9a79..78067901a2 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -191,6 +191,17 @@
 #define HGATP_PPNSATP64_PPN
 #endif
 
+/* Virtual CSRs */
+#define CSR_VSSTATUS0x200
+#define CSR_VSIE0x204
+#define CSR_VSTVEC  0x205
+#define CSR_VSSCRATCH   0x240
+#define CSR_VSEPC   0x241
+#define CSR_VSCAUSE 0x242
+#define CSR_VSTVAL  0x243
+#define CSR_VSIP0x244
+#define CSR_VSATP   0x280
+
 /* Physical Memory Protection */
 #define CSR_PMPCFG0 0x3a0
 #define CSR_PMPCFG1 0x3a1
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 388775d45a..e2e908fbc0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -817,6 +817,115 @@ static int write_hgatp(CPURISCVState *env, int csrno, 
target_ulong val)
 return 0;
 }
 
+/* Virtual CSR Registers */
+static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vsstatus;
+return 0;
+}
+
+static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vsstatus = val;
+return 0;
+}
+
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vsie;
+return 0;
+}
+
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vsie = val;
+return 0;
+}
+
+static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vstvec;
+return 0;
+}
+
+static int write_vstvec(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vstvec = val;
+return 0;
+}
+
+static int read_vsscratch(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vsscratch;
+return 0;
+}
+
+static int write_vsscratch(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vsscratch = val;
+return 0;
+}
+
+static int read_vsepc(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vsepc;
+return 0;
+}
+
+static int write_vsepc(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vsepc = val;
+return 0;
+}
+
+static int read_vscause(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vscause;
+return 0;
+}
+
+static int write_vscause(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vscause = val;
+return 0;
+}
+
+static int read_vstval(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vstval;
+return 0;
+}
+
+static int write_vstval(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vstval = val;
+return 0;
+}
+
+static int read_vsip(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = (target_ulong)atomic_read(>vsip);
+return 0;
+}
+
+static int write_vsip(CPURISCVState *env, int csrno, target_ulong val)
+{
+atomic_set(>vsip, val);
+return 0;
+}
+
+static int read_vsatp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->vsatp;
+return 0;
+}
+
+static int write_vsatp(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->vsatp = val;
+return 0;
+}
+
 /* Physical Memory Protection */
 static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -1018,6 +1127,16 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_HIDELEG] = { hmode,   read_hideleg, write_hideleg
},
 [CSR_HGATP] =   { hmode,   read_hgatp,   write_hgatp  
},
 
+[CSR_VSSTATUS] ={ hmode,   read_vsstatus,write_vsstatus   
},
+[CSR_VSIE] ={ hmode,   read_vsie,write_vsie   
},
+[CSR_VSTVEC] =  { hmode,   read_vstvec,  write_vstvec 
},
+[CSR_VSSCRATCH] =   { hmode,   read_vsscratch,   write_vsscratch  
},
+[CSR_VSEPC] =   { hmode,   read_vsepc,   write_vsepc  
},
+[CSR_VSCAUSE] = { hmode,   read_vscause, write_vscause
},
+[CSR_VSTVAL] =  { hmode,   read_vstval,  write_vstval 
},
+[CSR_VSIP] ={ hmode,   read_vsip,write_vsip   
},
+[CSR_VSATP] =   { hmode,   read_vsatp,   write_vsatp  
},
+
 /* Physical Memory Protection */
 [CSR_PMPCFG0  ... CSR_PMPADDR9] =  { pmp,   read_pmpcfg,  write_pmpcfg   },
 [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp,   read_pmpaddr, write_pmpaddr  },
-- 
2.22.0




[Qemu-devel] [PATCH v1 24/28] target/riscv: Implement second stage MMU

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 96 +++
 1 file changed, 86 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8b9871f9ea..188d5cb39f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -337,13 +337,40 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
  * (riscv_cpu_do_interrupt) is correct */
 
 int mode = mmu_idx;
+bool use_background = false;
 
+/*
+ * Check if we should use the background registers for the two
+ * stage translation. We don't need to check if we actually need
+ * two stage translation as that happened before this function
+ * was called. Background registers will be used if the guest has
+ * forced a two stage translation to be on (in HS or M mode).
+ */
 if (mode == PRV_M && access_type != MMU_INST_FETCH) {
 if (get_field(*env->mstatus, MSTATUS_MPRV)) {
 mode = get_field(*env->mstatus, MSTATUS_MPP);
+
+if (riscv_has_ext(env, RVH) &&
+get_field(*env->mstatus, MSTATUS_MPV)) {
+use_background = true;
+}
 }
 }
 
+if (mode == PRV_S && access_type != MMU_INST_FETCH &&
+riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
+if (get_field(env->hstatus, HSTATUS_SPRV)) {
+mode = get_field(*env->mstatus, SSTATUS_SPP);
+use_background = true;
+}
+}
+
+if (first_stage == false) {
+/* We are in stage 2 translation, this is similar to stage 1. */
+/* Stage 2 is always taken as U-mode */
+mode = PRV_U;
+}
+
 if (mode == PRV_M || !riscv_feature(env, RISCV_FEATURE_MMU)) {
 *physical = addr;
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -353,13 +380,30 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
 *prot = 0;
 
 target_ulong base;
-int levels, ptidxbits, ptesize, vm, sum;
-int mxr = get_field(*env->mstatus, MSTATUS_MXR);
+int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
+
+if (first_stage == true) {
+mxr = get_field(*env->mstatus, MSTATUS_MXR);
+} else {
+mxr = get_field(env->vsstatus, MSTATUS_MXR);
+}
 
 if (env->priv_ver >= PRIV_VERSION_1_10_0) {
-base = get_field(env->satp, SATP_PPN) << PGSHIFT;
+if (first_stage == true) {
+if (use_background) {
+base = get_field(env->vsatp, SATP_PPN) << PGSHIFT;
+vm = get_field(env->vsatp, SATP_MODE);
+} else {
+base = get_field(env->satp, SATP_PPN) << PGSHIFT;
+vm = get_field(env->satp, SATP_MODE);
+}
+widened = 0;
+} else {
+base = get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
+vm = get_field(env->hgatp, HGATP_MODE);
+widened = 2;
+}
 sum = get_field(*env->mstatus, MSTATUS_SUM);
-vm = get_field(env->satp, SATP_MODE);
 switch (vm) {
 case VM_1_10_SV32:
   levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -377,6 +421,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
   g_assert_not_reached();
 }
 } else {
+widened = 0;
 base = env->sptbr << PGSHIFT;
 sum = !get_field(*env->mstatus, MSTATUS_PUM);
 vm = get_field(*env->mstatus, MSTATUS_VM);
@@ -397,9 +442,16 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 
 CPUState *cs = env_cpu(env);
-int va_bits = PGSHIFT + levels * ptidxbits;
-target_ulong mask = (1L << (TARGET_LONG_BITS - (va_bits - 1))) - 1;
-target_ulong masked_msbs = (addr >> (va_bits - 1)) & mask;
+int va_bits = PGSHIFT + levels * ptidxbits + widened;
+target_ulong mask, masked_msbs;
+
+if (TARGET_LONG_BITS > (va_bits - 1)) {
+mask = (1L << (TARGET_LONG_BITS - (va_bits - 1))) - 1;
+} else {
+mask = 0;
+}
+masked_msbs = (addr >> (va_bits - 1)) & mask;
+
 if (masked_msbs != 0 && masked_msbs != mask) {
 return TRANSLATE_FAIL;
 }
@@ -411,17 +463,36 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
 restart:
 #endif
 for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
-target_ulong idx = (addr >> (PGSHIFT + ptshift)) &
+target_ulong idx;
+if (i == 0) {
+idx = (addr >> (PGSHIFT + ptshift)) &
+   ((1 << (ptidxbits + widened)) - 1);
+} else {
+idx = (addr >> (PGSHIFT + ptshift)) &
((1 << ptidxbits) - 1);
+}
 
 /* check that physical address of PTE is legal */
-target_ulong pte_addr = base + idx * ptesize;
+target_ulong pte_addr;
+
+if (two_stage && first_stage) {
+hwaddr vbase;
+
+

[Qemu-devel] [PATCH v1 16/28] target/riscv: Add hypvervisor trap support

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_bits.h   |  4 +--
 target/riscv/cpu_helper.c | 71 +--
 target/riscv/csr.c|  4 +--
 3 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 5cee72b726..353fc9a24a 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -513,8 +513,8 @@
 #define RISCV_EXCP_STORE_AMO_ADDR_MIS  0x6
 #define RISCV_EXCP_STORE_AMO_ACCESS_FAULT  0x7
 #define RISCV_EXCP_U_ECALL 0x8
-#define RISCV_EXCP_S_ECALL 0x9
-#define RISCV_EXCP_H_ECALL 0xa
+#define RISCV_EXCP_HS_ECALL0x9
+#define RISCV_EXCP_VS_ECALL0xa
 #define RISCV_EXCP_M_ECALL 0xb
 #define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
 #define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8e8b156fc0..17eec6217b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -668,6 +668,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
+target_ulong s;
 
 /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
  * so we mask off the MSB and separate into trap type and cause.
@@ -677,13 +678,6 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 target_ulong deleg = async ? env->mideleg : env->medeleg;
 target_ulong tval = 0;
 
-static const int ecall_cause_map[] = {
-[PRV_U] = RISCV_EXCP_U_ECALL,
-[PRV_S] = RISCV_EXCP_S_ECALL,
-[PRV_H] = RISCV_EXCP_H_ECALL,
-[PRV_M] = RISCV_EXCP_M_ECALL
-};
-
 if (!async) {
 /* set tval to badaddr for traps with address information */
 switch (cause) {
@@ -704,7 +698,16 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 /* ecall is dispatched as one cause so translate based on mode */
 if (cause == RISCV_EXCP_U_ECALL) {
 assert(env->priv <= 3);
-cause = ecall_cause_map[env->priv];
+
+if (env->priv == PRV_M) {
+cause = RISCV_EXCP_M_ECALL;
+} else if (env->priv == PRV_S && riscv_cpu_virt_enabled(env)) {
+cause = RISCV_EXCP_VS_ECALL;
+} else if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) {
+cause = RISCV_EXCP_HS_ECALL;
+} else if (env->priv == PRV_U) {
+cause = RISCV_EXCP_U_ECALL;
+}
 }
 }
 
@@ -714,7 +717,42 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 if (env->priv <= PRV_S &&
 cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
 /* handle the trap in S-mode */
-target_ulong s = *env->mstatus;
+if (riscv_has_ext(env, RVH)) {
+target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
+
+if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) &&
+!riscv_cpu_force_hs_excep_enabled(env)) {
+/* Trap to VS mode */
+} else if (riscv_cpu_virt_enabled(env)) {
+/* Trap into HS mode, from virt */
+riscv_cpu_swap_hypervisor_regs(env);
+env->hstatus = set_field(env->hstatus, HSTATUS_SP2V,
+ get_field(env->hstatus, HSTATUS_SPV));
+env->hstatus = set_field(env->hstatus, HSTATUS_SP2P,
+ get_field(*env->mstatus, 
SSTATUS_SPP));
+env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
+ riscv_cpu_virt_enabled(env));
+
+if (riscv_cpu_force_hs_excep_enabled(env)) {
+env->hstatus = set_field(env->hstatus, HSTATUS_STL, 1);
+} else {
+env->hstatus = set_field(env->hstatus, HSTATUS_STL, 0);
+}
+
+riscv_cpu_set_virt_enabled(env, VIRT_OFF);
+riscv_cpu_set_force_hs_excep(env, CLEAR_HS_EXCEP);
+} else {
+/* Trap into HS mode */
+env->hstatus = set_field(env->hstatus, HSTATUS_SP2V,
+ get_field(env->hstatus, HSTATUS_SPV));
+env->hstatus = set_field(env->hstatus, HSTATUS_SP2P,
+ get_field(*env->mstatus, 
SSTATUS_SPP));
+env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
+ riscv_cpu_virt_enabled(env));
+}
+}
+
+s = *env->mstatus;
 s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
 get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << 
env->priv));
 s = set_field(s, MSTATUS_SPP, env->priv);
@@ -728,7 +766,20 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 

[Qemu-devel] [PATCH v1 18/28] target/riscv: Add hfence instructions

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/insn32.decode| 23 ++-
 .../riscv/insn_trans/trans_privileged.inc.c   | 40 +++
 2 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 77f794ed70..cfd9ca6d2b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -63,20 +63,25 @@
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... %rs1 %rd
 
+@hfence_gvma ... . .   ... . ... %rs2 %rs1
+@hfence_bvma ... . .   ... . ... %rs2 %rs1
+
 @sfence_vma ... . .   ... . ... %rs2 %rs1
 @sfence_vm  ... . .   ... . ... %rs1
 
 
 # *** Privileged Instructions ***
-ecall   0 000 0 1110011
-ebreak 0001 0 000 0 1110011
-uret   00000010 0 000 0 1110011
-sret   000100000010 0 000 0 1110011
-hret   00100010 0 000 0 1110011
-mret   001100000010 0 000 0 1110011
-wfi000100000101 0 000 0 1110011
-sfence_vma 0001001. . 000 0 1110011 @sfence_vma
-sfence_vm  000100000100 . 000 0 1110011 @sfence_vm
+ecall    0 000 0 1110011
+ebreak  0001 0 000 0 1110011
+uret00000010 0 000 0 1110011
+sret000100000010 0 000 0 1110011
+hret00100010 0 000 0 1110011
+mret001100000010 0 000 0 1110011
+wfi 000100000101 0 000 0 1110011
+hfence_gvma 0110001. . 000 0 1110011 @hfence_gvma
+hfence_bvma 0010001. . 000 0 1110011 @hfence_bvma
+sfence_vma  0001001. . 000 0 1110011 @sfence_vma
+sfence_vm   000100000100 . 000 0 1110011 @sfence_vm
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
index c5e4b3e49a..b9b5a89b52 100644
--- a/target/riscv/insn_trans/trans_privileged.inc.c
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -108,3 +108,43 @@ static bool trans_sfence_vm(DisasContext *ctx, 
arg_sfence_vm *a)
 #endif
 return false;
 }
+
+static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
+has_ext(ctx, RVH)) {
+/* Hpervisor extensions exist */
+/*
+ * if (env->priv == PRV_M ||
+ *   (env->priv == PRV_S &&
+ *!riscv_cpu_virt_enabled(env) &&
+ *get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
+ */
+gen_helper_tlb_flush(cpu_env);
+return true;
+/* } */
+}
+#endif
+return false;
+}
+
+static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
+has_ext(ctx, RVH)) {
+/* Hpervisor extensions exist */
+/*
+ * if (env->priv == PRV_M ||
+ *   (env->priv == PRV_S &&
+ *!riscv_cpu_virt_enabled(env) &&
+ *get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
+ */
+gen_helper_tlb_flush(cpu_env);
+return true;
+/* } */
+}
+#endif
+return false;
+}
-- 
2.22.0




[Qemu-devel] [PATCH v1 07/28] target/riscv: Dump Hypervisor registers if enabled

2019-08-23 Thread Alistair Francis
Dump the Hypervisor registers and the current Hypervisor state.

While we are editing this code let's also dump stvec and scause.

Signed-off-by: Alistair Francis 
Signed-off-by: Atish Patra 
---
 target/riscv/cpu.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f13e298a36..be8f643fc2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -220,18 +220,52 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
int flags)
 CPURISCVState *env = >env;
 int i;
 
+#if !defined(CONFIG_USER_ONLY)
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s %d\n", "V  =  ", riscv_cpu_virt_enabled(env));
+}
+#endif
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc  ", env->pc);
 #ifndef CONFIG_USER_ONLY
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "bstatus ", env->vsstatus);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
  (target_ulong)atomic_read(>mip));
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsip",
+ (target_ulong)atomic_read(>vsip));
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsie", env->vsie);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hideleg ", env->hideleg);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hedeleg ", env->hedeleg);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec   ", env->mtvec);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stvec   ", env->stvec);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vstvec  ", env->vstvec);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc", env->mepc);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sepc", env->sepc);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsepc   ", env->vsepc);
+}
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause  ", env->mcause);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "scause  ", env->scause);
+if (riscv_has_ext(env, RVH)) {
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
+}
 #endif
 
 for (i = 0; i < 32; i++) {
-- 
2.22.0




[Qemu-devel] [PATCH v1 15/28] riscv: plic: Always set sip.SEIP bit for HS

2019-08-23 Thread Alistair Francis
When the PLIC generates an interrupt ensure we always set it for the SIP
CSR that corresponds to the HS (V=0) register.

Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_plic.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 98e4304b66..8309e96f64 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -150,7 +150,17 @@ static void sifive_plic_update(SiFivePLICState *plic)
 riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, 
BOOL_TO_MASK(level));
 break;
 case PLICMode_S:
-riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, 
BOOL_TO_MASK(level));
+if (riscv_cpu_virt_enabled(env)) {
+if (level) {
+atomic_or(>mip_novirt, MIP_SEIP);
+g_assert(riscv_cpu_virt_enabled(env));
+} else {
+atomic_and(>mip_novirt, ~MIP_SEIP);
+g_assert(riscv_cpu_virt_enabled(env));
+}
+} else {
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, 
BOOL_TO_MASK(level));
+}
 break;
 default:
 break;
-- 
2.22.0




[Qemu-devel] [PATCH v1 08/28] target/riscv: Add Hypervisor CSR access functions

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 68 ++
 1 file changed, 68 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 471f23a1d0..388775d45a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -98,6 +98,20 @@ static int smode(CPURISCVState *env, int csrno)
 return -!riscv_has_ext(env, RVS);
 }
 
+static int hmode(CPURISCVState *env, int csrno)
+{
+if (riscv_has_ext(env, RVS) &&
+riscv_has_ext(env, RVH)) {
+/* Hypervisor extension is supported */
+if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
+env->priv == PRV_M) {
+return 0;
+}
+}
+
+return -1;
+}
+
 static int pmp(CPURISCVState *env, int csrno)
 {
 return -!riscv_feature(env, RISCV_FEATURE_PMP);
@@ -754,6 +768,55 @@ static int write_satp(CPURISCVState *env, int csrno, 
target_ulong val)
 return 0;
 }
 
+/* Hypervisor Extensions */
+static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->hstatus;
+return 0;
+}
+
+static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->hstatus = val;
+return 0;
+}
+
+static int read_hedeleg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->hedeleg;
+return 0;
+}
+
+static int write_hedeleg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->hedeleg = val;
+return 0;
+}
+
+static int read_hideleg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->hideleg;
+return 0;
+}
+
+static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->hideleg = val;
+return 0;
+}
+
+static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->hgatp;
+return 0;
+}
+
+static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->hgatp = val;
+return 0;
+}
+
 /* Physical Memory Protection */
 static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -950,6 +1013,11 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Supervisor Protection and Translation */
 [CSR_SATP] ={ smode, read_satp,write_satp},
 
+[CSR_HSTATUS] = { hmode,   read_hstatus, write_hstatus
},
+[CSR_HEDELEG] = { hmode,   read_hedeleg, write_hedeleg
},
+[CSR_HIDELEG] = { hmode,   read_hideleg, write_hideleg
},
+[CSR_HGATP] =   { hmode,   read_hgatp,   write_hgatp  
},
+
 /* Physical Memory Protection */
 [CSR_PMPCFG0  ... CSR_PMPADDR9] =  { pmp,   read_pmpcfg,  write_pmpcfg   },
 [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp,   read_pmpaddr, write_pmpaddr  },
-- 
2.22.0




[Qemu-devel] [PATCH v1 14/28] target/riscv: Generate illegal instruction on WFI when V=1

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index d150551bc9..beb34e705b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -130,9 +130,10 @@ void helper_wfi(CPURISCVState *env)
 {
 CPUState *cs = env_cpu(env);
 
-if (env->priv == PRV_S &&
+if ((env->priv == PRV_S &&
 env->priv_ver >= PRIV_VERSION_1_10_0 &&
-get_field(*env->mstatus, MSTATUS_TW)) {
+get_field(*env->mstatus, MSTATUS_TW)) ||
+riscv_cpu_virt_enabled(env)) {
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
 } else {
 cs->halted = 1;
-- 
2.22.0




[Qemu-devel] [PATCH v1 13/28] target/ricsv: Flush the TLB on virtulisation mode changes

2019-08-23 Thread Alistair Francis
To ensure our TLB isn't out-of-date we flush it on all virt mode
changes. Unlike priv mode this isn't saved in the mmu_idx as all
guests share V=1. The easiest option is just to flush on all changes.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index afb3e8579e..8e8b156fc0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -203,6 +203,11 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 return;
 }
 
+/* Flush the TLB on all virt mode changes. */
+if (((env->virt & VIRT_MODE_MASK) >> VIRT_MODE_SHIFT) != enable) {
+tlb_flush(env_cpu(env));
+}
+
 env->virt &= ~VIRT_MODE_MASK;
 env->virt |= enable << VIRT_MODE_SHIFT;
 }
-- 
2.22.0




[Qemu-devel] [PATCH v1 03/28] target/riscv: Add the force HS exception mode

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_bits.h   |  6 ++
 target/riscv/cpu_helper.c | 23 +++
 3 files changed, 31 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0ef1ecb0e0..3a95c41428 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -261,6 +261,8 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
+bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
+void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1fbde516be..204d9d9a79 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -428,6 +428,12 @@
 #define VIRT_MODE_SHIFT 0
 #define VIRT_MODE_MASK  (1 << VIRT_MODE_SHIFT)
 
+/* HS-level exception modes */
+#define CLEAR_HS_EXCEP0
+#define FORCE_HS_EXCEP1
+#define FORCE_HS_EXCEP_SHIFT  1
+#define FORCE_HS_EXCEP_MASK   (1 << FORCE_HS_EXCEP_SHIFT)
+
 /* RV32 satp CSR field masks */
 #define SATP32_MODE 0x8000
 #define SATP32_ASID 0x7fc0
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7b0bb14c01..5bcfc2e090 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -104,6 +104,29 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 env->virt |= enable << VIRT_MODE_SHIFT;
 }
 
+bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env)
+{
+bool tmp;
+
+if (!riscv_has_ext(env, RVH)) {
+return false;
+}
+
+tmp = (env->virt & FORCE_HS_EXCEP_MASK) >> FORCE_HS_EXCEP_SHIFT;
+
+return tmp == FORCE_HS_EXCEP;
+}
+
+void riscv_cpu_set_force_hs_excep(CPURISCVState *env, bool enable)
+{
+if (!riscv_has_ext(env, RVH)) {
+return;
+}
+
+env->virt &= ~FORCE_HS_EXCEP_MASK;
+env->virt |= enable << FORCE_HS_EXCEP_SHIFT;
+}
+
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
 {
 CPURISCVState *env = >env;
-- 
2.22.0




[Qemu-devel] [PATCH v1 06/28] target/riscv: Print priv and virt in disas log

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index adeddb85f6..8ac72c6470 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -810,7 +810,15 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 
 static void riscv_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
 {
+#ifndef CONFIG_USER_ONLY
+RISCVCPU *rvcpu = RISCV_CPU(cpu);
+CPURISCVState *env = >env;
+#endif
+
 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
+#ifndef CONFIG_USER_ONLY
+qemu_log("Priv: "TARGET_FMT_ld"; Virt: "TARGET_FMT_ld"\n", env->priv, 
env->virt);
+#endif
 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
 }
 
-- 
2.22.0




[Qemu-devel] [PATCH v1 10/28] target/riscv: Convert mie and mstatus to pointers

2019-08-23 Thread Alistair Francis
To handle the new Hypervisor CSR register swapping let's use pointers.

We only need to convert the MIE and MSTATUS CSRs. With the exception of
MIP all of the other CSRs that swap with virtulsation changes are S-Mode
only, so we can just do a lazy switch. This because more challenging for
the M-Mode registers so it ends up being easier to use pointers.

As the MIP CSR is always accessed atomicly the pointer swap doesn't work
so we leave that as is.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c| 16 
 target/riscv/cpu.h| 12 ++--
 target/riscv/cpu_helper.c | 32 
 target/riscv/csr.c| 28 ++--
 target/riscv/op_helper.c  | 14 +++---
 5 files changed, 59 insertions(+), 43 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index be8f643fc2..371d5845af 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -228,7 +228,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc  ", env->pc);
 #ifndef CONFIG_USER_ONLY
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
-qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", *env->mstatus);
 if (riscv_has_ext(env, RVH)) {
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "bstatus ", env->vsstatus);
@@ -239,7 +239,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsip",
  (target_ulong)atomic_read(>vsip));
 }
-qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
+qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", *env->mie);
 if (riscv_has_ext(env, RVH)) {
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsie", env->vsie);
 }
@@ -309,7 +309,7 @@ static bool riscv_cpu_has_work(CPUState *cs)
  * Definition of the WFI instruction requires it to ignore the privilege
  * mode and delegation registers, but respect individual enables
  */
-return (atomic_read(>mip) & env->mie) != 0;
+return (atomic_read(>mip) & *env->mie) != 0;
 #else
 return true;
 #endif
@@ -330,7 +330,7 @@ static void riscv_cpu_reset(CPUState *cs)
 mcc->parent_reset(cs);
 #ifndef CONFIG_USER_ONLY
 env->priv = PRV_M;
-env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
+*env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
 env->mcause = 0;
 env->pc = env->resetvec;
 #endif
@@ -459,8 +459,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 static void riscv_cpu_init(Object *obj)
 {
 RISCVCPU *cpu = RISCV_CPU(obj);
+#ifndef CONFIG_USER_ONLY
+CPURISCVState *env = >env;
+#endif
 
 cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+env->mie = >mie_novirt;
+env->mstatus = >mstatus_novirt;
+#endif
 }
 
 static const VMStateDescription vmstate_riscv_cpu = {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4c342e7a79..680592cb60 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -122,7 +122,7 @@ struct CPURISCVState {
 target_ulong resetvec;
 
 target_ulong mhartid;
-target_ulong mstatus;
+target_ulong *mstatus;
 
 /*
  * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
@@ -136,7 +136,7 @@ struct CPURISCVState {
 uint32_t mip;
 uint32_t miclaim;
 
-target_ulong mie;
+target_ulong *mie;
 target_ulong mideleg;
 
 target_ulong sptbr;  /* until: priv-1.9.1 */
@@ -154,6 +154,14 @@ struct CPURISCVState {
 target_ulong mcause;
 target_ulong mtval;  /* since: priv-1.10.0 */
 
+/* The following registers are the "real" versions that the pointer
+ * versions point to. These should never be used unless you know what you
+ * are doing. To access these use the pointer versions instead. This is
+ * required to handle the Hypervisor register swapping.
+ */
+target_ulong mie_novirt;
+target_ulong mstatus_novirt;
+
 /* Hypervisor CSRs */
 target_ulong hstatus;
 target_ulong hedeleg;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5bcfc2e090..c597523d74 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -36,9 +36,9 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
-target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
-target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
-target_ulong pending = atomic_read(>mip) & env->mie;
+target_ulong mstatus_mie = get_field(*env->mstatus, MSTATUS_MIE);
+target_ulong mstatus_sie = get_field(*env->mstatus, MSTATUS_SIE);
+target_ulong pending = 

[Qemu-devel] [PATCH v1 05/28] target/riscv: Add the Hypervisor CSRs to CPUState

2019-08-23 Thread Alistair Francis
As the MIP CSR is 32-bits to allow atomic_read on 32-bit hosts the vsip
is 32-bit as well.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3a95c41428..4c342e7a79 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -154,6 +154,23 @@ struct CPURISCVState {
 target_ulong mcause;
 target_ulong mtval;  /* since: priv-1.10.0 */
 
+/* Hypervisor CSRs */
+target_ulong hstatus;
+target_ulong hedeleg;
+target_ulong hideleg;
+target_ulong hgatp;
+
+/* Virtual CSRs */
+target_ulong vsstatus;
+uint32_t vsip;
+target_ulong vsie;
+target_ulong vstvec;
+target_ulong vsscratch;
+target_ulong vsepc;
+target_ulong vscause;
+target_ulong vstval;
+target_ulong vsatp;
+
 target_ulong scounteren;
 target_ulong mcounteren;
 
-- 
2.22.0




[Qemu-devel] [PATCH v1 00/28] Add RISC-V Hypervisor Extension v0.4

2019-08-23 Thread Alistair Francis


This patch series adds the RISC-V Hypervisor extension v0.4. This is the
latest draft spec of the Hypervisor extension.

The Hypervisor extension is disabled by default, so this series should
result in no changes to anyone using QEMU unless they enable the
extension. The extention can be enabled with the -cpu property (see
below).

At the moment the spec does not include information about the mstatush
register. Although this information has since been merged into the
master spec. As it is only adding support for 32-bit I have added this
register to this series.

Testing of this implementation has been done by using the baremetal
Xvisor Hypervisor. We are able to run two Linux guests (that's all I
have tried) as guests in 64-bit. In 32-bit so far I can only run
baremetal guests, but I think this is a baremetal boot loader issue and
not an issue in QEMU.

The RISC-V KVM implementation was also written using these patches. The
KVM implementation is currently under review.

These patches result in a reproducable race when booting a SMP Linux
guest inside a SMP Linux KVM host. This will need to be fixed.

At the moment this spec is in a draft state and is subject to change. As
QEMU is extreamly useful in early bring up I think it makes sense for
QEMU to support non-frozen extensions.

Thanks to Anup for doing the initial port of Xvisor. The port is avaliable here:
https://github.com/avpatel/xvisor-next and will run on QEMU.

Also thanks to Atish for implementing the SBI call support in Xvisor and
for lots of help debugging.

To run this yourself:
 1. Apply this patch series to QEMU. The latest branch can be found here:
  
https://github.com/alistair23/qemu/tree/mainline/alistair/riscv-hyp-ext-v0.4.next
 2. Get the version of OpenSBI that supports the H extension. This can
be found here:
  https://github.com/riscv/opensbi/tree/hyp_ext_changes_v1
 3. Build the next release of Xvisor. It is available here:
  https://github.com/avpatel/xvisor-next
 4. Make sure you build the Xvisor tests, see here for details:
  
https://github.com/avpatel/xvisor-next/tree/master/tests/riscv/virt64/linux
 5. Run QEMU:
 ./riscv64-softmmu/qemu-system-riscv64 -nographic \
   -machine virt -cpu rv64,x-h=true\
   -serial mon:stdio -serial null -m 4G \
   -device loader,file=vmm.bin,addr=0x8020 \
   -kernel fw_jump.elf \
   -initrd vmm-disk-linux.img \
   -append "vmm.console=uart@1000 vmm.bootcmd=\"vfs mount initrd /;vfs 
run /boot.xscript;vfs cat /system/banner.txt\""

   Once you get to the prompt you can start the geust by running:
 guest kick guest0
   You can then bind to the serial port using:
 vserial bind guest0/uart0
   Then you can start Linux using:
 autoexec

 This was all tested with the mainline 5.2/5.3 kernels.

There is very early work on a Xen port as well which is avaliable here:
https://github.com/alistair23/xen/tree/alistair/riscv-port

ToDo/Issues
 - Get 32-bit fully working
 - Fix KVM SMP race condition

Based-on: cover.1566573576.git.alistair.fran...@wdc.com



Alistair Francis (28):
  target/riscv: Add the Hypervisor extension
  target/riscv: Add the virtulisation mode
  target/riscv: Add the force HS exception mode
  target/riscv: Fix CSR perm checking for HS mode
  target/riscv: Add the Hypervisor CSRs to CPUState
  target/riscv: Print priv and virt in disas log
  target/riscv: Dump Hypervisor registers if enabled
  target/riscv: Add Hypervisor CSR access functions
  target/riscv: Add Hypervisor virtual CSRs accesses
  target/riscv: Convert mie and mstatus to pointers
  target/riscv: Add background register swapping function
  target/riscv: Add support for virtual interrupt setting
  target/ricsv: Flush the TLB on virtulisation mode changes
  target/riscv: Generate illegal instruction on WFI when V=1
  riscv: plic: Always set sip.SEIP bit for HS
  target/riscv: Add hypvervisor trap support
  target/riscv: Add Hypervisor trap return support
  target/riscv: Add hfence instructions
  target/riscv: Disable guest FP support based on virtual status
  target/riscv: Mark both sstatus and vsstatus as dirty
  target/riscv: Respect MPRV and SPRV for floating point ops
  target/riscv: Allow specifying MMU stage
  target/riscv: Allow specifying number of MMU stages
  target/riscv: Implement second stage MMU
  target/riscv: Call the second stage MMU in virtualisation mode
  target/riscv: Add support for the 32-bit MSTATUSH CSR
  target/riscv: Add the MSTATUS_MPV_ISSET helper macro
  target/riscv: Allow enabling the Hypervisor extension

 hw/riscv/sifive_plic.c|  12 +-
 target/riscv/cpu.c|  61 ++-
 target/riscv/cpu.h|  68 ++-
 target/riscv/cpu_bits.h   |  48 +-
 target/riscv/cpu_helper.c | 485 --
 target/riscv/csr.c| 252 -
 target/riscv/insn32.decode|  23 +-
 

[Qemu-devel] [PATCH v1 11/28] target/riscv: Add background register swapping function

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h| 24 ---
 target/riscv/cpu_bits.h   |  7 
 target/riscv/cpu_helper.c | 88 +++
 3 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 680592cb60..05957f32a8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -125,15 +125,18 @@ struct CPURISCVState {
 target_ulong *mstatus;
 
 /*
- * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads. It should be read with atomic_read. It should be updated
- * using riscv_cpu_update_mip with the iothread mutex held. The iothread
- * mutex must be held because mip must be consistent with the CPU inturrept
- * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
- * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
+ * CAUTION! Unlike the rest of this struct, mip and mip_novirt is accessed
+ * asynchonously by I/O threads. It should be read with atomic_read. It 
should
+ * be updated using riscv_cpu_update_mip with the iothread mutex held. The
+ * iothread mutex must be held because mip must be consistent with the CPU
+ * inturrept state. riscv_cpu_update_mip calls cpu_interrupt or
+ * cpu_reset_interrupt wuth the invariant that CPU_INTERRUPT_HARD is set if
+ * mip is non-zero.
  * mip is 32-bits to allow atomic_read on 32-bit hosts.
  */
 uint32_t mip;
+uint32_t mip_novirt;
+
 uint32_t miclaim;
 
 target_ulong *mie;
@@ -179,6 +182,14 @@ struct CPURISCVState {
 target_ulong vstval;
 target_ulong vsatp;
 
+/* HS Backup CSRs */
+target_ulong stvec_hs;
+target_ulong sscratch_hs;
+target_ulong sepc_hs;
+target_ulong scause_hs;
+target_ulong stval_hs;
+target_ulong satp_hs;
+
 target_ulong scounteren;
 target_ulong mcounteren;
 
@@ -306,6 +317,7 @@ void riscv_cpu_list(void);
 #define cpu_mmu_index riscv_cpu_mmu_index
 
 #ifndef CONFIG_USER_ONLY
+void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
 uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 78067901a2..5cee72b726 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -556,4 +556,11 @@
 #define SIP_STIP   MIP_STIP
 #define SIP_SEIP   MIP_SEIP
 
+/* MIE masks */
+#define MIE_SEIE   (1 << IRQ_S_EXT)
+#define MIE_UEIE   (1 << IRQ_U_EXT)
+#define MIE_STIE   (1 << IRQ_S_TIMER)
+#define MIE_UTIE   (1 << IRQ_U_TIMER)
+#define MIE_SSIE   (1 << IRQ_S_SOFT)
+#define MIE_USIE   (1 << IRQ_U_SOFT)
 #endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c597523d74..41d4368128 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -81,6 +81,94 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 return false;
 }
 
+void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
+{
+RISCVCPU *cpu = RISCV_CPU(env_cpu(env));
+uint32_t tmp;
+target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
+MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
+target_ulong sie_mask = MIE_SEIE | MIE_STIE | MIE_SSIE |
+MIE_UEIE | MIE_UTIE | MIE_USIE;
+target_ulong mip_mask = MIP_SSIP | MIP_STIP | MIP_SEIP;
+bool current_virt = riscv_cpu_virt_enabled(env);
+
+g_assert(riscv_has_ext(env, RVH));
+
+#if defined(TARGET_RISCV64)
+mstatus_mask |= MSTATUS64_UXL;
+#endif
+
+if (current_virt) {
+/* Current V=1 and we are about to change to V=0 */
+env->mstatus = >mstatus_novirt;
+*env->mstatus &= mstatus_mask;
+*env->mstatus |= env->vsstatus & ~mstatus_mask;
+/* Ensure that vsstatus only holds the correct bits */
+env->vsstatus &= mstatus_mask;
+
+env->mie = >mie_novirt;
+*env->mie &= sie_mask;
+*env->mie |= env->vsie & ~sie_mask;
+/* Ensure that vsie only holds the correct bits */
+env->vsie &= sie_mask;
+
+env->vstvec = env->stvec;
+env->stvec = env->stvec_hs;
+
+env->vsscratch = env->sscratch;
+env->sscratch = env->sscratch_hs;
+
+env->vsepc = env->sepc;
+env->sepc = env->sepc_hs;
+
+env->vscause = env->scause;
+env->scause = env->scause_hs;
+
+env->vstval = env->sbadaddr;
+env->sbadaddr = env->stval_hs;
+
+env->vsatp = env->satp;
+env->satp = env->satp_hs;
+
+tmp = (uint32_t)atomic_read(>mip_novirt);
+tmp = 

[Qemu-devel] [PATCH v1 12/28] target/riscv: Add support for virtual interrupt setting

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 41d4368128..afb3e8579e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -38,12 +38,27 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
 target_ulong mstatus_mie = get_field(*env->mstatus, MSTATUS_MIE);
 target_ulong mstatus_sie = get_field(*env->mstatus, MSTATUS_SIE);
-target_ulong pending = atomic_read(env->mip) & *env->mie;
-target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
-target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
+target_ulong vsstatus_sie = get_field(env->mstatus_novirt, MSTATUS_SIE);
+
+target_ulong pending = atomic_read(>mip) & *env->mie;
+target_ulong hspending = atomic_read(>mip_novirt) & env->mie_novirt;
+
+target_ulong mie  = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
+target_ulong sie  = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
+target_ulong vsie = env->priv < PRV_S || (env->priv == PRV_S && 
vsstatus_sie);
+
 target_ulong irqs = (pending & ~env->mideleg & -mie) |
 (pending &  env->mideleg & -sie);
 
+if (riscv_cpu_virt_enabled(env)) {
+target_ulong pending_hs_irq = hspending & -vsie;
+
+if (pending_hs_irq) {
+riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP);
+return ctz64(pending_hs_irq);
+}
+}
+
 if (irqs) {
 return ctz64(irqs); /* since non-zero */
 } else {
-- 
2.22.0




[Qemu-devel] [PATCH v1 04/28] target/riscv: Fix CSR perm checking for HS mode

2019-08-23 Thread Alistair Francis
Update the CSR permission checking to work correctly when we are in
HS-mode.

Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f767ad24be..471f23a1d0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -799,9 +799,15 @@ int riscv_csrrw(CPURISCVState *env, int csrno, 
target_ulong *ret_value,
 
 /* check privileges and return -1 if check fails */
 #if !defined(CONFIG_USER_ONLY)
-int csr_priv = get_field(csrno, 0x300);
+int csr_priv = env->priv;
 int read_only = get_field(csrno, 0xC00) == 3;
-if ((write_mask && read_only) || (env->priv < csr_priv)) {
+
+if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
+/* Plus 1 as we are in HS mode */
+csr_priv++;
+}
+
+if ((write_mask && read_only) || (csr_priv < get_field(csrno, 0x300))) {
 return -1;
 }
 #endif
-- 
2.22.0




[Qemu-devel] [PATCH v1 02/28] target/riscv: Add the virtulisation mode

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  4 
 target/riscv/cpu_bits.h   |  6 ++
 target/riscv/cpu_helper.c | 23 +++
 3 files changed, 33 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7f54fb8c87..0ef1ecb0e0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -117,6 +117,8 @@ struct CPURISCVState {
 
 #ifndef CONFIG_USER_ONLY
 target_ulong priv;
+/* This contains QEMU specific information about the virt state. */
+target_ulong virt;
 target_ulong resetvec;
 
 target_ulong mhartid;
@@ -257,6 +259,8 @@ int riscv_cpu_gdb_read_register(CPUState *cpu, uint8_t 
*buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
+bool riscv_cpu_virt_enabled(CPURISCVState *env);
+void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e99834856c..1fbde516be 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -422,6 +422,12 @@
 #define PRV_H 2 /* Reserved */
 #define PRV_M 3
 
+/* Virtulisation modes */
+#define VIRT_OFF0
+#define VIRT_ON 1
+#define VIRT_MODE_SHIFT 0
+#define VIRT_MODE_MASK  (1 << VIRT_MODE_SHIFT)
+
 /* RV32 satp CSR field masks */
 #define SATP32_MODE 0x8000
 #define SATP32_ASID 0x7fc0
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 225e407cff..7b0bb14c01 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -81,6 +81,29 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 return false;
 }
 
+bool riscv_cpu_virt_enabled(CPURISCVState *env)
+{
+bool tmp;
+
+if (!riscv_has_ext(env, RVH)) {
+return false;
+}
+
+tmp = (env->virt & VIRT_MODE_MASK) >> VIRT_MODE_SHIFT;
+
+return tmp == VIRT_ON;
+}
+
+void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
+{
+if (!riscv_has_ext(env, RVH)) {
+return;
+}
+
+env->virt &= ~VIRT_MODE_MASK;
+env->virt |= enable << VIRT_MODE_SHIFT;
+}
+
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
 {
 CPURISCVState *env = >env;
-- 
2.22.0




[Qemu-devel] [PATCH v1 01/28] target/riscv: Add the Hypervisor extension

2019-08-23 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 124ed33ee4..7f54fb8c87 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -67,6 +67,7 @@
 #define RVC RV('C')
 #define RVS RV('S')
 #define RVU RV('U')
+#define RVH RV('H')
 
 /* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
-- 
2.22.0




Re: [Qemu-devel] [PATCH v3] RISC-V: Select FPU gdb xml file based on the supported extensions

2019-08-23 Thread Jim Wilson

On 8/21/19 9:28 AM, Georg Kotheimer wrote:

The size of the FPU registers depends solely on the floating point
extensions supported by the target architecture.
However, in the previous implementation the floating point register
size was derived from whether the target architecture is 32-bit or
64-bit.

To allow RVF without RVD, changes to riscv_gdb_get_fpu() and
riscv_gdb_set_fpu() were necessary.


Reviewed-by: Jim Wilson 

Jim



Re: [Qemu-devel] [PATCH v9 17/20] cpu: TLB_FLAGS_MASK bit to force memory slow path

2019-08-23 Thread Richard Henderson
On 8/23/19 11:36 AM, Tony Nguyen wrote:
> The fast path is taken when TLB_FLAGS_MASK is all zero.
> 
> TLB_FORCE_SLOW is simply a TLB_FLAGS_MASK bit to force the slow path,
> there are no other side effects.
> 
> Signed-off-by: Tony Nguyen 
> Reviewed-by: Richard Henderson 
> ---
>  include/exec/cpu-all.h | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)

FYI, while looking at this again, we do not need a new bit.  You can simply set
TLB_MMIO for this use case, like we do for ROM.

This seems to be the only change to be made for this patch set; I can fix this
up myself while queuing.


r~



[Qemu-devel] [PATCH] configure: more resilient Python version capture

2019-08-23 Thread Cleber Rosa
The current approach to capture the Python version is fragile, as it
was demonstrated by a very specific build of Python 3 on Fedora 29
that, under non-interactive shells would print multiline version
information.

The (badly) stripped version output would be sent to config-host.mak,
producing bad syntax and rendering the makefiles unusable.  Now, the
Python versions is printed by configure, but only a simple (and better
controlled variable) indicating whether the build system is using
Python 2 is kept on config-host.mak.

Signed-off-by: Cleber Rosa 
---
 configure  | 5 +++--
 tests/Makefile.include | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index e44e454c43..90b29037ab 100755
--- a/configure
+++ b/configure
@@ -1864,7 +1864,7 @@ if ! $python -c 'import sys; sys.exit(sys.version_info < 
(2,7))'; then
 fi
 
 # Preserve python version since some functionality is dependent on it
-python_version=$($python -V 2>&1 | sed -e 's/Python\ //')
+python_version=$(python2 -c 'import sys; print("%d.%d.%d" % 
(sys.version_info[0], sys.version_info[1], sys.version_info[2]))' 2>/dev/null)
 
 # Suppress writing compiled files
 python="$python -B"
@@ -6511,6 +6511,7 @@ if ! $python -c 'import sys; sys.exit(sys.version_info < 
(3,0))'; then
   echo
   echo "warning: Python 2 support is deprecated" >&2
   echo "warning: Python 3 will be required for building future versions of 
QEMU" >&2
+  python2="y"
 fi
 
 config_host_mak="config-host.mak"
@@ -7333,7 +7334,7 @@ echo "INSTALL_DATA=$install -c -m 0644" >> 
$config_host_mak
 echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
 echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
 echo "PYTHON=$python" >> $config_host_mak
-echo "PYTHON_VERSION=$python_version" >> $config_host_mak
+echo "PYTHON2=$python2" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 if $iasl -h > /dev/null 2>&1; then
   echo "IASL=$iasl" >> $config_host_mak
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 49684fd4f4..f5ac09549c 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -1135,7 +1135,7 @@ TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
 AVOCADO_SHOW=app
 AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter 
%-softmmu,$(TARGET_DIRS)))
 
-ifneq ($(findstring v2,"v$(PYTHON_VERSION)"),v2)
+ifneq ($(PYTHON2),y)
 $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
$(call quiet-command, \
 $(PYTHON) -m venv --system-site-packages $@, \
-- 
2.21.0




Re: [Qemu-devel] [PATCH 0/4] docs: add docs about use of automatic cleanup functions

2019-08-23 Thread Marc-André Lureau
Hi

On Fri, Aug 23, 2019 at 8:41 PM Daniel P. Berrangé  wrote:
>
> This is ostensibly about adding docs for the g_autofree/g_autoptr
> macros. As part of doing that, however, the existing HACKING doc
> is merged into the CODING_STYLE doc and the text is converted to
> markdown with a table of contents.

Why not rst, so it can integrate with the rest of qemu sphinx doc?

(markdown is quite poor when it comes to documenting code or
cross-referencing etc)



>
> Daniel P. Berrangé (4):
>   docs: convert CODING_STYLE and HACKING to markdown syntax
>   docs: merge HACKING.md contents into CODING_STYLE.md
>   docs: document use of automatic cleanup functions in glib
>   docs: add table of contents to CODING_STYLE.md
>
>  CODING_STYLE| 216 -
>  CODING_STYLE.md | 613 
>  HACKING | 257 
>  README  |   2 +-
>  4 files changed, 614 insertions(+), 474 deletions(-)
>  delete mode 100644 CODING_STYLE
>  create mode 100644 CODING_STYLE.md
>  delete mode 100644 HACKING
>
> --
> 2.21.0
>
>


-- 
Marc-André Lureau



Re: [Qemu-devel] [Libguestfs] [nbdkit PATCH 3/3] plugins: Add .can_fast_zero hook

2019-08-23 Thread Eric Blake
On 8/23/19 9:40 AM, Eric Blake wrote:
> Allow plugins to affect the handling of the new NBD_CMD_FLAG_FAST_ZERO
> flag, then update affected plugins.  In particular, in-memory plugins
> are always fast; the full plugin is better served by omitting .zero
> and relying on .pwrite fallback; nbd takes advantage of libnbd
> extensions proposed in parallel to pass through support; and
> v2 language bindings expose the choice to their scripts.
> 

> +++ b/server/plugins.c
> @@ -404,11 +404,25 @@ plugin_can_zero (struct backend *b, struct connection 
> *conn)
>  static int
>  plugin_can_fast_zero (struct backend *b, struct connection *conn)
>  {
> +  struct backend_plugin *p = container_of (b, struct backend_plugin, 
> backend);
> +  int r;
> +
>assert (connection_get_handle (conn, 0));
> 
>debug ("can_fast_zero");
> 
> -  return 0; /* Upcoming patch will actually add support. */
> +  if (p->plugin.can_fast_zero)
> +return p->plugin.can_fast_zero (connection_get_handle (conn, 0));
> +  /* Advertise support for fast zeroes if no .zero or .can_zero is
> +   * false: in those cases, we fail fast instead of using .pwrite.
> +   * This also works when v1 plugin has only ._zero_old.
> +   */
> +  if (p->plugin.zero == NULL)
> +return 1;
> +  r = plugin_can_zero (b, conn);
> +  if (r == -1)
> +return -1;
> +  return !r;
>  }
> 

Needs this squashed in for libnbd to pass rather than skip its new
'can-fast-zero-flag' test:


diff --git i/server/plugins.c w/server/plugins.c
index 84329cf4..695a77ab 100644
--- i/server/plugins.c
+++ w/server/plugins.c
@@ -208,6 +208,7 @@ plugin_dump_fields (struct backend *b)
   HAS (can_cache);
   HAS (cache);
   HAS (thread_model);
+  HAS (can_fast_zero);
 #undef HAS

   /* Custom fields. */


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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v5 0/4] virtio/block: handle zoned backing devices

2019-08-23 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190823194927.23278-1-dmitry.fomic...@wdc.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH v5 0/4] virtio/block: handle zoned backing devices
Message-id: 20190823194927.23278-1-dmitry.fomic...@wdc.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20190823194927.23278-1-dmitry.fomic...@wdc.com -> 
patchew/20190823194927.23278-1-dmitry.fomic...@wdc.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for 
path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) 
registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 
'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 
'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 
'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered 
for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) 
registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for 
path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) 
registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for 
path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) 
registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for 
path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for 
path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for 
path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) 
registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 
'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' 
(https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 
'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' 
(https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 
'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out 
'22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 
'90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 
'7bfe584e321946771692711ff83ad2b5850daca7'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out 
'20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) 
registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' 
(https://github.com/openssl/openssl) registered for path 
'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': 
checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out 
'50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered 
for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) 
registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': 
checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked 
out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 
'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography': checked out 
'09403100de2f6f1cdd0d484dcb8e620f1c335c8f'
Cloning into 

Re: [Qemu-devel] [RFC PATCH 17/17] build: Correct non-common common-obj-* to obj-*

2019-08-23 Thread Paolo Bonzini
Thanks for splitting this.  The good news is that most of these devices
actually need _not_ be target-endian.  Comments are inline.

Paolo

On 23/08/19 20:56, Tony Nguyen wrote:
> diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
> index 63db383709..13133b412d 100644
> --- a/hw/audio/Makefile.objs
> +++ b/hw/audio/Makefile.objs
> @@ -5,7 +5,8 @@ common-obj-$(CONFIG_AC97) += ac97.o
>  common-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o
>  common-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o
>  common-obj-$(CONFIG_CS4231A) += cs4231a.o
> -common-obj-$(CONFIG_HDA) += intel-hda.o hda-codec.o
> +common-obj-$(CONFIG_HDA) += hda-codec.o
> +obj-$(CONFIG_HDA) += intel-hda.o

These are certainly little endian, since they are PCI devices.

>  common-obj-$(CONFIG_PCSPK) += pcspk.o
>  common-obj-$(CONFIG_WM8750) += wm8750.o
> diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
> index f5f643f0cc..04ed4d7722 100644
> --- a/hw/block/Makefile.objs
> +++ b/hw/block/Makefile.objs
> @@ -1,9 +1,9 @@
>  common-obj-y += block.o cdrom.o hd-geometry.o
> -common-obj-$(CONFIG_FDC) += fdc.o
> +obj-$(CONFIG_FDC) += fdc.o

fdctrl_mem_ops and sysbus_fdc_info are not used AFAICT and
fdctrl_mem_strict_ops is min/max size=1 so it can be made host-endian.

>  common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
>  common-obj-$(CONFIG_NAND) += nand.o
> -common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
> -common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
> +obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
> +obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
>  common-obj-$(CONFIG_XEN) += xen-block.o
>  common-obj-$(CONFIG_ECC) += ecc.o
>  common-obj-$(CONFIG_ONENAND) += onenand.o
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 02d8a66925..215c02b752 100644
> --- a/hw/char/Makefile.objs
> +++ b/hw/char/Makefile.objs
> @@ -1,7 +1,6 @@
>  common-obj-$(CONFIG_IPACK) += ipoctal232.o
>  common-obj-$(CONFIG_ESCC) += escc.o
>  common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o
> -common-obj-$(CONFIG_PARALLEL) += parallel.o
>  common-obj-$(CONFIG_ISA_BUS) += parallel-isa.o
>  common-obj-$(CONFIG_PL011) += pl011.o
>  common-obj-$(CONFIG_SERIAL) += serial.o
> @@ -9,7 +8,6 @@ common-obj-$(CONFIG_SERIAL_ISA) += serial-isa.o
>  common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
>  common-obj-$(CONFIG_SERIAL_PCI_MULTI) += serial-pci-multi.o
>  common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
> -common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
>  common-obj-$(CONFIG_XEN) += xen_console.o
>  common-obj-$(CONFIG_CADENCE) += cadence_uart.o
>  
> @@ -21,6 +19,8 @@ obj-$(CONFIG_PSERIES) += spapr_vty.o
>  obj-$(CONFIG_DIGIC) += digic-uart.o
>  obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
>  obj-$(CONFIG_RASPI) += bcm2835_aux.o
> +obj-$(CONFIG_PARALLEL) += parallel.o
> +obj-$(CONFIG_XILINX) += xilinx_uartlite.o
>  
>  common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
>  common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index b49f880a0c..6ee184a6c4 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -9,7 +9,7 @@ common-obj-y += hotplug.o
>  common-obj-$(CONFIG_SOFTMMU) += nmi.o
>  common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
>  
> -common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
> +obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o

Bit bucket, just make it host endian.

>  common-obj-$(CONFIG_XILINX_AXI) += stream.o
>  common-obj-$(CONFIG_PTIMER) += ptimer.o
>  common-obj-$(CONFIG_SOFTMMU) += sysbus.o
> diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
> index a64998fc7b..facc1d4448 100644
> --- a/hw/display/Makefile.objs
> +++ b/hw/display/Makefile.objs
> @@ -8,7 +8,7 @@ common-obj-$(CONFIG_ADS7846) += ads7846.o
>  common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
>  common-obj-$(call 
> land,$(CONFIG_VGA_CIRRUS),$(CONFIG_VGA_ISA))+=cirrus_vga_isa.o
>  common-obj-$(CONFIG_G364FB) += g364fb.o
> -common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
> +obj-$(CONFIG_JAZZ_LED) += jazz_led.o

min/max size is 1, make it host endian.

>  common-obj-$(CONFIG_PL110) += pl110.o
>  common-obj-$(CONFIG_SII9022) += sii9022.o
>  common-obj-$(CONFIG_SSD0303) += ssd0303.o
> @@ -17,12 +17,12 @@ common-obj-$(CONFIG_XEN) += xenfb.o
>  
>  common-obj-$(CONFIG_VGA_PCI) += vga-pci.o
>  common-obj-$(CONFIG_VGA_ISA) += vga-isa.o
> -common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
> +obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
>  common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
>  common-obj-$(CONFIG_BOCHS_DISPLAY) += bochs-display.o
>  
>  common-obj-$(CONFIG_BLIZZARD) += blizzard.o
> -common-obj-$(CONFIG_EXYNOS4) += exynos4210_fimd.o
> +obj-$(CONFIG_EXYNOS4) += exynos4210_fimd.o

ARM-only, can be little endian.

>  common-obj-$(CONFIG_FRAMEBUFFER) += framebuffer.o
>  obj-$(CONFIG_MILKYMIST) += milkymist-vgafb.o
>  common-obj-$(CONFIG_ZAURUS) += tc6393xb.o
> diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
> index b672e7a522..5b45c8b9a3 100644
> --- 

Re: [Qemu-devel] [PATCH 3/4] docs: document use of automatic cleanup functions in glib

2019-08-23 Thread Eric Blake
On 8/23/19 11:39 AM, Daniel P. Berrangé wrote:
> Document the use of g_autofree and g_autoptr in glib for automatic
> freeing of memory, or other resource cleanup (eg mutex unlocking).
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  CODING_STYLE.md | 101 
>  1 file changed, 101 insertions(+)


> +The cleanup functions are not restricted to simply free'ing memory. The
> +GMutexLocker class is a variant of GMutex that has automatic locking and
> +unlocking at start and end of the enclosing scope
> +
> +In the following example, the `lock` in `MyObj` will be held for the
> +precise duration of the `somefunc` function
> +
> +typedef struct {
> +GMutex lock;
> +} MyObj;
> +
> +char *somefunc(MyObj *obj) {
> +g_autofree GMutexLocker *locker = g_mutex_locker_new(>lock)

Wrong example (you don't want to call g_free, and you missed ';'). This
should be

g_autoptr (GMutexLocker) locker = g_mutex_locker_new(>lock);

With that fixed,

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 3/4] block/ide/scsi: Set BLK_PERM_SUPPORT_ZONED

2019-08-23 Thread Dmitry Fomichev
Added a new boolean argument to blkconf_apply_backend_options()
to let the common block code know whether the chosen block
backend can handle zoned block devices or not.

blkconf_apply_backend_options() then sets BLK_PERM_SUPPORT_ZONED
permission accordingly. The raw code can then use this permission
to allow or deny opening a zone device by a particular block driver.

Signed-off-by: Dmitry Fomichev 
Acked-by: Paul Durrant 
---
 hw/block/block.c |  8 ++--
 hw/block/fdc.c   |  5 +++--
 hw/block/nvme.c  |  2 +-
 hw/block/virtio-blk.c|  2 +-
 hw/block/xen-block.c |  2 +-
 hw/ide/qdev.c|  2 +-
 hw/scsi/scsi-disk.c  | 13 +++--
 hw/scsi/scsi-generic.c   |  2 +-
 hw/usb/dev-storage.c |  2 +-
 include/hw/block/block.h |  3 ++-
 10 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/hw/block/block.c b/hw/block/block.c
index bf56c7612b..23fbe4d567 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -86,7 +86,8 @@ void blkconf_blocksizes(BlockConf *conf)
 }
 
 bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
-   bool resizable, Error **errp)
+   bool resizable, bool zoned_support,
+   Error **errp)
 {
 BlockBackend *blk = conf->blk;
 BlockdevOnError rerror, werror;
@@ -98,9 +99,12 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool 
readonly,
 if (!readonly) {
 perm |= BLK_PERM_WRITE;
 }
+if (zoned_support) {
+perm |= BLK_PERM_SUPPORT_ZONED;
+}
 
 shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
-  BLK_PERM_GRAPH_MOD;
+  BLK_PERM_GRAPH_MOD | BLK_PERM_SUPPORT_ZONED;
 if (resizable) {
 shared_perm |= BLK_PERM_RESIZE;
 }
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index ac5d31e8c1..c5f41b3eb6 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -477,7 +477,7 @@ static void fd_change_cb(void *opaque, bool load, Error 
**errp)
 } else {
 if (!blkconf_apply_backend_options(drive->conf,
blk_is_read_only(drive->blk), false,
-   errp)) {
+   false, errp)) {
 return;
 }
 }
@@ -569,7 +569,8 @@ static void floppy_drive_realize(DeviceState *qdev, Error 
**errp)
 dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
 
-if (!blkconf_apply_backend_options(>conf, read_only, false, errp)) {
+if (!blkconf_apply_backend_options(>conf, read_only, false, false,
+  errp)) {
 return;
 }
 
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 12d8254250..07f08d0768 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1334,7 +1334,7 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
 }
 blkconf_blocksizes(>conf);
 if (!blkconf_apply_backend_options(>conf, blk_is_read_only(n->conf.blk),
-   false, errp)) {
+   false, false, errp)) {
 return;
 }
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 18851601cb..8be62903e2 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1127,7 +1127,7 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 
 if (!blkconf_apply_backend_options(>conf,
blk_is_read_only(conf->conf.blk), true,
-   errp)) {
+   false, errp)) {
 return;
 }
 s->original_wce = blk_enable_write_cache(conf->conf.blk);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index f77343db60..57fe970908 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -229,7 +229,7 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 }
 
 if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY,
-   true, errp)) {
+   true, false, errp)) {
 return;
 }
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6fba6b62b8..a57a8f1a8f 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -200,7 +200,7 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind 
kind, Error **errp)
 }
 }
 if (!blkconf_apply_backend_options(>conf, kind == IDE_CD,
-   kind != IDE_CD, errp)) {
+   kind != IDE_CD, false, errp)) {
 return;
 }
 
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 915641a0f1..8a57caafd7 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2318,7 +2318,7 @@ static void scsi_disk_unit_attention_reported(SCSIDevice 
*dev)
 }
 }
 
-static void scsi_realize(SCSIDevice 

Re: [Qemu-devel] [PATCH v4 0/4] virtio/block: handle zoned backing devices

2019-08-23 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190823192226.21154-1-dmitry.fomic...@wdc.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH v4 0/4] virtio/block: handle zoned backing devices
Message-id: 20190823192226.21154-1-dmitry.fomic...@wdc.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20190823192226.21154-1-dmitry.fomic...@wdc.com -> 
patchew/20190823192226.21154-1-dmitry.fomic...@wdc.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for 
path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) 
registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 
'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 
'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 
'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered 
for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) 
registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for 
path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) 
registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for 
path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) 
registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for 
path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for 
path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for 
path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) 
registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 
'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' 
(https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 
'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' 
(https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 
'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out 
'22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 
'90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 
'7bfe584e321946771692711ff83ad2b5850daca7'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out 
'20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) 
registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' 
(https://github.com/openssl/openssl) registered for path 
'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': 
checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out 
'50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered 
for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) 
registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': 
checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked 
out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 
'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography': checked out 
'09403100de2f6f1cdd0d484dcb8e620f1c335c8f'
Cloning into 

[Qemu-devel] [PATCH v5 2/4] raw: Recognize zoned backing devices

2019-08-23 Thread Dmitry Fomichev
The purpose of this patch is to recognize a zoned block device (ZBD)
when it is opened as a raw file. The new code initializes the zoned
model propery introduced by the previous commit.

This commit is Linux-specific as it gets the Zoned Block Device Model
value (none/host-managed/host-aware) from sysfs on the host.

In order to avoid code duplication in file-posix.c, a common helper
function is added to read values of sysfs entries under
/sys/block//queue. This way, the existing function that reads
the value of "max_segments" entry and the the new function that reads
"zoned" value both share the same helper code.

Signed-off-by: Dmitry Fomichev 
---
 block/file-posix.c | 74 ++
 block/raw-format.c |  8 +
 2 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index fbeb0068db..d9f2fc5e46 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1067,15 +1067,13 @@ static int sg_get_max_transfer_length(int fd)
 #endif
 }
 
-static int sg_get_max_segments(int fd)
+static int hdev_read_blk_queue_entry(int fd, const char *key,
+char *buf, int buf_len)
 {
 #ifdef CONFIG_LINUX
-char buf[32];
-const char *end;
 char *sysfspath = NULL;
 int ret;
 int sysfd = -1;
-long max_segments;
 struct stat st;
 
 if (fstat(fd, )) {
@@ -1083,23 +1081,45 @@ static int sg_get_max_segments(int fd)
 goto out;
 }
 
-sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-major(st.st_rdev), minor(st.st_rdev));
+sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
+major(st.st_rdev), minor(st.st_rdev), key);
 sysfd = open(sysfspath, O_RDONLY);
 if (sysfd == -1) {
 ret = -errno;
 goto out;
 }
 do {
-ret = read(sysfd, buf, sizeof(buf) - 1);
+ret = read(sysfd, buf, buf_len - 1);
 } while (ret == -1 && errno == EINTR);
 if (ret < 0) {
 ret = -errno;
-goto out;
 } else if (ret == 0) {
 ret = -EIO;
+}
+out:
+if (sysfd != -1) {
+close(sysfd);
+}
+g_free(sysfspath);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int sg_get_max_segments(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+const char *end;
+int ret;
+long max_segments;
+
+ret = hdev_read_blk_queue_entry(fd, "max_segments", buf, sizeof(buf));
+if (ret < 0) {
 goto out;
 }
+
 buf[ret] = 0;
 /* The file is ended with '\n', pass 'end' to accept that. */
 ret = qemu_strtol(buf, , 10, _segments);
@@ -1108,10 +1128,33 @@ static int sg_get_max_segments(int fd)
 }
 
 out:
-if (sysfd != -1) {
-close(sysfd);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int hdev_get_zoned_model(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+int ret;
+
+ret = hdev_read_blk_queue_entry(fd, "zoned", buf, sizeof(buf));
+if (ret < 0) {
+ret = BLK_ZONED_MODEL_NONE;
+goto out;
 }
-g_free(sysfspath);
+
+buf[ret - 1] = 0;
+ret = BLK_ZONED_MODEL_NONE;
+if (strcmp(buf, "host-managed") == 0) {
+ret = BLK_ZONED_MODEL_HM;
+} else if (strcmp(buf, "host-aware") == 0) {
+ret = BLK_ZONED_MODEL_HA;
+}
+
+out:
 return ret;
 #else
 return -ENOTSUP;
@@ -1121,9 +1164,10 @@ out:
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
+int ret;
 
 if (bs->sg) {
-int ret = sg_get_max_transfer_length(s->fd);
+ret = sg_get_max_transfer_length(s->fd);
 
 if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
 bs->bl.max_transfer = pow2floor(ret);
@@ -1133,6 +1177,12 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 if (ret > 0) {
 bs->bl.max_transfer = MIN(bs->bl.max_transfer, ret * 
getpagesize());
 }
+
+}
+
+ret = hdev_get_zoned_model(s->fd);
+if (ret >= 0) {
+bs->bl.zoned_model = ret;
 }
 
 raw_probe_alignment(bs, s->fd, errp);
diff --git a/block/raw-format.c b/block/raw-format.c
index 42c28cc29a..a606e4a7fe 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -369,6 +369,13 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 }
 
+static void raw_get_zoned_info(BlockDriverState *bs)
+{
+if (!bs->probed) {
+bs->bl.zoned_model = bs->file->bs->bl.zoned_model;
+}
+}
+
 static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
 PreallocMode prealloc, Error **errp)
 {
@@ -578,6 +585,7 @@ BlockDriver bdrv_raw = {
 .create_opts  = _create_opts,
 .bdrv_has_zero_init   = _has_zero_init,
 .bdrv_has_zero_init_truncate = _has_zero_init_truncate,
+.bdrv_get_zoned_info  = _get_zoned_info,
 .strong_runtime_opts  = 

Re: [Qemu-devel] [RFC PATCH 00/17] Declare device little or big endian

2019-08-23 Thread no-reply
Patchew URL: https://patchew.org/QEMU/cover.1566467963.git.tony.ngu...@bt.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [RFC PATCH 00/17] Declare device little or big endian
Message-id: cover.1566467963.git.tony.ngu...@bt.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/cover.1566466906.git.tony.ngu...@bt.com -> 
patchew/cover.1566466906.git.tony.ngu...@bt.com
 * [new tag] patchew/cover.1566467963.git.tony.ngu...@bt.com -> 
patchew/cover.1566467963.git.tony.ngu...@bt.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for 
path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) 
registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 
'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 
'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 
'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered 
for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) 
registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for 
path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) 
registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for 
path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) 
registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for 
path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for 
path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for 
path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) 
registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 
'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' 
(https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 
'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' 
(https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 
'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out 
'22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 
'90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 
'7bfe584e321946771692711ff83ad2b5850daca7'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out 
'20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) 
registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' 
(https://github.com/openssl/openssl) registered for path 
'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': 
checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out 
'50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered 
for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) 
registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': 
checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked 
out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 

[Qemu-devel] [PATCH v5 0/4] virtio/block: handle zoned backing devices

2019-08-23 Thread Dmitry Fomichev
Ping... Any objections to merging this patchset? Ask me if you are not
sure how to validate these patches without having the hardware :)


Currently, attaching zoned block devices (i.e., storage devices
compliant to ZAC/ZBC standards) using several virtio methods doesn't
work properly as zoned devices appear as regular block devices at the
guest. This may cause unexpected i/o errors and, potentially, some
data corruption.

To be more precise, attaching a zoned device via virtio-pci-blk,
virtio-scsi-pci/scsi-disk or virtio-scsi-pci/scsi-hd demonstrates the
above behavior. The virtio-scsi-pci/scsi-block method works with a
recent patch. The virtio-scsi-pci/scsi-generic method also appears to
handle zoned devices without problems.

This patch set adds code to check if the backing device that is being
opened is a zoned Host Managed device. If this is the case, the patch
prohibits attaching such device for all use cases lacking proper
zoned support.

Host Aware zoned block devices are designed to work as regular block
devices at a guest system that does not support ZBD. Therefore, this
patch set doesn't prohibit attachment of Host Aware devices.

Considering that there is still a couple of different working ways
to attach a ZBD, this patch set provides a reasonable short-term
solution for this problem.

ZBD support for virtio-scsi-pci/scsi-disk and virtio-scsi-pci/scsi-hd
does not seem as necessary. Users will be expected to attach zoned
block devices via virtio-scsi-pci/scsi-block instead.

This patch set contains some Linux-specific code. This code is
necessary to obtain Zoned Block Device model value from Linux sysfs.

History:

v1 -> v2:
- rework code to be permission-based
- always allow Host Aware devices to be attached
- add fix for Host Aware attachments aka RCAP output snoop

v2 -> v3:
- drop the patch for RCAP output snoop - merged separately

v3 -> v4:
- rebase to the current code

v4 -> v5:
- avoid checkpatch warning

Dmitry Fomichev (4):
  block: Add zoned device model property
  raw: Recognize zoned backing devices
  block/ide/scsi: Set BLK_PERM_SUPPORT_ZONED
  raw: Don't open ZBDs if backend can't handle them

 block.c   | 19 +
 block/file-posix.c| 88 +--
 block/raw-format.c|  8 
 hw/block/block.c  |  8 +++-
 hw/block/fdc.c|  5 ++-
 hw/block/nvme.c   |  2 +-
 hw/block/virtio-blk.c |  2 +-
 hw/block/xen-block.c  |  2 +-
 hw/ide/qdev.c |  2 +-
 hw/scsi/scsi-disk.c   | 13 +++---
 hw/scsi/scsi-generic.c|  2 +-
 hw/usb/dev-storage.c  |  2 +-
 include/block/block.h | 21 +-
 include/block/block_int.h |  4 ++
 include/hw/block/block.h  |  3 +-
 15 files changed, 151 insertions(+), 30 deletions(-)

-- 
2.21.0




[Qemu-devel] [PATCH v5 1/4] block: Add zoned device model property

2019-08-23 Thread Dmitry Fomichev
This commit adds Zoned Device Model (as defined in T10 ZBC and
T13 ZAC standards) as a block driver property, along with some
useful access functions.

A new backend driver permission, BLK_PERM_SUPPORT_ZONED, is also
introduced. Only the drivers having this permission will be allowed
to open zoned block devices.

No code is added yet to initialize or check the value of this new
property, therefore this commit doesn't change any functionality.

Signed-off-by: Dmitry Fomichev 
---
 block.c   | 19 +++
 include/block/block.h | 21 -
 include/block/block_int.h |  4 
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 874a29a983..6dd4cecded 100644
--- a/block.c
+++ b/block.c
@@ -4679,6 +4679,25 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t 
*nb_sectors_ptr)
 *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
 }
 
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs)
+{
+if (bs->drv->bdrv_get_zoned_info) {
+bs->drv->bdrv_get_zoned_info(bs);
+}
+
+return bs->bl.zoned_model;
+}
+
+uint8_t bdrv_is_zoned(BlockDriverState *bs)
+{
+/*
+ * Host Aware zone devices are supposed to be able to work
+ * just like regular block devices. Thus, we only consider
+ * Host Managed devices to be zoned here.
+ */
+return bdrv_get_zoned_model(bs) == BLK_ZONED_MODEL_HM;
+}
+
 bool bdrv_is_sg(BlockDriverState *bs)
 {
 return bs->sg;
diff --git a/include/block/block.h b/include/block/block.h
index 124ad40809..238c0f5ed7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -271,18 +271,35 @@ enum {
  */
 BLK_PERM_GRAPH_MOD  = 0x10,
 
+/** This permission is required to open zoned block devices. */
+BLK_PERM_SUPPORT_ZONED  = 0x20,
+
 BLK_PERM_ALL= 0x1f,
 
 DEFAULT_PERM_PASSTHROUGH= BLK_PERM_CONSISTENT_READ
  | BLK_PERM_WRITE
  | BLK_PERM_WRITE_UNCHANGED
- | BLK_PERM_RESIZE,
+ | BLK_PERM_RESIZE
+ | BLK_PERM_SUPPORT_ZONED,
 
 DEFAULT_PERM_UNCHANGED  = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
 };
 
 char *bdrv_perm_names(uint64_t perm);
 
+/*
+ * Known zoned device models.
+ *
+ * TODO For a Linux host, it could be preferrable to include
+ * /usr/include/linux/blkzoned.h instead of defining ZBD-specific
+ * values here.
+ */
+enum blk_zoned_model {
+BLK_ZONED_MODEL_NONE, /* Regular block device */
+BLK_ZONED_MODEL_HA,   /* Host-aware zoned block device */
+BLK_ZONED_MODEL_HM,   /* Host-managed zoned block device */
+};
+
 /* disk I/O throttling */
 void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
@@ -359,6 +376,8 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
BlockDriverState *in_bs, Error **errp);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs);
+uint8_t bdrv_is_zoned(BlockDriverState *bs);
 void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_change_backing_file(BlockDriverState *bs,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index ceec8c2f56..91496e8149 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -415,6 +415,7 @@ struct BlockDriver {
 bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
 
 void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
+void (*bdrv_get_zoned_info)(BlockDriverState *bs);
 
 /*
  * Returns 1 if newly created images are guaranteed to contain only
@@ -620,6 +621,9 @@ typedef struct BlockLimits {
 
 /* maximum number of iovec elements */
 int max_iov;
+
+/* Zoned device model. Zero value indicates a regular block device */
+uint8_t zoned_model;
 } BlockLimits;
 
 typedef struct BdrvOpBlocker BdrvOpBlocker;
-- 
2.21.0




[Qemu-devel] [PATCH v5 4/4] raw: Don't open ZBDs if backend can't handle them

2019-08-23 Thread Dmitry Fomichev
Abort opening a zoned device as a raw file in case the chosen
block backend driver lacks proper support for this type of
storage.

Signed-off-by: Dmitry Fomichev 
---
 block/file-posix.c | 14 ++
 hw/block/fdc.c |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index d9f2fc5e46..090e7c4d2f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2884,6 +2884,20 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t 
perm, uint64_t shared,
 goto fail;
 }
 }
+
+/*
+ * If we are opening a zoned block device, check if the backend
+ * driver can properly handle such devices, abort if not.
+ */
+if (bdrv_is_zoned(bs) &&
+(shared & BLK_PERM_SUPPORT_ZONED) &&
+!(perm & BLK_PERM_SUPPORT_ZONED)) {
+error_setg(errp,
+   "block backend driver doesn't support HM zoned devices");
+ret = -ENOTSUP;
+goto fail;
+}
+
 return 0;
 
 fail:
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index c5f41b3eb6..673a8b39bc 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -570,7 +570,7 @@ static void floppy_drive_realize(DeviceState *qdev, Error 
**errp)
 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
 
 if (!blkconf_apply_backend_options(>conf, read_only, false, false,
-  errp)) {
+   errp)) {
 return;
 }
 
-- 
2.21.0




[Qemu-devel] [PATCH 6/9] memory: Delete devend_memop

2019-08-23 Thread Tony Nguyen
device_endian has been made redundant by MemOp.

Signed-off-by: Tony Nguyen 
---
 include/exec/memory.h |  3 ---
 memory.c  | 19 +--
 memory_ldst.inc.c | 18 ++
 3 files changed, 7 insertions(+), 33 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 1fa7e03707..ff80465ac1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2211,9 +2211,6 @@ address_space_write_cached(MemoryRegionCache *cache, 
hwaddr addr,
 }
 }
 
-/* MemOp to MemOp.  */
-MemOp devend_memop(MemOp end);
-
 #endif
 
 #endif
diff --git a/memory.c b/memory.c
index ee2bef7b1e..d78d6e46db 100644
--- a/memory.c
+++ b/memory.c
@@ -354,7 +354,7 @@ static bool memory_region_big_endian(MemoryRegion *mr)
 
 static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
 {
-if ((op & MO_BSWAP) != devend_memop(mr->ops->endianness)) {
+if ((op & MO_BSWAP) != mr->ops->endianness) {
 switch (op & MO_SIZE) {
 case MO_8:
 break;
@@ -3271,20 +3271,3 @@ static void memory_register_types(void)
 }
 
 type_init(memory_register_types)
-
-MemOp devend_memop(MemOp end)
-{
-static MemOp conv[] = {
-[MO_LE] = MO_LE,
-[MO_BE] = MO_BE,
-[MO_TE] = MO_TE,
-[DEVICE_HOST_ENDIAN] = 0,
-};
-switch (end) {
-case MO_LE:
-case MO_BE:
-return conv[end];
-default:
-g_assert_not_reached();
-}
-}
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index dd1e02d685..028227f52f 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -37,8 +37,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);
 
 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, ,
-MO_32 | devend_memop(endian), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_32 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -104,8 +103,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);
 
 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, ,
-MO_64 | devend_memop(endian), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_64 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -205,8 +203,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);
 
 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, ,
-MO_16 | devend_memop(endian), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_16 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -309,8 +306,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val,
- MO_32 | devend_memop(endian), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -405,8 +401,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (l < 2 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val,
- MO_16 | devend_memop(endian), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_16 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -469,8 +464,7 @@ static void glue(address_space_stq_internal, 
SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (l < 8 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val,
- MO_64 | devend_memop(endian), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_64 | endian, 
attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
-- 
2.23.0




[Qemu-devel] [PATCH 9/9] memory: Delete memory_region_big_endian

2019-08-23 Thread Tony Nguyen
memory_region_big_endian is no longer useful now we are consistently
using MemOp for endianness.

Signed-off-by: Tony Nguyen 
---
 memory.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/memory.c b/memory.c
index ee7559a18c..b647a8d3dd 100644
--- a/memory.c
+++ b/memory.c
@@ -343,15 +343,6 @@ static void flatview_simplify(FlatView *view)
 }
 }
 
-static bool memory_region_big_endian(MemoryRegion *mr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-return mr->ops->endianness != MO_LE;
-#else
-return mr->ops->endianness == MO_BE;
-#endif
-}
-
 static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
 {
 if ((op & MO_BSWAP) != mr->ops->endianness) {
@@ -555,7 +546,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
 /* FIXME: support unaligned access? */
 access_size = MAX(MIN(size, access_size_max), access_size_min);
 access_mask = MAKE_64BIT_MASK(0, access_size * 8);
-if (memory_region_big_endian(mr)) {
+if (mr->ops->endianness == MO_BE) {
 for (i = 0; i < size; i += access_size) {
 r |= access_fn(mr, addr + i, value, access_size,
 (size - access_size - i) * 8, access_mask, attrs);
-- 
2.23.0




[Qemu-devel] [PATCH 8/9] exec: Delete DEVICE_HOST_ENDIAN

2019-08-23 Thread Tony Nguyen
Simplify code with MemOp short hand for host endianness, 0.

 typedef enum MemOp {
 /* snip */
 #ifdef HOST_WORDS_BIGENDIAN
 MO_LE= MO_BSWAP,
 MO_BE= 0,
 #else
 MO_LE= 0,
 MO_BE= MO_BSWAP,
 #endif
 /* snip */
 };

Signed-off-by: Tony Nguyen 
---
 include/exec/cpu-common.h | 8 
 memory.c  | 2 +-
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 7eeb78c48b..b33dc0c9f5 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,14 +16,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);
 
 #if !defined(CONFIG_USER_ONLY)
 
-#include "exec/memop.h"
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define DEVICE_HOST_ENDIAN MO_BE
-#else
-#define DEVICE_HOST_ENDIAN MO_LE
-#endif
-
 /* address in the RAM (different from a physical address) */
 #if defined(CONFIG_XEN_BACKEND)
 typedef uint64_t ram_addr_t;
diff --git a/memory.c b/memory.c
index d78d6e46db..ee7559a18c 100644
--- a/memory.c
+++ b/memory.c
@@ -1353,7 +1353,7 @@ static void memory_region_ram_device_write(void *opaque, 
hwaddr addr,
 static const MemoryRegionOps ram_device_mem_ops = {
 .read = memory_region_ram_device_read,
 .write = memory_region_ram_device_write,
-.endianness = DEVICE_HOST_ENDIAN,
+.endianness = 0, /* Host endianness */
 .valid = {
 .min_access_size = 1,
 .max_access_size = 8,
-- 
2.23.0




[Qemu-devel] [PATCH 2/9] exec: Replace DEVICE_NATIVE_ENDIAN with MO_TE

2019-08-23 Thread Tony Nguyen
Simplify endianness comparisons with consistent use of the more
expressive MemOp.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 exec.c |  8 +++
 hw/adc/stm32f2xx_adc.c |  2 +-
 hw/arm/allwinner-a10.c |  2 +-
 hw/arm/armv7m.c|  2 +-
 hw/arm/aspeed.c|  2 +-
 hw/arm/exynos4210.c|  2 +-
 hw/arm/highbank.c  |  2 +-
 hw/arm/integratorcp.c  |  6 +++---
 hw/arm/kzm.c   |  2 +-
 hw/arm/msf2-soc.c  |  2 +-
 hw/arm/musicpal.c  | 20 +-
 hw/arm/omap1.c | 38 +-
 hw/arm/omap2.c | 10 -
 hw/arm/omap_sx1.c  |  2 +-
 hw/arm/palm.c  |  2 +-
 hw/arm/pxa2xx.c| 20 +-
 hw/arm/pxa2xx_gpio.c   |  2 +-
 hw/arm/pxa2xx_pic.c|  2 +-
 hw/arm/spitz.c |  2 +-
 hw/arm/stellaris.c |  8 +++
 hw/arm/strongarm.c | 12 +--
 hw/arm/versatilepb.c   |  2 +-
 hw/audio/intel-hda.c   |  2 +-
 hw/block/fdc.c |  4 ++--
 hw/block/pflash_cfi01.c|  2 +-
 hw/block/pflash_cfi02.c|  2 +-
 hw/char/bcm2835_aux.c  |  2 +-
 hw/char/digic-uart.c   |  2 +-
 hw/char/exynos4210_uart.c  |  2 +-
 hw/char/mcf_uart.c |  2 +-
 hw/char/omap_uart.c|  6 +++---
 hw/char/parallel.c |  2 +-
 hw/char/sh_serial.c|  2 +-
 hw/char/stm32f2xx_usart.c  |  2 +-
 hw/char/xilinx_uartlite.c  |  2 +-
 hw/core/empty_slot.c   |  2 +-
 hw/cris/axis_dev88.c   |  4 ++--
 hw/display/bcm2835_fb.c|  2 +-
 hw/display/cg3.c   |  2 +-
 hw/display/exynos4210_fimd.c   |  2 +-
 hw/display/jazz_led.c  |  2 +-
 hw/display/milkymist-tmu2.c|  2 +-
 hw/display/milkymist-vgafb.c   |  2 +-
 hw/display/omap_dss.c  | 10 -
 hw/display/omap_lcdc.c |  2 +-
 hw/display/pxa2xx_lcd.c|  2 +-
 hw/display/tcx.c   | 14 ++---
 hw/display/vga-isa-mm.c|  2 +-
 hw/display/xlnx_dp.c   |  8 +++
 hw/dma/i8257.c |  4 ++--
 hw/dma/omap_dma.c  |  4 ++--
 hw/dma/pxa2xx_dma.c|  2 +-
 hw/dma/rc4030.c|  4 ++--
 hw/dma/xilinx_axidma.c |  2 +-
 hw/dma/xlnx_dpdma.c|  2 +-
 hw/gpio/bcm2835_gpio.c |  2 +-
 hw/gpio/imx_gpio.c |  2 +-
 hw/gpio/omap_gpio.c|  6 +++---
 hw/gpio/puv3_gpio.c|  2 +-
 hw/i2c/exynos4210_i2c.c|  2 +-
 hw/i2c/omap_i2c.c  |  2 +-
 hw/i2c/ppc4xx_i2c.c|  2 +-
 hw/i386/kvm/apic.c |  2 +-
 hw/i386/kvmvapic.c |  2 +-
 hw/i386/pc.c   |  4 ++--
 hw/i386/xen/xen_apic.c |  2 +-
 hw/i386/xen/xen_platform.c |  2 +-
 hw/input/milkymist-softusb.c   |  2 +-
 hw/input/pckbd.c   |  2 +-
 hw/input/pxa2xx_keypad.c   |  2 +-
 hw/intc/allwinner-a10-pic.c|  2 +-
 hw/intc/apic.c |  2 +-
 hw/intc/arm_gicv3_its_common.c |  2 +-
 hw/intc/armv7m_nvic.c  |  6 +++---
 hw/intc/bcm2835_ic.c   |  2 +-
 hw/intc/bcm2836_control.c  |  2 +-
 hw/intc/exynos4210_combiner.c  |  2 +-
 hw/intc/grlib_irqmp.c  |  2 +-
 hw/intc/ioapic.c   |  2 +-
 hw/intc/mips_gic.c |  2 +-
 hw/intc/omap_intc.c|  4 ++--
 hw/intc/ompic.c|  2 +-
 hw/intc/sh_intc.c  |  2 +-
 hw/intc/slavio_intctl.c|  4 ++--
 hw/intc/xilinx_intc.c  |  2 +-
 hw/ipack/tpci200.c | 10 -
 hw/m68k/mcf5206.c  |  2 +-
 hw/m68k/mcf5208.c  |  4 ++--
 hw/m68k/mcf_intc.c |  2 +-
 hw/mips/boston.c   |  6 +++---
 hw/mips/gt64xxx_pci.c  |  2 +-
 hw/mips/mips_jazz.c|  8 +++
 hw/mips/mips_malta.c   |  4 ++--
 hw/mips/mips_r4k.c |  2 +-
 hw/misc/arm_integrator_debug.c |  2 +-
 hw/misc/arm_sysctl.c   |  2 +-
 hw/misc/aspeed_xdma.c  |  2 +-
 hw/misc/bcm2835_mbox.c |  2 +-
 hw/misc/bcm2835_property.c |  2 +-
 hw/misc/bcm2835_rng.c  |  2 +-
 hw/misc/eccmemctl.c|  4 ++--
 hw/misc/edu.c  |  2 +-
 hw/misc/exynos4210_clk.c   |  2 +-
 hw/misc/exynos4210_pmu.c   |  2 +-
 hw/misc/exynos4210_rng.c   |  2 +-
 hw/misc/imx25_ccm.c|  2 +-
 hw/misc/imx2_wdt.c |  2 +-
 hw/misc/imx31_ccm.c|  2 +-
 hw/misc/imx6_ccm.c |  4 ++--
 hw/misc/imx6_src.c |  2 +-
 hw/misc/imx6ul_ccm.c   |  4 ++--
 hw/misc/imx7_ccm.c |  4 ++--
 hw/misc/imx7_gpr.c |  2 +-
 hw/misc/imx7_snvs.c|  2 +-
 hw/misc/ivshmem.c  |  2 +-
 

[Qemu-devel] [PATCH 4/9] exec: Replace DEVICE_BIG_ENDIAN with MO_BE

2019-08-23 Thread Tony Nguyen
Simplify endianness comparisons with consistent use of the more
expressive MemOp.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 hw/audio/cs4231.c   |  2 +-
 hw/audio/milkymist-ac97.c   |  2 +-
 hw/char/escc.c  |  2 +-
 hw/char/grlib_apbuart.c |  2 +-
 hw/char/lm32_uart.c |  2 +-
 hw/char/milkymist-uart.c|  2 +-
 hw/char/serial.c|  4 ++--
 hw/dma/sparc32_dma.c|  2 +-
 hw/gpio/mpc8xxx.c   |  2 +-
 hw/hppa/dino.c  |  4 ++--
 hw/hppa/machine.c   |  2 +-
 hw/hppa/pci.c   |  6 +++---
 hw/i2c/mpc_i2c.c|  2 +-
 hw/intc/openpic.c   | 12 ++--
 hw/intc/openpic_kvm.c   |  2 +-
 hw/intc/pnv_xive.c  | 14 +++---
 hw/intc/xics_pnv.c  |  2 +-
 hw/intc/xive.c  |  6 +++---
 hw/misc/grlib_ahb_apb_pnp.c |  4 ++--
 hw/misc/macio/cuda.c|  2 +-
 hw/misc/macio/pmu.c |  2 +-
 hw/net/lance.c  |  2 +-
 hw/nvram/fw_cfg.c   |  6 +++---
 hw/nvram/mac_nvram.c|  2 +-
 hw/pci-host/ppce500.c   |  2 +-
 hw/pci-host/sabre.c |  2 +-
 hw/pci-host/uninorth.c  |  2 +-
 hw/pci/pci_host.c   |  4 ++--
 hw/ppc/e500.c   |  4 ++--
 hw/ppc/mpc8544_guts.c   |  2 +-
 hw/ppc/pnv_core.c   |  6 +++---
 hw/ppc/pnv_lpc.c|  8 
 hw/ppc/pnv_occ.c|  4 ++--
 hw/ppc/pnv_psi.c|  8 
 hw/ppc/pnv_xscom.c  |  2 +-
 hw/ppc/ppc405_boards.c  |  2 +-
 hw/ppc/ppc405_uc.c  | 10 +-
 hw/ppc/ppc440_bamboo.c  |  4 ++--
 hw/ppc/ppce500_spin.c   |  2 +-
 hw/ppc/sam460ex.c   |  4 ++--
 hw/sparc64/niagara.c|  2 +-
 hw/sparc64/sun4u.c  |  2 +-
 hw/sparc64/sun4u_iommu.c|  2 +-
 hw/timer/grlib_gptimer.c|  2 +-
 hw/timer/lm32_timer.c   |  2 +-
 hw/timer/m48t59.c   |  2 +-
 hw/timer/milkymist-sysctl.c |  2 +-
 hw/timer/sun4v-rtc.c|  2 +-
 include/exec/cpu-common.h   |  2 +-
 memory.c|  6 +++---
 memory_ldst.inc.c   | 24 
 51 files changed, 101 insertions(+), 101 deletions(-)

diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c
index 1ff9093efa..abfab8c4e3 100644
--- a/hw/audio/cs4231.c
+++ b/hw/audio/cs4231.c
@@ -133,7 +133,7 @@ static void cs_mem_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps cs_mem_ops = {
 .read = cs_mem_read,
 .write = cs_mem_write,
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 };
 
 static const VMStateDescription vmstate_cs4231 = {
diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c
index 897dfff85a..bde90e4e76 100644
--- a/hw/audio/milkymist-ac97.c
+++ b/hw/audio/milkymist-ac97.c
@@ -177,7 +177,7 @@ static const MemoryRegionOps ac97_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 };
 
 static void ac97_in_cb(void *opaque, int avail_b)
diff --git a/hw/char/escc.c b/hw/char/escc.c
index e2130e04e5..505364e1f8 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -576,7 +576,7 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps escc_mem_ops = {
 .read = escc_mem_read,
 .write = escc_mem_write,
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 1,
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index 880878ab4d..de21334ace 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -239,7 +239,7 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps grlib_apbuart_ops = {
 .write  = grlib_apbuart_write,
 .read   = grlib_apbuart_read,
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 };
 
 static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index 372c7d60d8..533a401fee 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -207,7 +207,7 @@ static void uart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps uart_ops = {
 .read = uart_read,
 .write = uart_write,
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index ed4f02c500..3d008685d1 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -158,7 +158,7 @@ static const MemoryRegionOps uart_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_BIG_ENDIAN,
+.endianness = MO_BE,
 };
 
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 

[Qemu-devel] [PATCH 7/9] exec: Delete device_endian

2019-08-23 Thread Tony Nguyen
device_endian has been made redundant by MemOp.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/cpu-common.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 01a29ba571..7eeb78c48b 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -18,14 +18,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);
 
 #include "exec/memop.h"
 
-enum device_endian {
-#ifdef NEED_CPU_H
-DEVICE_NATIVE_ENDIAN = MO_TE,
-#endif
-DEVICE_BIG_ENDIAN = MO_BE,
-DEVICE_LITTLE_ENDIAN = MO_LE,
-};
-
 #if defined(HOST_WORDS_BIGENDIAN)
 #define DEVICE_HOST_ENDIAN MO_BE
 #else
-- 
2.23.0




[Qemu-devel] [PATCH 5/9] exec: Replace enum device_endian with MemOp

2019-08-23 Thread Tony Nguyen
Simplify endianness comparisons with consistent use of the more
expressive MemOp.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 hw/char/serial.c |  2 +-
 include/exec/memory.h|  6 +++---
 include/hw/char/serial.h |  2 +-
 memory.c |  2 +-
 memory_ldst.inc.c| 15 ++-
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index cf41203be6..c725688828 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -1036,7 +1036,7 @@ static const MemoryRegionOps serial_mm_ops[2] = {
 SerialState *serial_mm_init(MemoryRegion *address_space,
 hwaddr base, int it_shift,
 qemu_irq irq, int baudbase,
-Chardev *chr, enum device_endian end)
+Chardev *chr, MemOp end)
 {
 SerialState *s;
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c4c86a6ff4..1fa7e03707 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -168,7 +168,7 @@ struct MemoryRegionOps {
 unsigned size,
 MemTxAttrs attrs);
 
-enum device_endian endianness;
+MemOp endianness;
 /* Guest-visible constraints: */
 struct {
 /* If nonzero, specify bounds on access sizes beyond which a machine
@@ -2211,8 +2211,8 @@ address_space_write_cached(MemoryRegionCache *cache, 
hwaddr addr,
 }
 }
 
-/* enum device_endian to MemOp.  */
-MemOp devend_memop(enum device_endian end);
+/* MemOp to MemOp.  */
+MemOp devend_memop(MemOp end);
 
 #endif
 
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 8be3d8a4f9..175b980249 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -90,7 +90,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
 SerialState *serial_mm_init(MemoryRegion *address_space,
 hwaddr base, int it_shift,
 qemu_irq irq, int baudbase,
-Chardev *chr, enum device_endian end);
+Chardev *chr, MemOp end);
 
 /* serial-isa.c */
 
diff --git a/memory.c b/memory.c
index 52090e18eb..ee2bef7b1e 100644
--- a/memory.c
+++ b/memory.c
@@ -3272,7 +3272,7 @@ static void memory_register_types(void)
 
 type_init(memory_register_types)
 
-MemOp devend_memop(enum device_endian end)
+MemOp devend_memop(MemOp end)
 {
 static MemOp conv[] = {
 [MO_LE] = MO_LE,
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index 45bec83a94..dd1e02d685 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -21,8 +21,7 @@
 
 /* warning: addr must be aligned */
 static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
-hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
-enum device_endian endian)
+hwaddr addr, MemTxAttrs attrs, MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 uint64_t val;
@@ -89,8 +88,7 @@ uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
 
 /* warning: addr must be aligned */
 static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
-hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
-enum device_endian endian)
+hwaddr addr, MemTxAttrs attrs, MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 uint64_t val;
@@ -191,8 +189,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 
 /* warning: addr must be aligned */
 static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
-hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
-enum device_endian endian)
+hwaddr addr, MemTxAttrs attrs, MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 uint64_t val;
@@ -299,7 +296,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 /* warning: addr must be aligned */
 static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
 hwaddr addr, uint32_t val, MemTxAttrs attrs,
-MemTxResult *result, enum device_endian endian)
+MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 MemoryRegion *mr;
@@ -395,7 +392,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 /* warning: addr must be aligned */
 static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
 hwaddr addr, uint32_t val, MemTxAttrs attrs,
-MemTxResult *result, enum device_endian endian)
+MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 MemoryRegion *mr;
@@ -459,7 +456,7 @@ void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
 
 static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
 hwaddr addr, uint64_t val, MemTxAttrs attrs,
-MemTxResult *result, enum device_endian endian)
+MemTxResult *result, MemOp endian)
 {
 uint8_t *ptr;
 MemoryRegion *mr;
-- 
2.23.0




[Qemu-devel] [PATCH 1/9] exec: Map device_endian onto MemOp

2019-08-23 Thread Tony Nguyen
Preparation to replace device_endian with MemOp.

Mapping device_endian onto MemOp limits behaviour changes to this
relatively smaller patch.

The next patch will replace all device_endian usages with the
equivalent MemOp. That patch will be large but have no behaviour
changes.

A subsequent patch will then delete unused device_endian.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/char/serial.c  | 18 ++
 include/exec/cpu-common.h | 10 +++---
 memory.c  |  1 -
 3 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index b4aa250950..6328476f52 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -1016,22 +1016,15 @@ static void serial_mm_write(void *opaque, hwaddr addr,
 serial_ioport_write(s, addr >> s->it_shift, value, 1);
 }
 
-static const MemoryRegionOps serial_mm_ops[3] = {
-[DEVICE_NATIVE_ENDIAN] = {
-.read = serial_mm_read,
-.write = serial_mm_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.valid.max_access_size = 8,
-.impl.max_access_size = 8,
-},
-[DEVICE_LITTLE_ENDIAN] = {
+static const MemoryRegionOps serial_mm_ops[2] = {
+[0] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid.max_access_size = 8,
 .impl.max_access_size = 8,
 },
-[DEVICE_BIG_ENDIAN] = {
+[1] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_BIG_ENDIAN,
@@ -1057,8 +1050,9 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
 serial_realize_core(s, _fatal);
 vmstate_register(NULL, base, _serial, s);
 
-memory_region_init_io(>io, NULL, _mm_ops[end], s,
-  "serial", 8 << it_shift);
+memory_region_init_io(>io, NULL,
+  _mm_ops[end == DEVICE_BIG_ENDIAN],
+  s, "serial", 8 << it_shift);
 memory_region_add_subregion(address_space, base, >io);
 return s;
 }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index f7dbe75fbc..c388453ed7 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,10 +16,14 @@ void tcg_flush_softmmu_tlb(CPUState *cs);
 
 #if !defined(CONFIG_USER_ONLY)
 
+#include "exec/memop.h"
+
 enum device_endian {
-DEVICE_NATIVE_ENDIAN,
-DEVICE_BIG_ENDIAN,
-DEVICE_LITTLE_ENDIAN,
+#ifdef NEED_CPU_H
+DEVICE_NATIVE_ENDIAN = MO_TE,
+#endif
+DEVICE_BIG_ENDIAN = MO_BE,
+DEVICE_LITTLE_ENDIAN = MO_LE,
 };
 
 #if defined(HOST_WORDS_BIGENDIAN)
diff --git a/memory.c b/memory.c
index 11a9b08060..f30ce520c9 100644
--- a/memory.c
+++ b/memory.c
@@ -3283,7 +3283,6 @@ MemOp devend_memop(enum device_endian end)
 switch (end) {
 case DEVICE_LITTLE_ENDIAN:
 case DEVICE_BIG_ENDIAN:
-case DEVICE_NATIVE_ENDIAN:
 return conv[end];
 default:
 g_assert_not_reached();
-- 
2.23.0




[Qemu-devel] [PATCH 0/9] Delete enum device_endian

2019-08-23 Thread Tony Nguyen
This series deletes endian related enum, converter, and macro which have been
made redundant by MemOp being pushed down from TCG into the memory API.

This clean up was split out from an earlier series which collapsed byte swaps
along the I/O path.

Based-on: 
[PATCH v9 00/20] Invert Endian bit in SPARCv9 MMU TTE
Based-on: 
[RFC PATCH 00/17] Declare device little or big endian

Tony Nguyen (9):
  exec: Map device_endian onto MemOp
  exec: Replace DEVICE_NATIVE_ENDIAN with MO_TE
  exec: Replace DEVICE_LITTLE_ENDIAN with MO_LE
  exec: Replace DEVICE_BIG_ENDIAN with MO_BE
  exec: Replace enum device_endian with MemOp
  memory: Delete devend_memop
  exec: Delete device_endian
  exec: Delete DEVICE_HOST_ENDIAN
  memory: Delete memory_region_big_endian

 exec.c  |  8 +--
 hw/acpi/core.c  |  6 +-
 hw/acpi/cpu.c   |  2 +-
 hw/acpi/cpu_hotplug.c   |  2 +-
 hw/acpi/ich9.c  |  4 +-
 hw/acpi/memory_hotplug.c|  2 +-
 hw/acpi/nvdimm.c|  2 +-
 hw/acpi/pcihp.c |  2 +-
 hw/acpi/piix4.c |  2 +-
 hw/acpi/tco.c   |  2 +-
 hw/adc/stm32f2xx_adc.c  |  2 +-
 hw/alpha/pci.c  |  6 +-
 hw/alpha/typhoon.c  |  6 +-
 hw/arm/allwinner-a10.c  |  2 +-
 hw/arm/armv7m.c |  2 +-
 hw/arm/aspeed.c |  2 +-
 hw/arm/aspeed_soc.c |  2 +-
 hw/arm/exynos4210.c |  2 +-
 hw/arm/highbank.c   |  2 +-
 hw/arm/integratorcp.c   |  6 +-
 hw/arm/kzm.c|  2 +-
 hw/arm/msf2-soc.c   |  2 +-
 hw/arm/musicpal.c   | 20 +++
 hw/arm/omap1.c  | 40 ++---
 hw/arm/omap2.c  | 10 ++--
 hw/arm/omap_sx1.c   |  2 +-
 hw/arm/palm.c   |  2 +-
 hw/arm/pxa2xx.c | 20 +++
 hw/arm/pxa2xx_gpio.c|  2 +-
 hw/arm/pxa2xx_pic.c |  2 +-
 hw/arm/smmuv3.c |  2 +-
 hw/arm/spitz.c  |  2 +-
 hw/arm/stellaris.c  |  8 +--
 hw/arm/strongarm.c  | 12 ++--
 hw/arm/versatilepb.c|  2 +-
 hw/audio/ac97.c |  4 +-
 hw/audio/cs4231.c   |  2 +-
 hw/audio/es1370.c   |  2 +-
 hw/audio/intel-hda.c|  2 +-
 hw/audio/marvell_88w8618.c  |  2 +-
 hw/audio/milkymist-ac97.c   |  2 +-
 hw/audio/pl041.c|  2 +-
 hw/block/fdc.c  |  4 +-
 hw/block/nvme.c |  4 +-
 hw/block/onenand.c  |  2 +-
 hw/block/pflash_cfi01.c |  2 +-
 hw/block/pflash_cfi02.c |  2 +-
 hw/char/bcm2835_aux.c   |  2 +-
 hw/char/cadence_uart.c  |  2 +-
 hw/char/cmsdk-apb-uart.c|  2 +-
 hw/char/debugcon.c  |  2 +-
 hw/char/digic-uart.c|  2 +-
 hw/char/escc.c  |  2 +-
 hw/char/etraxfs_ser.c   |  2 +-
 hw/char/exynos4210_uart.c   |  2 +-
 hw/char/grlib_apbuart.c |  2 +-
 hw/char/imx_serial.c|  2 +-
 hw/char/lm32_uart.c |  2 +-
 hw/char/mcf_uart.c  |  2 +-
 hw/char/milkymist-uart.c|  2 +-
 hw/char/nrf51_uart.c|  2 +-
 hw/char/omap_uart.c |  6 +-
 hw/char/parallel.c  |  2 +-
 hw/char/pl011.c |  2 +-
 hw/char/serial.c| 26 
 hw/char/sh_serial.c |  2 +-
 hw/char/stm32f2xx_usart.c   |  2 +-
 hw/char/xilinx_uartlite.c   |  2 +-
 hw/core/empty_slot.c|  2 +-
 hw/cris/axis_dev88.c|  4 +-
 hw/display/ati.c|  2 +-
 hw/display/bcm2835_fb.c |  2 +-
 hw/display/bochs-display.c  |  4 +-
 hw/display/cg3.c|  2 +-
 hw/display/cirrus_vga.c | 10 ++--
 hw/display/edid-region.c|  2 +-
 hw/display/exynos4210_fimd.c|  2 +-
 hw/display/g364fb.c |  2 +-
 hw/display/jazz_led.c   |  2 +-
 hw/display/milkymist-tmu2.c |  2 +-
 hw/display/milkymist-vgafb.c|  2 +-
 hw/display/omap_dss.c   | 10 ++--
 hw/display/omap_lcdc.c  |  2 +-
 hw/display/pl110.c  |  2 +-
 hw/display/pxa2xx_lcd.c |  2 +-
 hw/display/sm501.c  | 10 ++--
 hw/display/tc6393xb.c   |  2 +-
 hw/display/tcx.c| 14 ++---
 hw/display/vga-isa-mm.c |  2 +-
 hw/display/vga-pci.c|  6 +-
 hw/display/vga.c|  2 +-
 hw/display/vmware_vga.c |  2 +-
 hw/display/xlnx_dp.c|  8 +--
 

[Qemu-devel] [PATCH v4 1/4] block: Add zoned device model property

2019-08-23 Thread Dmitry Fomichev
This commit adds Zoned Device Model (as defined in T10 ZBC and
T13 ZAC standards) as a block driver property, along with some
useful access functions.

A new backend driver permission, BLK_PERM_SUPPORT_ZONED, is also
introduced. Only the drivers having this permission will be allowed
to open zoned block devices.

No code is added yet to initialize or check the value of this new
property, therefore this commit doesn't change any functionality.

Signed-off-by: Dmitry Fomichev 
---
 block.c   | 19 +++
 include/block/block.h | 21 -
 include/block/block_int.h |  4 
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 874a29a983..6dd4cecded 100644
--- a/block.c
+++ b/block.c
@@ -4679,6 +4679,25 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t 
*nb_sectors_ptr)
 *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
 }
 
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs)
+{
+if (bs->drv->bdrv_get_zoned_info) {
+bs->drv->bdrv_get_zoned_info(bs);
+}
+
+return bs->bl.zoned_model;
+}
+
+uint8_t bdrv_is_zoned(BlockDriverState *bs)
+{
+/*
+ * Host Aware zone devices are supposed to be able to work
+ * just like regular block devices. Thus, we only consider
+ * Host Managed devices to be zoned here.
+ */
+return bdrv_get_zoned_model(bs) == BLK_ZONED_MODEL_HM;
+}
+
 bool bdrv_is_sg(BlockDriverState *bs)
 {
 return bs->sg;
diff --git a/include/block/block.h b/include/block/block.h
index 124ad40809..238c0f5ed7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -271,18 +271,35 @@ enum {
  */
 BLK_PERM_GRAPH_MOD  = 0x10,
 
+/** This permission is required to open zoned block devices. */
+BLK_PERM_SUPPORT_ZONED  = 0x20,
+
 BLK_PERM_ALL= 0x1f,
 
 DEFAULT_PERM_PASSTHROUGH= BLK_PERM_CONSISTENT_READ
  | BLK_PERM_WRITE
  | BLK_PERM_WRITE_UNCHANGED
- | BLK_PERM_RESIZE,
+ | BLK_PERM_RESIZE
+ | BLK_PERM_SUPPORT_ZONED,
 
 DEFAULT_PERM_UNCHANGED  = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
 };
 
 char *bdrv_perm_names(uint64_t perm);
 
+/*
+ * Known zoned device models.
+ *
+ * TODO For a Linux host, it could be preferrable to include
+ * /usr/include/linux/blkzoned.h instead of defining ZBD-specific
+ * values here.
+ */
+enum blk_zoned_model {
+BLK_ZONED_MODEL_NONE, /* Regular block device */
+BLK_ZONED_MODEL_HA,   /* Host-aware zoned block device */
+BLK_ZONED_MODEL_HM,   /* Host-managed zoned block device */
+};
+
 /* disk I/O throttling */
 void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
@@ -359,6 +376,8 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
BlockDriverState *in_bs, Error **errp);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs);
+uint8_t bdrv_is_zoned(BlockDriverState *bs);
 void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_change_backing_file(BlockDriverState *bs,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index ceec8c2f56..91496e8149 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -415,6 +415,7 @@ struct BlockDriver {
 bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
 
 void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
+void (*bdrv_get_zoned_info)(BlockDriverState *bs);
 
 /*
  * Returns 1 if newly created images are guaranteed to contain only
@@ -620,6 +621,9 @@ typedef struct BlockLimits {
 
 /* maximum number of iovec elements */
 int max_iov;
+
+/* Zoned device model. Zero value indicates a regular block device */
+uint8_t zoned_model;
 } BlockLimits;
 
 typedef struct BdrvOpBlocker BdrvOpBlocker;
-- 
2.21.0




Re: [Qemu-devel] [PATCH 2/4] docs: merge HACKING.md contents into CODING_STYLE.md

2019-08-23 Thread Eric Blake
On 8/23/19 11:39 AM, Daniel P. Berrangé wrote:
> The split of information between the two docs is rather arbitary and
> unclear. It is simpler for contributors if all the information is in
> one file.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  CODING_STYLE.md | 262 +++
>  HACKING.md  | 263 
>  README  |   2 +-
>  3 files changed, 263 insertions(+), 264 deletions(-)
>  delete mode 100644 HACKING.md

Is it worth trying to group related sections as part of the combination?
 (Your solution of just concatenating at the end is obviously the
fastest, but may result in odd ordering where similar things are
mentioned twice but in different parts of the file).

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v4 0/4] virtio/block: handle zoned backing devices

2019-08-23 Thread Dmitry Fomichev
Ping... Any objections to merging this patchset? Ask me if you are not
sure how to validate these patches without having the hardware :)


Currently, attaching zoned block devices (i.e., storage devices
compliant to ZAC/ZBC standards) using several virtio methods doesn't
work properly as zoned devices appear as regular block devices at the
guest. This may cause unexpected i/o errors and, potentially, some
data corruption.

To be more precise, attaching a zoned device via virtio-pci-blk,
virtio-scsi-pci/scsi-disk or virtio-scsi-pci/scsi-hd demonstrates the
above behavior. The virtio-scsi-pci/scsi-block method works with a
recent patch. The virtio-scsi-pci/scsi-generic method also appears to
handle zoned devices without problems.

This patch set adds code to check if the backing device that is being
opened is a zoned Host Managed device. If this is the case, the patch
prohibits attaching such device for all use cases lacking proper
zoned support.

Host Aware zoned block devices are designed to work as regular block
devices at a guest system that does not support ZBD. Therefore, this
patch set doesn't prohibit attachment of Host Aware devices.

Considering that there is still a couple of different working ways
to attach a ZBD, this patch set provides a reasonable short-term
solution for this problem.

ZBD support for virtio-scsi-pci/scsi-disk and virtio-scsi-pci/scsi-hd
does not seem as necessary. Users will be expected to attach zoned
block devices via virtio-scsi-pci/scsi-block instead.

This patch set contains some Linux-specific code. This code is
necessary to obtain Zoned Block Device model value from Linux sysfs.

History:

v1 -> v2:
- rework code to be permission-based
- always allow Host Aware devices to be attached
- add fix for Host Aware attachments aka RCAP output snoop

v2 -> v3:
- drop the patch for RCAP output snoop - merged separately

v3 -> v4:
- rebase to the current code

Dmitry Fomichev (4):
  block: Add zoned device model property
  raw: Recognize zoned backing devices
  block/ide/scsi: Set BLK_PERM_SUPPORT_ZONED
  raw: Don't open ZBDs if backend can't handle them

 block.c   | 19 +
 block/file-posix.c| 88 +--
 block/raw-format.c|  8 
 hw/block/block.c  |  8 +++-
 hw/block/fdc.c|  5 ++-
 hw/block/nvme.c   |  2 +-
 hw/block/virtio-blk.c |  2 +-
 hw/block/xen-block.c  |  2 +-
 hw/ide/qdev.c |  2 +-
 hw/scsi/scsi-disk.c   | 13 +++---
 hw/scsi/scsi-generic.c|  2 +-
 hw/usb/dev-storage.c  |  2 +-
 include/block/block.h | 21 +-
 include/block/block_int.h |  4 ++
 include/hw/block/block.h  |  3 +-
 15 files changed, 151 insertions(+), 30 deletions(-)

-- 
2.21.0




[Qemu-devel] [PATCH v4 3/4] block/ide/scsi: Set BLK_PERM_SUPPORT_ZONED

2019-08-23 Thread Dmitry Fomichev
Added a new boolean argument to blkconf_apply_backend_options()
to let the common block code know whether the chosen block
backend can handle zoned block devices or not.

blkconf_apply_backend_options() then sets BLK_PERM_SUPPORT_ZONED
permission accordingly. The raw code can then use this permission
to allow or deny opening a zone device by a particular block driver.

Signed-off-by: Dmitry Fomichev 
Acked-by: Paul Durrant 
---
 hw/block/block.c |  8 ++--
 hw/block/fdc.c   |  5 +++--
 hw/block/nvme.c  |  2 +-
 hw/block/virtio-blk.c|  2 +-
 hw/block/xen-block.c |  2 +-
 hw/ide/qdev.c|  2 +-
 hw/scsi/scsi-disk.c  | 13 +++--
 hw/scsi/scsi-generic.c   |  2 +-
 hw/usb/dev-storage.c |  2 +-
 include/hw/block/block.h |  3 ++-
 10 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/hw/block/block.c b/hw/block/block.c
index bf56c7612b..23fbe4d567 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -86,7 +86,8 @@ void blkconf_blocksizes(BlockConf *conf)
 }
 
 bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
-   bool resizable, Error **errp)
+   bool resizable, bool zoned_support,
+   Error **errp)
 {
 BlockBackend *blk = conf->blk;
 BlockdevOnError rerror, werror;
@@ -98,9 +99,12 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool 
readonly,
 if (!readonly) {
 perm |= BLK_PERM_WRITE;
 }
+if (zoned_support) {
+perm |= BLK_PERM_SUPPORT_ZONED;
+}
 
 shared_perm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
-  BLK_PERM_GRAPH_MOD;
+  BLK_PERM_GRAPH_MOD | BLK_PERM_SUPPORT_ZONED;
 if (resizable) {
 shared_perm |= BLK_PERM_RESIZE;
 }
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index ac5d31e8c1..c5f41b3eb6 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -477,7 +477,7 @@ static void fd_change_cb(void *opaque, bool load, Error 
**errp)
 } else {
 if (!blkconf_apply_backend_options(drive->conf,
blk_is_read_only(drive->blk), false,
-   errp)) {
+   false, errp)) {
 return;
 }
 }
@@ -569,7 +569,8 @@ static void floppy_drive_realize(DeviceState *qdev, Error 
**errp)
 dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
 
-if (!blkconf_apply_backend_options(>conf, read_only, false, errp)) {
+if (!blkconf_apply_backend_options(>conf, read_only, false, false,
+  errp)) {
 return;
 }
 
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 12d8254250..07f08d0768 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1334,7 +1334,7 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
 }
 blkconf_blocksizes(>conf);
 if (!blkconf_apply_backend_options(>conf, blk_is_read_only(n->conf.blk),
-   false, errp)) {
+   false, false, errp)) {
 return;
 }
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 18851601cb..8be62903e2 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1127,7 +1127,7 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 
 if (!blkconf_apply_backend_options(>conf,
blk_is_read_only(conf->conf.blk), true,
-   errp)) {
+   false, errp)) {
 return;
 }
 s->original_wce = blk_enable_write_cache(conf->conf.blk);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index f77343db60..57fe970908 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -229,7 +229,7 @@ static void xen_block_realize(XenDevice *xendev, Error 
**errp)
 }
 
 if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY,
-   true, errp)) {
+   true, false, errp)) {
 return;
 }
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6fba6b62b8..a57a8f1a8f 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -200,7 +200,7 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind 
kind, Error **errp)
 }
 }
 if (!blkconf_apply_backend_options(>conf, kind == IDE_CD,
-   kind != IDE_CD, errp)) {
+   kind != IDE_CD, false, errp)) {
 return;
 }
 
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 915641a0f1..8a57caafd7 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2318,7 +2318,7 @@ static void scsi_disk_unit_attention_reported(SCSIDevice 
*dev)
 }
 }
 
-static void scsi_realize(SCSIDevice 

[Qemu-devel] [RFC PATCH 16/17] hw/timer: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/timer/a9gtimer.c | 4 ++--
 hw/timer/arm_mptimer.c  | 4 ++--
 hw/timer/arm_timer.c| 4 ++--
 hw/timer/armv7m_systick.c   | 2 +-
 hw/timer/aspeed_rtc.c   | 2 +-
 hw/timer/cadence_ttc.c  | 2 +-
 hw/timer/grlib_gptimer.c| 2 +-
 hw/timer/hpet.c | 2 +-
 hw/timer/imx_epit.c | 2 +-
 hw/timer/imx_gpt.c  | 2 +-
 hw/timer/lm32_timer.c   | 2 +-
 hw/timer/milkymist-sysctl.c | 2 +-
 hw/timer/mss-timer.c| 2 +-
 hw/timer/pl031.c| 2 +-
 hw/timer/stm32f2xx_timer.c  | 2 +-
 hw/timer/sun4v-rtc.c| 2 +-
 16 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index 75f1867174..ffdc78f383 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -258,7 +258,7 @@ static const MemoryRegionOps a9_gtimer_this_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const MemoryRegionOps a9_gtimer_ops = {
@@ -268,7 +268,7 @@ static const MemoryRegionOps a9_gtimer_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void a9_gtimer_reset(DeviceState *dev)
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 983e61847e..bf6295add1 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -194,7 +194,7 @@ static const MemoryRegionOps arm_thistimer_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const MemoryRegionOps timerblock_ops = {
@@ -204,7 +204,7 @@ static const MemoryRegionOps timerblock_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void timerblock_reset(TimerBlock *tb)
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
index c2e6211188..f95c897d05 100644
--- a/hw/timer/arm_timer.c
+++ b/hw/timer/arm_timer.c
@@ -267,7 +267,7 @@ static void sp804_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps sp804_ops = {
 .read = sp804_read,
 .write = sp804_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_sp804 = {
@@ -348,7 +348,7 @@ static void icp_pit_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps icp_pit_ops = {
 .read = icp_pit_read,
 .write = icp_pit_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void icp_pit_init(Object *obj)
diff --git a/hw/timer/armv7m_systick.c b/hw/timer/armv7m_systick.c
index 85d122dbcb..b8003e2962 100644
--- a/hw/timer/armv7m_systick.c
+++ b/hw/timer/armv7m_systick.c
@@ -193,7 +193,7 @@ static MemTxResult systick_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps systick_ops = {
 .read_with_attrs = systick_read,
 .write_with_attrs = systick_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
diff --git a/hw/timer/aspeed_rtc.c b/hw/timer/aspeed_rtc.c
index 5313017353..e3bd196dc0 100644
--- a/hw/timer/aspeed_rtc.c
+++ b/hw/timer/aspeed_rtc.c
@@ -131,7 +131,7 @@ static void aspeed_rtc_reset(DeviceState *d)
 static const MemoryRegionOps aspeed_rtc_ops = {
 .read = aspeed_rtc_read,
 .write = aspeed_rtc_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_aspeed_rtc = {
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 5e3128c1e3..6155d0055f 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -391,7 +391,7 @@ static void cadence_ttc_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps cadence_ttc_ops = {
 .read = cadence_ttc_read,
 .write = cadence_ttc_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void cadence_timer_reset(CadenceTimerState *s)
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
index 32dbf870d4..df84735197 

[Qemu-devel] [PATCH v4 2/4] raw: Recognize zoned backing devices

2019-08-23 Thread Dmitry Fomichev
The purpose of this patch is to recognize a zoned block device (ZBD)
when it is opened as a raw file. The new code initializes the zoned
model propery introduced by the previous commit.

This commit is Linux-specific as it gets the Zoned Block Device Model
value (none/host-managed/host-aware) from sysfs on the host.

In order to avoid code duplication in file-posix.c, a common helper
function is added to read values of sysfs entries under
/sys/block//queue. This way, the existing function that reads
the value of "max_segments" entry and the the new function that reads
"zoned" value both share the same helper code.

Signed-off-by: Dmitry Fomichev 
---
 block/file-posix.c | 74 ++
 block/raw-format.c |  8 +
 2 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index fbeb0068db..d9f2fc5e46 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1067,15 +1067,13 @@ static int sg_get_max_transfer_length(int fd)
 #endif
 }
 
-static int sg_get_max_segments(int fd)
+static int hdev_read_blk_queue_entry(int fd, const char *key,
+char *buf, int buf_len)
 {
 #ifdef CONFIG_LINUX
-char buf[32];
-const char *end;
 char *sysfspath = NULL;
 int ret;
 int sysfd = -1;
-long max_segments;
 struct stat st;
 
 if (fstat(fd, )) {
@@ -1083,23 +1081,45 @@ static int sg_get_max_segments(int fd)
 goto out;
 }
 
-sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-major(st.st_rdev), minor(st.st_rdev));
+sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
+major(st.st_rdev), minor(st.st_rdev), key);
 sysfd = open(sysfspath, O_RDONLY);
 if (sysfd == -1) {
 ret = -errno;
 goto out;
 }
 do {
-ret = read(sysfd, buf, sizeof(buf) - 1);
+ret = read(sysfd, buf, buf_len - 1);
 } while (ret == -1 && errno == EINTR);
 if (ret < 0) {
 ret = -errno;
-goto out;
 } else if (ret == 0) {
 ret = -EIO;
+}
+out:
+if (sysfd != -1) {
+close(sysfd);
+}
+g_free(sysfspath);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int sg_get_max_segments(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+const char *end;
+int ret;
+long max_segments;
+
+ret = hdev_read_blk_queue_entry(fd, "max_segments", buf, sizeof(buf));
+if (ret < 0) {
 goto out;
 }
+
 buf[ret] = 0;
 /* The file is ended with '\n', pass 'end' to accept that. */
 ret = qemu_strtol(buf, , 10, _segments);
@@ -1108,10 +1128,33 @@ static int sg_get_max_segments(int fd)
 }
 
 out:
-if (sysfd != -1) {
-close(sysfd);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int hdev_get_zoned_model(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+int ret;
+
+ret = hdev_read_blk_queue_entry(fd, "zoned", buf, sizeof(buf));
+if (ret < 0) {
+ret = BLK_ZONED_MODEL_NONE;
+goto out;
 }
-g_free(sysfspath);
+
+buf[ret - 1] = 0;
+ret = BLK_ZONED_MODEL_NONE;
+if (strcmp(buf, "host-managed") == 0) {
+ret = BLK_ZONED_MODEL_HM;
+} else if (strcmp(buf, "host-aware") == 0) {
+ret = BLK_ZONED_MODEL_HA;
+}
+
+out:
 return ret;
 #else
 return -ENOTSUP;
@@ -1121,9 +1164,10 @@ out:
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
+int ret;
 
 if (bs->sg) {
-int ret = sg_get_max_transfer_length(s->fd);
+ret = sg_get_max_transfer_length(s->fd);
 
 if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
 bs->bl.max_transfer = pow2floor(ret);
@@ -1133,6 +1177,12 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 if (ret > 0) {
 bs->bl.max_transfer = MIN(bs->bl.max_transfer, ret * 
getpagesize());
 }
+
+}
+
+ret = hdev_get_zoned_model(s->fd);
+if (ret >= 0) {
+bs->bl.zoned_model = ret;
 }
 
 raw_probe_alignment(bs, s->fd, errp);
diff --git a/block/raw-format.c b/block/raw-format.c
index 42c28cc29a..a606e4a7fe 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -369,6 +369,13 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 }
 
+static void raw_get_zoned_info(BlockDriverState *bs)
+{
+if (!bs->probed) {
+bs->bl.zoned_model = bs->file->bs->bl.zoned_model;
+}
+}
+
 static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
 PreallocMode prealloc, Error **errp)
 {
@@ -578,6 +585,7 @@ BlockDriver bdrv_raw = {
 .create_opts  = _create_opts,
 .bdrv_has_zero_init   = _has_zero_init,
 .bdrv_has_zero_init_truncate = _has_zero_init_truncate,
+.bdrv_get_zoned_info  = _get_zoned_info,
 .strong_runtime_opts  = 

[Qemu-devel] [PATCH v4 4/4] raw: Don't open ZBDs if backend can't handle them

2019-08-23 Thread Dmitry Fomichev
Abort opening a zoned device as a raw file in case the chosen
block backend driver lacks proper support for this type of
storage.

Signed-off-by: Dmitry Fomichev 
---
 block/file-posix.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index d9f2fc5e46..090e7c4d2f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2884,6 +2884,20 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t 
perm, uint64_t shared,
 goto fail;
 }
 }
+
+/*
+ * If we are opening a zoned block device, check if the backend
+ * driver can properly handle such devices, abort if not.
+ */
+if (bdrv_is_zoned(bs) &&
+(shared & BLK_PERM_SUPPORT_ZONED) &&
+!(perm & BLK_PERM_SUPPORT_ZONED)) {
+error_setg(errp,
+   "block backend driver doesn't support HM zoned devices");
+ret = -ENOTSUP;
+goto fail;
+}
+
 return 0;
 
 fail:
-- 
2.21.0




[Qemu-devel] [PATCH v4 2/4] raw: Recognize zoned backing devices

2019-08-23 Thread Dmitry Fomichev
The purpose of this patch is to recognize a zoned block device (ZBD)
when it is opened as a raw file. The new code initializes the zoned
model propery introduced by the previous commit.

This commit is Linux-specific as it gets the Zoned Block Device Model
value (none/host-managed/host-aware) from sysfs on the host.

In order to avoid code duplication in file-posix.c, a common helper
function is added to read values of sysfs entries under
/sys/block//queue. This way, the existing function that reads
the value of "max_segments" entry and the the new function that reads
"zoned" value both share the same helper code.

Signed-off-by: Dmitry Fomichev 
---
 block/file-posix.c | 74 ++
 block/raw-format.c |  8 +
 2 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index fbeb0068db..d9f2fc5e46 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1067,15 +1067,13 @@ static int sg_get_max_transfer_length(int fd)
 #endif
 }
 
-static int sg_get_max_segments(int fd)
+static int hdev_read_blk_queue_entry(int fd, const char *key,
+char *buf, int buf_len)
 {
 #ifdef CONFIG_LINUX
-char buf[32];
-const char *end;
 char *sysfspath = NULL;
 int ret;
 int sysfd = -1;
-long max_segments;
 struct stat st;
 
 if (fstat(fd, )) {
@@ -1083,23 +1081,45 @@ static int sg_get_max_segments(int fd)
 goto out;
 }
 
-sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-major(st.st_rdev), minor(st.st_rdev));
+sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
+major(st.st_rdev), minor(st.st_rdev), key);
 sysfd = open(sysfspath, O_RDONLY);
 if (sysfd == -1) {
 ret = -errno;
 goto out;
 }
 do {
-ret = read(sysfd, buf, sizeof(buf) - 1);
+ret = read(sysfd, buf, buf_len - 1);
 } while (ret == -1 && errno == EINTR);
 if (ret < 0) {
 ret = -errno;
-goto out;
 } else if (ret == 0) {
 ret = -EIO;
+}
+out:
+if (sysfd != -1) {
+close(sysfd);
+}
+g_free(sysfspath);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int sg_get_max_segments(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+const char *end;
+int ret;
+long max_segments;
+
+ret = hdev_read_blk_queue_entry(fd, "max_segments", buf, sizeof(buf));
+if (ret < 0) {
 goto out;
 }
+
 buf[ret] = 0;
 /* The file is ended with '\n', pass 'end' to accept that. */
 ret = qemu_strtol(buf, , 10, _segments);
@@ -1108,10 +1128,33 @@ static int sg_get_max_segments(int fd)
 }
 
 out:
-if (sysfd != -1) {
-close(sysfd);
+return ret;
+#else
+return -ENOTSUP;
+#endif
+}
+
+static int hdev_get_zoned_model(int fd)
+{
+#ifdef CONFIG_LINUX
+char buf[32];
+int ret;
+
+ret = hdev_read_blk_queue_entry(fd, "zoned", buf, sizeof(buf));
+if (ret < 0) {
+ret = BLK_ZONED_MODEL_NONE;
+goto out;
 }
-g_free(sysfspath);
+
+buf[ret - 1] = 0;
+ret = BLK_ZONED_MODEL_NONE;
+if (strcmp(buf, "host-managed") == 0) {
+ret = BLK_ZONED_MODEL_HM;
+} else if (strcmp(buf, "host-aware") == 0) {
+ret = BLK_ZONED_MODEL_HA;
+}
+
+out:
 return ret;
 #else
 return -ENOTSUP;
@@ -1121,9 +1164,10 @@ out:
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
+int ret;
 
 if (bs->sg) {
-int ret = sg_get_max_transfer_length(s->fd);
+ret = sg_get_max_transfer_length(s->fd);
 
 if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
 bs->bl.max_transfer = pow2floor(ret);
@@ -1133,6 +1177,12 @@ static void raw_refresh_limits(BlockDriverState *bs, 
Error **errp)
 if (ret > 0) {
 bs->bl.max_transfer = MIN(bs->bl.max_transfer, ret * 
getpagesize());
 }
+
+}
+
+ret = hdev_get_zoned_model(s->fd);
+if (ret >= 0) {
+bs->bl.zoned_model = ret;
 }
 
 raw_probe_alignment(bs, s->fd, errp);
diff --git a/block/raw-format.c b/block/raw-format.c
index 42c28cc29a..a606e4a7fe 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -369,6 +369,13 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 }
 
+static void raw_get_zoned_info(BlockDriverState *bs)
+{
+if (!bs->probed) {
+bs->bl.zoned_model = bs->file->bs->bl.zoned_model;
+}
+}
+
 static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
 PreallocMode prealloc, Error **errp)
 {
@@ -578,6 +585,7 @@ BlockDriver bdrv_raw = {
 .create_opts  = _create_opts,
 .bdrv_has_zero_init   = _has_zero_init,
 .bdrv_has_zero_init_truncate = _has_zero_init_truncate,
+.bdrv_get_zoned_info  = _get_zoned_info,
 .strong_runtime_opts  = 

[Qemu-devel] [RFC PATCH 15/17] hw/ssi: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/ssi/mss-spi.c   | 2 +-
 hw/ssi/pl022.c | 2 +-
 hw/ssi/stm32f2xx_spi.c | 2 +-
 hw/ssi/xilinx_spips.c  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 3050fabb69..914f90f3ad 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -361,7 +361,7 @@ static void spi_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps spi_ops = {
 .read = spi_read,
 .write = spi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 4
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index cade2e92a8..1501af2850 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -228,7 +228,7 @@ static void pl022_reset(DeviceState *dev)
 static const MemoryRegionOps pl022_ops = {
 .read = pl022_read,
 .write = pl022_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int pl022_post_load(void *opaque, int version_id)
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
index cd6e8443db..dbb109b2dc 100644
--- a/hw/ssi/stm32f2xx_spi.c
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -167,7 +167,7 @@ static void stm32f2xx_spi_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps stm32f2xx_spi_ops = {
 .read = stm32f2xx_spi_read,
 .write = stm32f2xx_spi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_stm32f2xx_spi = {
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index a309c712ca..e622e38f6d 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -1240,7 +1240,7 @@ static MemTxResult lqspi_write(void *opaque, hwaddr 
offset, uint64_t value,
 static const MemoryRegionOps lqspi_ops = {
 .read_with_attrs = lqspi_read,
 .write_with_attrs = lqspi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 4,
 .max_access_size = 4,
-- 
2.23.0




[Qemu-devel] [PATCH v4 1/4] block: Add zoned device model property

2019-08-23 Thread Dmitry Fomichev
This commit adds Zoned Device Model (as defined in T10 ZBC and
T13 ZAC standards) as a block driver property, along with some
useful access functions.

A new backend driver permission, BLK_PERM_SUPPORT_ZONED, is also
introduced. Only the drivers having this permission will be allowed
to open zoned block devices.

No code is added yet to initialize or check the value of this new
property, therefore this commit doesn't change any functionality.

Signed-off-by: Dmitry Fomichev 
---
 block.c   | 19 +++
 include/block/block.h | 21 -
 include/block/block_int.h |  4 
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 874a29a983..6dd4cecded 100644
--- a/block.c
+++ b/block.c
@@ -4679,6 +4679,25 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t 
*nb_sectors_ptr)
 *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
 }
 
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs)
+{
+if (bs->drv->bdrv_get_zoned_info) {
+bs->drv->bdrv_get_zoned_info(bs);
+}
+
+return bs->bl.zoned_model;
+}
+
+uint8_t bdrv_is_zoned(BlockDriverState *bs)
+{
+/*
+ * Host Aware zone devices are supposed to be able to work
+ * just like regular block devices. Thus, we only consider
+ * Host Managed devices to be zoned here.
+ */
+return bdrv_get_zoned_model(bs) == BLK_ZONED_MODEL_HM;
+}
+
 bool bdrv_is_sg(BlockDriverState *bs)
 {
 return bs->sg;
diff --git a/include/block/block.h b/include/block/block.h
index 124ad40809..238c0f5ed7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -271,18 +271,35 @@ enum {
  */
 BLK_PERM_GRAPH_MOD  = 0x10,
 
+/** This permission is required to open zoned block devices. */
+BLK_PERM_SUPPORT_ZONED  = 0x20,
+
 BLK_PERM_ALL= 0x1f,
 
 DEFAULT_PERM_PASSTHROUGH= BLK_PERM_CONSISTENT_READ
  | BLK_PERM_WRITE
  | BLK_PERM_WRITE_UNCHANGED
- | BLK_PERM_RESIZE,
+ | BLK_PERM_RESIZE
+ | BLK_PERM_SUPPORT_ZONED,
 
 DEFAULT_PERM_UNCHANGED  = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
 };
 
 char *bdrv_perm_names(uint64_t perm);
 
+/*
+ * Known zoned device models.
+ *
+ * TODO For a Linux host, it could be preferrable to include
+ * /usr/include/linux/blkzoned.h instead of defining ZBD-specific
+ * values here.
+ */
+enum blk_zoned_model {
+BLK_ZONED_MODEL_NONE, /* Regular block device */
+BLK_ZONED_MODEL_HA,   /* Host-aware zoned block device */
+BLK_ZONED_MODEL_HM,   /* Host-managed zoned block device */
+};
+
 /* disk I/O throttling */
 void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
@@ -359,6 +376,8 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
 BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
BlockDriverState *in_bs, Error **errp);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
+uint8_t bdrv_get_zoned_model(BlockDriverState *bs);
+uint8_t bdrv_is_zoned(BlockDriverState *bs);
 void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_change_backing_file(BlockDriverState *bs,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index ceec8c2f56..91496e8149 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -415,6 +415,7 @@ struct BlockDriver {
 bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
 
 void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
+void (*bdrv_get_zoned_info)(BlockDriverState *bs);
 
 /*
  * Returns 1 if newly created images are guaranteed to contain only
@@ -620,6 +621,9 @@ typedef struct BlockLimits {
 
 /* maximum number of iovec elements */
 int max_iov;
+
+/* Zoned device model. Zero value indicates a regular block device */
+uint8_t zoned_model;
 } BlockLimits;
 
 typedef struct BdrvOpBlocker BdrvOpBlocker;
-- 
2.21.0




[Qemu-devel] [RFC PATCH 13/17] hw/pci-host: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/pci-host/q35.c   | 2 +-
 hw/pci-host/versatile.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 158d270b9f..485e2a02af 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -289,7 +289,7 @@ static void tseg_blackhole_write(void *opaque, hwaddr addr, 
uint64_t val,
 static const MemoryRegionOps tseg_blackhole_ops = {
 .read = tseg_blackhole_read,
 .write = tseg_blackhole_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
 .impl.min_access_size = 4,
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index b731d0544f..df7212237d 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -243,7 +243,7 @@ static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps pci_vpb_reg_ops = {
 .read = pci_vpb_reg_read,
 .write = pci_vpb_reg_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
@@ -309,7 +309,7 @@ static uint64_t pci_vpb_config_read(void *opaque, hwaddr 
addr,
 static const MemoryRegionOps pci_vpb_config_ops = {
 .read = pci_vpb_config_read,
 .write = pci_vpb_config_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 14/17] hw/sd: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/sd/pl181.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 8033fe455d..f19d8764e8 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -451,7 +451,7 @@ static void pl181_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl181_ops = {
 .read = pl181_read,
 .write = pl181_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl181_reset(DeviceState *d)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 12/17] hw/net: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/net/allwinner_emac.c | 2 +-
 hw/net/imx_fec.c| 2 +-
 hw/net/lan9118.c| 4 ++--
 hw/net/lance.c  | 2 +-
 hw/net/smc91c111.c  | 2 +-
 hw/net/stellaris_enet.c | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index e055a661c4..84b48b1774 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -421,7 +421,7 @@ static void aw_emac_set_link(NetClientState *nc)
 static const MemoryRegionOps aw_emac_mem_ops = {
 .read = aw_emac_read,
 .write = aw_emac_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index bd99236864..0f3dd7e8e4 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1285,7 +1285,7 @@ static const MemoryRegionOps imx_eth_ops = {
 .write = imx_eth_write,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
-.endianness= DEVICE_NATIVE_ENDIAN,
+.endianness= DEVICE_LITTLE_ENDIAN,
 };
 
 static void imx_eth_cleanup(NetClientState *nc)
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 8bba2a8056..498a6acfe9 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1308,13 +1308,13 @@ static uint64_t lan9118_16bit_mode_read(void *opaque, 
hwaddr offset,
 static const MemoryRegionOps lan9118_mem_ops = {
 .read = lan9118_readl,
 .write = lan9118_writel,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const MemoryRegionOps lan9118_16bit_mem_ops = {
 .read = lan9118_16bit_mode_read,
 .write = lan9118_16bit_mode_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static NetClientInfo net_lan9118_info = {
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 6631e2a4e0..27dfa3a688 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -76,7 +76,7 @@ static uint64_t lance_mem_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps lance_mem_ops = {
 .read = lance_mem_read,
 .write = lance_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 2,
 .max_access_size = 2,
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index e574635969..50cd6fc140 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -760,7 +760,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
 .write = smc91c111_writefn,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static NetClientInfo net_smc91c111_info = {
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 3aca2a09f3..5dfd43b3f2 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -459,7 +459,7 @@ static void stellaris_enet_write(void *opaque, hwaddr 
offset,
 static const MemoryRegionOps stellaris_enet_ops = {
 .read = stellaris_enet_read,
 .write = stellaris_enet_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void stellaris_enet_reset(DeviceState *dev)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 10/17] hw/isa: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/isa/vt82c686.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 50bd28fa82..400f2b3c87 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -109,7 +109,7 @@ static uint64_t superio_ioport_readb(void *opaque, hwaddr 
addr, unsigned size)
 static const MemoryRegionOps superio_ops = {
 .read = superio_ioport_readb,
 .write = superio_ioport_writeb,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
-- 
2.23.0




Re: [Qemu-devel] [PATCH v9 14/20] memory: Access MemoryRegion with endianness

2019-08-23 Thread Richard Henderson
On 8/23/19 11:36 AM, Tony Nguyen wrote:
> Preparation for collapsing the two byte swaps adjust_endianness and
> handle_bswap into the former.
> 
> Call memory_region_dispatch_{read|write} with endianness encoded into
> the "MemOp op" operand.
> 
> This patch does not change any behaviour as
> memory_region_dispatch_{read|write} is yet to handle the endianness.
> 
> Once it does handle endianness, callers with byte swaps can collapse
> them into adjust_endianness.
> 
> Signed-off-by: Tony Nguyen 
> ---
>  accel/tcg/cputlb.c   |  8 ++--
>  exec.c   | 13 +++--
>  hw/intc/armv7m_nvic.c| 15 ---
>  hw/s390x/s390-pci-inst.c |  6 --
>  hw/vfio/pci-quirks.c |  5 +++--
>  hw/virtio/virtio-pci.c   |  6 --
>  include/exec/memory.h|  3 +++
>  memory.c | 18 ++
>  memory_ldst.inc.c| 24 ++--
>  9 files changed, 75 insertions(+), 23 deletions(-)

Reviewed-by: Richard Henderson 


r~



[Qemu-devel] [RFC PATCH 09/17] hw/intc: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/intc/arm_gic.c | 12 ++--
 hw/intc/arm_gicv3.c   |  4 ++--
 hw/intc/etraxfs_pic.c |  2 +-
 hw/intc/imx_avic.c|  2 +-
 hw/intc/imx_gpcv2.c   |  2 +-
 hw/intc/pl190.c   |  2 +-
 hw/intc/puv3_intc.c   |  2 +-
 7 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 7af591daac..abcadc9af4 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -2000,38 +2000,38 @@ static const MemoryRegionOps gic_ops[2] = {
 {
 .read_with_attrs = gic_dist_read,
 .write_with_attrs = gic_dist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gic_thiscpu_read,
 .write_with_attrs = gic_thiscpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };
 
 static const MemoryRegionOps gic_cpu_ops = {
 .read_with_attrs = gic_do_cpu_read,
 .write_with_attrs = gic_do_cpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const MemoryRegionOps gic_virt_ops[2] = {
 {
 .read_with_attrs = gic_thiscpu_hyp_read,
 .write_with_attrs = gic_thiscpu_hyp_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gic_thisvcpu_read,
 .write_with_attrs = gic_thisvcpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };
 
 static const MemoryRegionOps gic_viface_ops = {
 .read_with_attrs = gic_do_hyp_read,
 .write_with_attrs = gic_do_hyp_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void arm_gic_realize(DeviceState *dev, Error **errp)
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
index 66eaa97198..9b4d5bad69 100644
--- a/hw/intc/arm_gicv3.c
+++ b/hw/intc/arm_gicv3.c
@@ -352,12 +352,12 @@ static const MemoryRegionOps gic_ops[] = {
 {
 .read_with_attrs = gicv3_dist_read,
 .write_with_attrs = gicv3_dist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gicv3_redist_read,
 .write_with_attrs = gicv3_redist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };
 
diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c
index 77f652acec..5895b671b1 100644
--- a/hw/intc/etraxfs_pic.c
+++ b/hw/intc/etraxfs_pic.c
@@ -112,7 +112,7 @@ static void pic_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps pic_ops = {
 .read = pic_read,
 .write = pic_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4
diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index 63fc602a1a..15ed512e86 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -310,7 +310,7 @@ static void imx_avic_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps imx_avic_ops = {
 .read = imx_avic_read,
 .write = imx_avic_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void imx_avic_reset(DeviceState *dev)
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
index 17007a4078..3df4a443b8 100644
--- a/hw/intc/imx_gpcv2.c
+++ b/hw/intc/imx_gpcv2.c
@@ -65,7 +65,7 @@ static void imx_gpcv2_write(void *opaque, hwaddr offset,
 static const struct MemoryRegionOps imx_gpcv2_ops = {
 .read = imx_gpcv2_read,
 .write = imx_gpcv2_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 /*
  * Our device would not work correctly if the guest was doing
diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c
index e3bd3dd121..1b474d25b9 100644
--- a/hw/intc/pl190.c
+++ b/hw/intc/pl190.c
@@ -222,7 +222,7 @@ static void pl190_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl190_ops = {
 .read = pl190_read,
 .write = pl190_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl190_reset(DeviceState *d)
diff --git a/hw/intc/puv3_intc.c b/hw/intc/puv3_intc.c

[Qemu-devel] [RFC PATCH 01/17] hw/audio: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/audio/cs4231.c  | 2 +-
 hw/audio/marvell_88w8618.c | 2 +-
 hw/audio/milkymist-ac97.c  | 2 +-
 hw/audio/pl041.c   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c
index b5d3e895ce..1ff9093efa 100644
--- a/hw/audio/cs4231.c
+++ b/hw/audio/cs4231.c
@@ -133,7 +133,7 @@ static void cs_mem_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps cs_mem_ops = {
 .read = cs_mem_read,
 .write = cs_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static const VMStateDescription vmstate_cs4231 = {
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index 883ef74c8b..da1ab89ce6 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -242,7 +242,7 @@ static void mv88w8618_audio_reset(DeviceState *d)
 static const MemoryRegionOps mv88w8618_audio_ops = {
 .read = mv88w8618_audio_read,
 .write = mv88w8618_audio_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void mv88w8618_audio_init(Object *obj)
diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c
index 6d409eff1b..897dfff85a 100644
--- a/hw/audio/milkymist-ac97.c
+++ b/hw/audio/milkymist-ac97.c
@@ -177,7 +177,7 @@ static const MemoryRegionOps ac97_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static void ac97_in_cb(void *opaque, int avail_b)
diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c
index c30417d46d..5803bfcf0c 100644
--- a/hw/audio/pl041.c
+++ b/hw/audio/pl041.c
@@ -522,7 +522,7 @@ static void pl041_device_reset(DeviceState *d)
 static const MemoryRegionOps pl041_ops = {
 .read = pl041_read,
 .write = pl041_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl041_init(Object *obj)
-- 
2.23.0




Re: [Qemu-devel] [PATCH v9 16/20] memory: Single byte swap along the I/O path

2019-08-23 Thread Richard Henderson
On 8/23/19 11:36 AM, Tony Nguyen wrote:
> Now that MemOp has been pushed down into the memory API, and
> callers are encoding endianness, we can collapse byte swaps
> along the I/O path into the accelerator and target independent
> adjust_endianness.
> 
> Collapsing byte swaps along the I/O path enables additional endian
> inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant
> byte swaps cancelling out.
> 
> Suggested-by: Richard Henderson 
> Signed-off-by: Tony Nguyen 
> ---
>  accel/tcg/cputlb.c | 42 ++--
>  exec.c | 17 +++-
>  hw/virtio/virtio-pci.c | 10 +++
>  memory.c   | 33 --
>  memory_ldst.inc.c  | 63 --
>  5 files changed, 23 insertions(+), 142 deletions(-)

Reviewed-by: Richard Henderson 


r~




[Qemu-devel] [RFC PATCH 00/17] Declare device little or big endian

2019-08-23 Thread Tony Nguyen
This series is an attempt to re-declare devices with DEVICE_NATIVE_ENDIAN as
DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN.

This clean up was split out from an earlier series which collapsed byte swaps
along the I/O path.

On Wed, 7 Aug 2019 at 12:42, Paolo Bonzini wrote:
> On 07/08/19 10:31, tony.nguyen@bt wrote:
>>
>> Device realizing code with MemorRegionOps endianness as
>> DEVICE_NATIVE_ENDIAN is not common code.
>> 
>> Corrected devices were identified by making the declaration of
>> DEVICE_NATIVE_ENDIAN conditional upon NEED_CPU_H and then listing
>> what failed to compile.
>
> The general approach makes sense.  However, most of these should not be
> DEVICE_NATIVE_ENDIAN.  I can help with some of them.

An RFC as most devices I have never heard of... a collective effort is needed =)

On Fri, 16 Aug 2019 at 13:02, Peter Maydell wrote:
> OTOH it's worth noting that it's quite likely that most of
> the implementations of these DEVICE_NATIVE_ENDIAN devices
> picked it in an equally naive way, by just copying some other
> device's code...

I am starting off with the following *naive* approach.

For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

Please help spot devices which are genuinely native endian.

Thanks!

Tony Nguyen (17):
  hw/audio: Declare device little or big endian
  hw/block: Declare device little or big endian
  hw/char: Declare device little or big endian
  hw/display: Declare device little or big endian
  hw/dma: Declare device little or big endian
  hw/gpio: Declare device little or big endian
  hw/i2c: Declare device little or big endian
  hw/input: Declare device little or big endian
  hw/intc: Declare device little or big endian
  hw/isa: Declare device little or big endian
  hw/misc: Declare device little or big endian
  hw/net: Declare device little or big endian
  hw/pci-host: Declare device little or big endian
  hw/sd: Declare device little or big endian
  hw/ssi: Declare device little or big endian
  hw/timer: Declare device little or big endian
  build: Correct non-common common-obj-* to obj-*

 hw/audio/Makefile.objs  |  3 ++-
 hw/audio/cs4231.c   |  2 +-
 hw/audio/marvell_88w8618.c  |  2 +-
 hw/audio/milkymist-ac97.c   |  2 +-
 hw/audio/pl041.c|  2 +-
 hw/block/Makefile.objs  |  6 +++---
 hw/block/onenand.c  |  2 +-
 hw/char/Makefile.objs   |  4 ++--
 hw/char/cadence_uart.c  |  2 +-
 hw/char/escc.c  |  2 +-
 hw/char/etraxfs_ser.c   |  2 +-
 hw/char/grlib_apbuart.c |  2 +-
 hw/char/imx_serial.c|  2 +-
 hw/char/lm32_uart.c |  2 +-
 hw/char/milkymist-uart.c|  2 +-
 hw/char/pl011.c |  2 +-
 hw/core/Makefile.objs   |  2 +-
 hw/display/Makefile.objs|  6 +++---
 hw/display/pl110.c  |  2 +-
 hw/display/tc6393xb.c   |  2 +-
 hw/dma/Makefile.objs|  6 +++---
 hw/dma/bcm2835_dma.c|  4 ++--
 hw/dma/etraxfs_dma.c|  2 +-
 hw/dma/pl080.c  |  2 +-
 hw/dma/pl330.c  |  2 +-
 hw/dma/puv3_dma.c   |  2 +-
 hw/dma/sparc32_dma.c|  2 +-
 hw/gpio/Makefile.objs   |  2 +-
 hw/gpio/pl061.c |  2 +-
 hw/gpio/zaurus.c|  2 +-
 hw/i2c/Makefile.objs|  2 +-
 hw/i2c/imx_i2c.c|  2 +-
 hw/i2c/mpc_i2c.c|  2 +-
 hw/i2c/versatile_i2c.c  |  2 +-
 hw/input/Makefile.objs  |  2 +-
 hw/input/pl050.c|  2 +-
 hw/intc/Makefile.objs   |  6 +++---
 hw/intc/arm_gic.c   | 12 ++--
 hw/intc/arm_gicv3.c |  4 ++--
 hw/intc/etraxfs_pic.c   |  2 +-
 hw/intc/imx_avic.c  |  2 +-
 hw/intc/imx_gpcv2.c |  2 +-
 hw/intc/pl190.c |  2 +-
 hw/intc/puv3_intc.c |  2 +-
 hw/ipack/Makefile.objs  |  2 +-
 hw/isa/vt82c686.c   |  2 +-
 hw/misc/Makefile.objs   | 10 +-
 hw/misc/a9scu.c |  2 +-
 hw/misc/applesmc.c  |  6 +++---
 hw/misc/arm11scu.c  |  2 +-
 hw/misc/arm_l2x0.c  |  2 +-
 hw/misc/puv3_pm.c   |  2 +-
 hw/net/Makefile.objs|  2 +-
 hw/net/allwinner_emac.c |  2 +-
 hw/net/imx_fec.c|  2 +-
 hw/net/lan9118.c|  4 ++--
 hw/net/lance.c  |  2 +-
 hw/net/smc91c111.c  |  2 +-
 hw/net/stellaris_enet.c |  2 +-
 hw/pci-host/Makefile.objs   |  2 +-
 hw/pci-host/q35.c   |  2 +-
 hw/pci-host/versatile.c |  4 ++--
 hw/scsi/Makefile.objs   |  2 +-
 hw/sd/pl181.c   |  2 +-
 hw/ssi/Makefile.objs|  2 +-
 hw/ssi/mss-spi.c|  2 +-
 hw/ssi/pl022.c  |  2 +-
 

[Qemu-devel] [RFC PATCH 07/17] hw/i2c: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/i2c/imx_i2c.c   | 2 +-
 hw/i2c/mpc_i2c.c   | 2 +-
 hw/i2c/versatile_i2c.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index 30b9aea247..cc2689d967 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -278,7 +278,7 @@ static const MemoryRegionOps imx_i2c_ops = {
 .write = imx_i2c_write,
 .valid.min_access_size = 1,
 .valid.max_access_size = 2,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription imx_i2c_vmstate = {
diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
index 0aa1be3ce7..b71b5ff7d5 100644
--- a/hw/i2c/mpc_i2c.c
+++ b/hw/i2c/mpc_i2c.c
@@ -306,7 +306,7 @@ static const MemoryRegionOps i2c_ops = {
 .read =  mpc_i2c_read,
 .write =  mpc_i2c_write,
 .valid.max_access_size = 1,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static const VMStateDescription mpc_i2c_vmstate = {
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
index 1ac2a6f59a..c92d3b115c 100644
--- a/hw/i2c/versatile_i2c.c
+++ b/hw/i2c/versatile_i2c.c
@@ -77,7 +77,7 @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps versatile_i2c_ops = {
 .read = versatile_i2c_read,
 .write = versatile_i2c_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void versatile_i2c_init(Object *obj)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 17/17] build: Correct non-common common-obj-* to obj-*

2019-08-23 Thread Tony Nguyen
Device realizing code with MemorRegionOps endianness as
DEVICE_NATIVE_ENDIAN is not common code.

Corrected devices were identified by making the declaration of
DEVICE_NATIVE_ENDIAN conditional upon NEED_CPU_H and then listing
what failed to compile.

Signed-off-by: Tony Nguyen 
---
 hw/audio/Makefile.objs|  3 ++-
 hw/block/Makefile.objs|  6 +++---
 hw/char/Makefile.objs |  4 ++--
 hw/core/Makefile.objs |  2 +-
 hw/display/Makefile.objs  |  6 +++---
 hw/dma/Makefile.objs  |  6 +++---
 hw/gpio/Makefile.objs |  2 +-
 hw/i2c/Makefile.objs  |  2 +-
 hw/input/Makefile.objs|  2 +-
 hw/intc/Makefile.objs |  6 +++---
 hw/ipack/Makefile.objs|  2 +-
 hw/misc/Makefile.objs | 10 +-
 hw/net/Makefile.objs  |  2 +-
 hw/pci-host/Makefile.objs |  2 +-
 hw/scsi/Makefile.objs |  2 +-
 hw/ssi/Makefile.objs  |  2 +-
 hw/timer/Makefile.objs|  6 +++---
 hw/virtio/Makefile.objs   |  2 +-
 18 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
index 63db383709..13133b412d 100644
--- a/hw/audio/Makefile.objs
+++ b/hw/audio/Makefile.objs
@@ -5,7 +5,8 @@ common-obj-$(CONFIG_AC97) += ac97.o
 common-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o
 common-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o
 common-obj-$(CONFIG_CS4231A) += cs4231a.o
-common-obj-$(CONFIG_HDA) += intel-hda.o hda-codec.o
+common-obj-$(CONFIG_HDA) += hda-codec.o
+obj-$(CONFIG_HDA) += intel-hda.o
 
 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_WM8750) += wm8750.o
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index f5f643f0cc..04ed4d7722 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -1,9 +1,9 @@
 common-obj-y += block.o cdrom.o hd-geometry.o
-common-obj-$(CONFIG_FDC) += fdc.o
+obj-$(CONFIG_FDC) += fdc.o
 common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
-common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
-common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
+obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
+obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen-block.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 02d8a66925..215c02b752 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -1,7 +1,6 @@
 common-obj-$(CONFIG_IPACK) += ipoctal232.o
 common-obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o
-common-obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_ISA_BUS) += parallel-isa.o
 common-obj-$(CONFIG_PL011) += pl011.o
 common-obj-$(CONFIG_SERIAL) += serial.o
@@ -9,7 +8,6 @@ common-obj-$(CONFIG_SERIAL_ISA) += serial-isa.o
 common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
 common-obj-$(CONFIG_SERIAL_PCI_MULTI) += serial-pci-multi.o
 common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
-common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
 common-obj-$(CONFIG_XEN) += xen_console.o
 common-obj-$(CONFIG_CADENCE) += cadence_uart.o
 
@@ -21,6 +19,8 @@ obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o
+obj-$(CONFIG_PARALLEL) += parallel.o
+obj-$(CONFIG_XILINX) += xilinx_uartlite.o
 
 common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index b49f880a0c..6ee184a6c4 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -9,7 +9,7 @@ common-obj-y += hotplug.o
 common-obj-$(CONFIG_SOFTMMU) += nmi.o
 common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
 
-common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
+obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
 common-obj-$(CONFIG_PTIMER) += ptimer.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index a64998fc7b..facc1d4448 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -8,7 +8,7 @@ common-obj-$(CONFIG_ADS7846) += ads7846.o
 common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
 common-obj-$(call 
land,$(CONFIG_VGA_CIRRUS),$(CONFIG_VGA_ISA))+=cirrus_vga_isa.o
 common-obj-$(CONFIG_G364FB) += g364fb.o
-common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
+obj-$(CONFIG_JAZZ_LED) += jazz_led.o
 common-obj-$(CONFIG_PL110) += pl110.o
 common-obj-$(CONFIG_SII9022) += sii9022.o
 common-obj-$(CONFIG_SSD0303) += ssd0303.o
@@ -17,12 +17,12 @@ common-obj-$(CONFIG_XEN) += xenfb.o
 
 common-obj-$(CONFIG_VGA_PCI) += vga-pci.o
 common-obj-$(CONFIG_VGA_ISA) += vga-isa.o
-common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
+obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
 common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
 common-obj-$(CONFIG_BOCHS_DISPLAY) += bochs-display.o
 
 common-obj-$(CONFIG_BLIZZARD) += blizzard.o
-common-obj-$(CONFIG_EXYNOS4) += 

Re: [Qemu-devel] [PATCH v9 00/20] Invert Endian bit in SPARCv9 MMU TTE

2019-08-23 Thread Richard Henderson
On 8/23/19 5:25 AM, tony.ngu...@bt.com wrote:
> Frustratingly, I keep getting blocked.

Whee!  They have all arrived and applied correctly.
Thanks for your persistence.

r~



[Qemu-devel] [RFC PATCH 06/17] hw/gpio: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/gpio/pl061.c  | 2 +-
 hw/gpio/zaurus.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index 2a828260bd..25371d6c5a 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -341,7 +341,7 @@ static void pl061_set_irq(void * opaque, int irq, int level)
 static const MemoryRegionOps pl061_ops = {
 .read = pl061_read,
 .write = pl061_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl061_luminary_init(Object *obj)
diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
index 9a12c68342..608564 100644
--- a/hw/gpio/zaurus.c
+++ b/hw/gpio/zaurus.c
@@ -157,7 +157,7 @@ static void scoop_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps scoop_ops = {
 .read = scoop_read,
 .write = scoop_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void scoop_gpio_set(void *opaque, int line, int level)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 11/17] hw/misc: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/misc/a9scu.c| 2 +-
 hw/misc/applesmc.c | 6 +++---
 hw/misc/arm11scu.c | 2 +-
 hw/misc/arm_l2x0.c | 2 +-
 hw/misc/puv3_pm.c  | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/misc/a9scu.c b/hw/misc/a9scu.c
index 45c91db303..59335ca72f 100644
--- a/hw/misc/a9scu.c
+++ b/hw/misc/a9scu.c
@@ -96,7 +96,7 @@ static void a9_scu_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps a9_scu_ops = {
 .read = a9_scu_read,
 .write = a9_scu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void a9_scu_reset(DeviceState *dev)
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 24d57e8677..fb39837b7f 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -285,7 +285,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
 static const MemoryRegionOps applesmc_data_io_ops = {
 .write = applesmc_io_data_write,
 .read = applesmc_io_data_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -295,7 +295,7 @@ static const MemoryRegionOps applesmc_data_io_ops = {
 static const MemoryRegionOps applesmc_cmd_io_ops = {
 .write = applesmc_io_cmd_write,
 .read = applesmc_io_cmd_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -305,7 +305,7 @@ static const MemoryRegionOps applesmc_cmd_io_ops = {
 static const MemoryRegionOps applesmc_err_io_ops = {
 .write = applesmc_io_err_write,
 .read = applesmc_io_err_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c
index 3023284d6f..dd690dc985 100644
--- a/hw/misc/arm11scu.c
+++ b/hw/misc/arm11scu.c
@@ -58,7 +58,7 @@ static void mpcore_scu_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps mpcore_scu_ops = {
 .read = mpcore_scu_read,
 .write = mpcore_scu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void arm11_scu_realize(DeviceState *dev, Error **errp)
diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c
index af2c7af4a0..cd1747b7a1 100644
--- a/hw/misc/arm_l2x0.c
+++ b/hw/misc/arm_l2x0.c
@@ -159,7 +159,7 @@ static void l2x0_priv_reset(DeviceState *dev)
 static const MemoryRegionOps l2x0_mem_ops = {
 .read = l2x0_priv_read,
 .write = l2x0_priv_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
  };
 
 static void l2x0_priv_init(Object *obj)
diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c
index c213500d9c..b04950ecb9 100644
--- a/hw/misc/puv3_pm.c
+++ b/hw/misc/puv3_pm.c
@@ -117,7 +117,7 @@ static const MemoryRegionOps puv3_pm_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void puv3_pm_realize(DeviceState *dev, Error **errp)
-- 
2.23.0




[Qemu-devel] [RFC PATCH 05/17] hw/dma: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/dma/bcm2835_dma.c | 4 ++--
 hw/dma/etraxfs_dma.c | 2 +-
 hw/dma/pl080.c   | 2 +-
 hw/dma/pl330.c   | 2 +-
 hw/dma/puv3_dma.c| 2 +-
 hw/dma/sparc32_dma.c | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c
index 192bd377a0..550e67f686 100644
--- a/hw/dma/bcm2835_dma.c
+++ b/hw/dma/bcm2835_dma.c
@@ -290,7 +290,7 @@ static void bcm2835_dma15_write(void *opaque, hwaddr 
offset, uint64_t value,
 static const MemoryRegionOps bcm2835_dma0_ops = {
 .read = bcm2835_dma0_read,
 .write = bcm2835_dma0_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
@@ -298,7 +298,7 @@ static const MemoryRegionOps bcm2835_dma0_ops = {
 static const MemoryRegionOps bcm2835_dma15_ops = {
 .read = bcm2835_dma15_read,
 .write = bcm2835_dma15_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
diff --git a/hw/dma/etraxfs_dma.c b/hw/dma/etraxfs_dma.c
index 47e1c6df12..b4e3f83ca4 100644
--- a/hw/dma/etraxfs_dma.c
+++ b/hw/dma/etraxfs_dma.c
@@ -700,7 +700,7 @@ dma_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps dma_ops = {
.read = dma_read,
.write = dma_write,
-   .endianness = DEVICE_NATIVE_ENDIAN,
+   .endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 4
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 52ba23f4bf..cbdd1849cd 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -350,7 +350,7 @@ static void pl080_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl080_ops = {
 .read = pl080_read,
 .write = pl080_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl080_reset(DeviceState *dev)
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index f2bb2d9ac1..a9216680ef 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1496,7 +1496,7 @@ static uint64_t pl330_iomem_read(void *opaque, hwaddr 
offset,
 static const MemoryRegionOps pl330_ops = {
 .read = pl330_iomem_read,
 .write = pl330_iomem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/dma/puv3_dma.c b/hw/dma/puv3_dma.c
index 5488d388a9..1577056715 100644
--- a/hw/dma/puv3_dma.c
+++ b/hw/dma/puv3_dma.c
@@ -74,7 +74,7 @@ static const MemoryRegionOps puv3_dma_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void puv3_dma_realize(DeviceState *dev, Error **errp)
diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 0e5bbcdc7f..bf76f2e558 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -226,7 +226,7 @@ static void dma_mem_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps dma_mem_ops = {
 .read = dma_mem_read,
 .write = dma_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
-- 
2.23.0




[Qemu-devel] [PATCH 1/2] block: Let blockdev-create return 0 on success

2019-08-23 Thread Max Reitz
Block drivers should let their .bdrv_co_create() implementation return a
non-negative value to indicate success.  However, jobs should return
exactly 0.  Thus, we need to translate positive return values to 0 in
blockdev_create_run().

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
---
 block/create.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/block/create.c b/block/create.c
index 1bd00ed5f8..4b23672e1b 100644
--- a/block/create.c
+++ b/block/create.c
@@ -48,7 +48,8 @@ static int coroutine_fn blockdev_create_run(Job *job, Error 
**errp)
 
 qapi_free_BlockdevCreateOptions(s->opts);
 
-return ret;
+/* Jobs must return 0 to indicate success */
+return ret < 0 ? ret : 0;
 }
 
 static const JobDriver blockdev_create_job_driver = {
-- 
2.21.0




[Qemu-devel] [RFC PATCH 08/17] hw/input: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/input/pl050.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 1123037b38..873f44abad 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -139,7 +139,7 @@ static void pl050_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl050_ops = {
 .read = pl050_read,
 .write = pl050_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl050_realize(DeviceState *dev, Error **errp)
-- 
2.23.0




Re: [Qemu-devel] [PATCH 1/1] protocol: Add NBD_CMD_FLAG_FAST_ZERO

2019-08-23 Thread Eric Blake
On 8/23/19 1:48 PM, Wouter Verhelst wrote:
> On Fri, Aug 23, 2019 at 09:34:26AM -0500, Eric Blake wrote:
>> +- bit 4, `NBD_CMD_FLAG_FAST_ZERO`; valid during
>> +  `NBD_CMD_WRITE_ZEROES`. If set, but the server cannot perform the
>> +  write zeroes any faster than it would for an equivalent
>> +  `NBD_CMD_WRITE`,
> 
> One way of fulfilling the letter of this requirement but not its spirit
> could be to have background writes; that is, the server makes a note
> that the zeroed region should contain zeroes, makes an error-free reply
> to the client, and then starts updating things in the background (with
> proper layering so that an NBD_CMD_READ would see zeroes).

For writes, this should still be viable IF the server can also cancel
that background write of zeroes in favor of a foreground request for
actual data to be written to the same offset.  In other words, as long
as the behavior to the client is "as if" there is no duplicated I/O
cost, the zero appears fast, even if it kicked off a long-running async
process to actually accomplish it.

> 
> This could negatively impact performance after that command to the
> effect that syncing the device would be slower rather than faster, if
> not done right.

Oh. I see - for flush requests, you're worried about the cost of the
flush forcing the I/O for the background zero to complete before flush
can return.

Perhaps that merely means that a client using fast zero requests as a
means of probing whether it can do a bulk pre-zero pass even though it
will be rewriting part of that image with data later SHOULD NOT attempt
to flush the disk until all other interesting write requests are also
ready to queue.  In the 'qemu-img convert' case which spawned this
discussion, that's certainly the case (qemu-img does not call flush
after the pre-zeroing, but only after all data is copied - and then it
really DOES want to wait for any remaining backgrounded zeroing to land
on the disk along with any normal writes when it does its final flush).

> 
> Do we want to keep that in consideration?

Ideas on how best to add what I mentioned above into the specification?

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [RFC PATCH 04/17] hw/display: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/display/pl110.c| 2 +-
 hw/display/tc6393xb.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index c2991a28d2..3831505165 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -473,7 +473,7 @@ static void pl110_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl110_ops = {
 .read = pl110_read,
 .write = pl110_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void pl110_mux_ctrl_set(void *opaque, int line, int level)
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 49a676d1b0..6a9477a0c7 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -549,7 +549,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t 
base, qemu_irq irq)
 static const MemoryRegionOps tc6393xb_ops = {
 .read = tc6393xb_readb,
 .write = tc6393xb_writeb,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
-- 
2.23.0




Re: [Qemu-devel] [PATCH 1/1] protocol: Add NBD_CMD_FLAG_FAST_ZERO

2019-08-23 Thread Wouter Verhelst
On Fri, Aug 23, 2019 at 09:34:26AM -0500, Eric Blake wrote:
> +- bit 4, `NBD_CMD_FLAG_FAST_ZERO`; valid during
> +  `NBD_CMD_WRITE_ZEROES`. If set, but the server cannot perform the
> +  write zeroes any faster than it would for an equivalent
> +  `NBD_CMD_WRITE`,

One way of fulfilling the letter of this requirement but not its spirit
could be to have background writes; that is, the server makes a note
that the zeroed region should contain zeroes, makes an error-free reply
to the client, and then starts updating things in the background (with
proper layering so that an NBD_CMD_READ would see zeroes).

This could negatively impact performance after that command to the
effect that syncing the device would be slower rather than faster, if
not done right.

Do we want to keep that in consideration?

-- 
 Home is where you have to wash the dishes.
  -- #debian-devel, Freenode, 2004-09-22



[Qemu-devel] [RFC PATCH 03/17] hw/char: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/char/cadence_uart.c   | 2 +-
 hw/char/escc.c   | 2 +-
 hw/char/etraxfs_ser.c| 2 +-
 hw/char/grlib_apbuart.c  | 2 +-
 hw/char/imx_serial.c | 2 +-
 hw/char/lm32_uart.c  | 2 +-
 hw/char/milkymist-uart.c | 2 +-
 hw/char/pl011.c  | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 0e315b2376..5a128aa5b3 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -459,7 +459,7 @@ static uint64_t uart_read(void *opaque, hwaddr offset,
 static const MemoryRegionOps uart_ops = {
 .read = uart_read,
 .write = uart_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void cadence_uart_reset(DeviceState *dev)
diff --git a/hw/char/escc.c b/hw/char/escc.c
index e185522e27..e2130e04e5 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -576,7 +576,7 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps escc_mem_ops = {
 .read = escc_mem_read,
 .write = escc_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 1,
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index 15ac12ef22..6096158188 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -157,7 +157,7 @@ ser_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps ser_ops = {
 .read = ser_read,
 .write = ser_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index fe3cbf41a3..880878ab4d 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -239,7 +239,7 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps grlib_apbuart_ops = {
 .write  = grlib_apbuart_write,
 .read   = grlib_apbuart_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index fddde9b43d..8a2f10d7bd 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -334,7 +334,7 @@ static void imx_event(void *opaque, int event)
 static const struct MemoryRegionOps imx_serial_ops = {
 .read = imx_serial_read,
 .write = imx_serial_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void imx_serial_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index 32f29c44cf..372c7d60d8 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -207,7 +207,7 @@ static void uart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps uart_ops = {
 .read = uart_read,
 .write = uart_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index c358ca07f3..ed4f02c500 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -158,7 +158,7 @@ static const MemoryRegionOps uart_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 84ad8ff9fb..0a86f6f340 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -289,7 +289,7 @@ static void pl011_event(void *opaque, int event)
 static const MemoryRegionOps pl011_ops = {
 .read = pl011_read,
 .write = pl011_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_pl011 = {
-- 
2.23.0




Re: [Qemu-devel] [PATCH v5 15/30] riscv: hart: Add a "hartid-base" property to RISC-V hart array

2019-08-23 Thread Alistair Francis
On Thu, Aug 22, 2019 at 10:29 PM Bin Meng  wrote:
>
> At present each hart's hartid in a RISC-V hart array is assigned
> the same value of its index in the hart array. But for a system
> that has multiple hart arrays, this is not the case any more.
>
> Add a new "hartid-base" property so that hartid number can be
> assigned based on the property value.
>
> Signed-off-by: Bin Meng 
>
> ---
>
> Changes in v5: None
> Changes in v4:
> - new patch to add a "hartid-base" property to RISC-V hart array
>
> Changes in v3: None
> Changes in v2: None
>
>  hw/riscv/riscv_hart.c | 8 +---
>  include/hw/riscv/riscv_hart.h | 1 +
>  2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> index 9deef869..52ab86a 100644
> --- a/hw/riscv/riscv_hart.c
> +++ b/hw/riscv/riscv_hart.c
> @@ -27,6 +27,7 @@
>
>  static Property riscv_harts_props[] = {
>  DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
> +DEFINE_PROP_UINT32("hartid-base", RISCVHartArrayState, hartid_base, 0),
>  DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -37,7 +38,7 @@ static void riscv_harts_cpu_reset(void *opaque)
>  cpu_reset(CPU(cpu));
>  }
>
> -static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
> +static void riscv_hart_realize(RISCVHartArrayState *s, int idx, uint32_t 
> hartid,
> char *cpu_type, Error **errp)

Do we need to pass hartid, can't we just get it from s here?

>  {
>  Error *err = NULL;
> @@ -45,7 +46,7 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
> idx,
>  object_initialize_child(OBJECT(s), "harts[*]", >harts[idx],
>  sizeof(RISCVCPU), cpu_type,
>  _abort, NULL);
> -s->harts[idx].env.mhartid = idx;
> +s->harts[idx].env.mhartid = hartid;
>  qemu_register_reset(riscv_harts_cpu_reset, >harts[idx]);
>  object_property_set_bool(OBJECT(>harts[idx]), true,
>   "realized", );
> @@ -58,12 +59,13 @@ static void riscv_hart_realize(RISCVHartArrayState *s, 
> int idx,
>  static void riscv_harts_realize(DeviceState *dev, Error **errp)
>  {
>  RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
> +uint32_t hartid = s->hartid_base;

I think s->hartid_base can just be used directly, instead of a extra variable.

Alistair

>  int n;
>
>  s->harts = g_new0(RISCVCPU, s->num_harts);
>
>  for (n = 0; n < s->num_harts; n++) {
> -riscv_hart_realize(s, n, s->cpu_type, errp);
> +riscv_hart_realize(s, n, hartid + n, s->cpu_type, errp);
>  }
>  }
>
> diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
> index 0671d88..1984e30 100644
> --- a/include/hw/riscv/riscv_hart.h
> +++ b/include/hw/riscv/riscv_hart.h
> @@ -32,6 +32,7 @@ typedef struct RISCVHartArrayState {
>
>  /*< public >*/
>  uint32_t num_harts;
> +uint32_t hartid_base;
>  char *cpu_type;
>  RISCVCPU *harts;
>  } RISCVHartArrayState;
> --
> 2.7.4
>
>



[Qemu-devel] [PATCH 2/2] iotests: Test blockdev-create for vpc

2019-08-23 Thread Max Reitz
Signed-off-by: Max Reitz 
---
 tests/qemu-iotests/266 | 182 +
 tests/qemu-iotests/266.out | 107 ++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 290 insertions(+)
 create mode 100755 tests/qemu-iotests/266
 create mode 100644 tests/qemu-iotests/266.out

diff --git a/tests/qemu-iotests/266 b/tests/qemu-iotests/266
new file mode 100755
index 00..19b7b29535
--- /dev/null
+++ b/tests/qemu-iotests/266
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+#
+# Test VPC and file image creation
+#
+# Copyright (C) 2019 Red Hat, Inc.
+#
+# 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 .
+#
+
+import iotests
+from iotests import imgfmt
+
+iotests.verify_image_format(supported_fmts=['vpc'])
+iotests.verify_protocol(supported=['file'])
+
+def blockdev_create(vm, options):
+result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
+filters=[iotests.filter_qmp_testfiles])
+
+if 'return' in result:
+assert result['return'] == {}
+vm.run_job('job0')
+iotests.log("")
+
+with iotests.FilePath('t.vpc') as disk_path, \
+ iotests.VM() as vm:
+
+#
+# Successful image creation (defaults)
+#
+iotests.log("=== Successful image creation (defaults) ===")
+iotests.log("")
+
+# 8 heads, 964 cyls/head, 17 secs/cyl
+# (Close to 64 MB)
+size = 8 * 964 * 17 * 512
+
+vm.launch()
+blockdev_create(vm, { 'driver': 'file',
+  'filename': disk_path,
+  'size': 0 })
+
+vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+   node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'imgfile',
+  'size': size })
+vm.shutdown()
+
+iotests.img_info_log(disk_path)
+
+#
+# Successful image creation (explicit defaults)
+#
+iotests.log("=== Successful image creation (explicit defaults) ===")
+iotests.log("")
+
+# 16 heads, 964 cyls/head, 17 secs/cyl
+# (Close to 128 MB)
+size = 16 * 964 * 17 * 512
+
+vm.launch()
+blockdev_create(vm, { 'driver': 'file',
+  'filename': disk_path,
+  'size': 0 })
+
+vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+   node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'imgfile',
+  'size': size,
+  'subformat': 'dynamic',
+  'force-size': False })
+vm.shutdown()
+
+iotests.img_info_log(disk_path)
+
+#
+# Successful image creation (non-default options)
+#
+iotests.log("=== Successful image creation (non-default options) ===")
+iotests.log("")
+
+# Not representable in CHS (fine with force-size=True)
+size = 1048576
+
+vm.launch()
+blockdev_create(vm, { 'driver': 'file',
+  'filename': disk_path,
+  'size': 0 })
+
+vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+   node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'imgfile',
+  'size': size,
+  'subformat': 'fixed',
+  'force-size': True })
+vm.shutdown()
+
+iotests.img_info_log(disk_path)
+
+#
+# Size not representable in CHS with force-size=False
+#
+iotests.log("=== Size not representable in CHS ===")
+iotests.log("")
+
+# Not representable in CHS (will not work with force-size=False)
+size = 1048576
+
+vm.launch()
+blockdev_create(vm, { 'driver': 'file',
+  'filename': disk_path,
+  'size': 0 })
+
+vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+   node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
+
+blockdev_create(vm, { 'driver': imgfmt,
+  'file': 'imgfile',
+  'size': size,
+  'force-size': False })
+vm.shutdown()
+
+#
+# Zero size
+#
+

[Qemu-devel] [RFC PATCH 02/17] hw/block: Declare device little or big endian

2019-08-23 Thread Tony Nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/block/onenand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index fcc5a69b90..95fc0443d3 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -771,7 +771,7 @@ static void onenand_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps onenand_ops = {
 .read = onenand_read,
 .write = onenand_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void onenand_realize(DeviceState *dev, Error **errp)
-- 
2.23.0




[Qemu-devel] [PATCH v9 19/20] target/sparc: Add TLB entry with attributes

2019-08-23 Thread Tony Nguyen
Append MemTxAttrs to interfaces so we can pass along up coming Invert
Endian TTE bit on SPARC64.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/sparc/mmu_helper.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index cbd1e91179..826e14b6f0 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -88,7 +88,7 @@ static const int perm_table[2][8] = {
 };
 
 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -219,6 +219,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 target_ulong page_size;
 int error_code = 0, prot, access_index;
+MemTxAttrs attrs = {};
 
 /*
  * TODO: If we ever need tlb_vaddr_to_host for this target,
@@ -229,7 +230,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 assert(!probe);
 
 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 vaddr = address;
@@ -490,8 +491,8 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 return 0;
 }
 
-static int get_physical_address_data(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int rw, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -608,8 +609,8 @@ static int get_physical_address_data(CPUSPARCState *env,
 return 1;
 }
 
-static int get_physical_address_code(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_code(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -686,7 +687,7 @@ static int get_physical_address_code(CPUSPARCState *env,
 }
 
 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -716,11 +717,11 @@ static int get_physical_address(CPUSPARCState *env, 
hwaddr *physical,
 }
 
 if (rw == 2) {
-return get_physical_address_code(env, physical, prot, address,
+return get_physical_address_code(env, physical, prot, attrs, address,
  mmu_idx);
 } else {
-return get_physical_address_data(env, physical, prot, address, rw,
- mmu_idx);
+return get_physical_address_data(env, physical, prot, attrs, address,
+ rw, mmu_idx);
 }
 }
 
@@ -734,10 +735,11 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 hwaddr paddr;
 target_ulong page_size;
+MemTxAttrs attrs = {};
 int error_code = 0, prot, access_index;
 
 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 if (likely(error_code == 0)) {
@@ -747,7 +749,8 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
env->dmmu.mmu_primary_context,
env->dmmu.mmu_secondary_context);
 
-tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
+tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx,
+page_size);
 return true;
 }
 if (probe) {
@@ -849,9 +852,10 @@ static int cpu_sparc_get_phys_page(CPUSPARCState *env, 
hwaddr *phys,
 {
 target_ulong page_size;
 int prot, access_index;
+MemTxAttrs attrs = {};
 
-return get_physical_address(env, phys, , _index, addr, rw,
-mmu_idx, _size);
+return get_physical_address(env, phys, , _index, , addr,
+rw, mmu_idx, _size);
 }
 
 #if defined(TARGET_SPARC64)
-- 

[Qemu-devel] [PATCH v9 20/20] target/sparc: sun4u Invert Endian TTE bit

2019-08-23 Thread Tony Nguyen
This bit configures endianness of PCI MMIO devices. It is used by
Solaris and OpenBSD sunhme drivers.

Tested working on OpenBSD.

Unfortunately Solaris 10 had a unrelated keyboard issue blocking
testing... another inch towards Solaris 10 on SPARC64 =)

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Tested-by: Mark Cave-Ayland 
---
 target/sparc/cpu.h| 2 ++
 target/sparc/mmu_helper.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 694d7139cf..490e14dfcf 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -275,6 +275,7 @@ enum {
 
 #define TTE_VALID_BIT   (1ULL << 63)
 #define TTE_NFO_BIT (1ULL << 60)
+#define TTE_IE_BIT  (1ULL << 59)
 #define TTE_USED_BIT(1ULL << 41)
 #define TTE_LOCKED_BIT  (1ULL <<  6)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
@@ -291,6 +292,7 @@ enum {
 
 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT)
+#define TTE_IS_IE(tte)  ((tte) & TTE_IE_BIT)
 #define TTE_IS_USED(tte)((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index 826e14b6f0..77dc86ac5c 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -537,6 +537,10 @@ static int get_physical_address_data(CPUSPARCState *env, 
hwaddr *physical,
 if (ultrasparc_tag_match(>dtlb[i], address, context, physical)) {
 int do_fault = 0;
 
+if (TTE_IS_IE(env->dtlb[i].tte)) {
+attrs->byte_swap = true;
+}
+
 /* access ok? */
 /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
@@ -792,7 +796,7 @@ void dump_mmu(CPUSPARCState *env)
 }
 if (TTE_IS_VALID(env->dtlb[i].tte)) {
 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
-", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
+", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 i,
 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 TTE_PA(env->dtlb[i].tte),
@@ -801,6 +805,8 @@ void dump_mmu(CPUSPARCState *env)
 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 TTE_IS_LOCKED(env->dtlb[i].tte) ?
 "locked" : "unlocked",
+TTE_IS_IE(env->dtlb[i].tte) ?
+"yes" : "no",
 env->dtlb[i].tag & (uint64_t)0x1fffULL,
 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 "global" : "local");
-- 
2.23.0




[Qemu-devel] [PATCH 0/2] block: Let blockdev-create return 0 on success

2019-08-23 Thread Max Reitz
Jobs are expected to return 0 on success.  .bdrv_co_create() on the
other hand is a block layer function, and as such returns a non-negative
value on success.

blockdev_create_run() should translate between the two (patch 1).

Without patch 1, blockdev-create is likely to fail for VPC images.
Hence patch 2.


Max Reitz (2):
  block: Let blockdev-create return 0 on success
  iotests: Test blockdev-create for vpc

 block/create.c |   3 +-
 tests/qemu-iotests/266 | 182 +
 tests/qemu-iotests/266.out | 107 ++
 tests/qemu-iotests/group   |   1 +
 4 files changed, 292 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/266
 create mode 100644 tests/qemu-iotests/266.out

-- 
2.21.0




[Qemu-devel] [PATCH v9 18/20] cputlb: Byte swap memory transaction attribute

2019-08-23 Thread Tony Nguyen
Notice new attribute, byte swap, and force the transaction through the
memory slow path.

Required by architectures that can invert endianness of memory
transaction, e.g. SPARC64 has the Invert Endian TTE bit.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/memattrs.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 3c9e634d99..f4573e2c7a 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -738,6 +738,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  */
 address |= TLB_RECHECK;
 }
+if (attrs.byte_swap) {
+address |= TLB_FORCE_SLOW;
+}
 if (!memory_region_is_ram(section->mr) &&
 !memory_region_is_romd(section->mr)) {
 /* IO memory case */
@@ -891,6 +894,10 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;
 
+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -933,6 +940,10 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;
 
+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index d4a3477d71..95f2d20d55 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
 unsigned int user:1;
 /* Requester ID (for MSI for example) */
 unsigned int requester_id:16;
+/* Invert endianness for this page */
+unsigned int byte_swap:1;
 /*
  * The following are target-specific page-table bits.  These are not
  * related to actual memory transactions at all.  However, this structure
-- 
2.23.0




Re: [Qemu-devel] [PATCH v5 17/30] riscv: sifive_u: Set the minimum number of cpus to 2

2019-08-23 Thread Alistair Francis
On Thu, Aug 22, 2019 at 10:16 PM Bin Meng  wrote:
>
> It is not useful if we only have one management CPU.
>
> Signed-off-by: Bin Meng 
> Reviewed-by: Alistair Francis 

Ah, I jumped the gun with patch 16. This should be before patch 16,
otherwise patch 16 is fine.

Alistair

>
> ---
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3:
> - use management cpu count + 1 for the min_cpus
>
> Changes in v2:
> - update the file header to indicate at least 2 harts are created
>
>  hw/riscv/sifive_u.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 0e5bbe7..a36cd77 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -10,8 +10,8 @@
>   * 1) CLINT (Core Level Interruptor)
>   * 2) PLIC (Platform Level Interrupt Controller)
>   *
> - * This board currently generates devicetree dynamically that indicates at 
> most
> - * five harts.
> + * This board currently generates devicetree dynamically that indicates at 
> least
> + * two harts and up to five harts.
>   *
>   * This program is free software; you can redistribute it and/or modify it
>   * under the terms and conditions of the GNU General Public License,
> @@ -485,6 +485,7 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
>  mc->desc = "RISC-V Board compatible with SiFive U SDK";
>  mc->init = riscv_sifive_u_init;
>  mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 
> SIFIVE_U_COMPUTE_CPU_COUNT;
> +mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
>  }
>
>  DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
> --
> 2.7.4
>
>



[Qemu-devel] [PATCH v9 17/20] cpu: TLB_FLAGS_MASK bit to force memory slow path

2019-08-23 Thread Tony Nguyen
The fast path is taken when TLB_FLAGS_MASK is all zero.

TLB_FORCE_SLOW is simply a TLB_FLAGS_MASK bit to force the slow path,
there are no other side effects.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/cpu-all.h | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58f81..e496f9900f 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -331,12 +331,18 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS - 3))
 /* Set if TLB entry must have MMU lookup repeated for every access */
 #define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
+/* Set if TLB entry must take the slow path.  */
+#define TLB_FORCE_SLOW  (1 << (TARGET_PAGE_BITS - 5))
 
 /* Use this mask to check interception with an alignment mask
  * in a TCG backend.
  */
-#define TLB_FLAGS_MASK  (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
- | TLB_RECHECK)
+#define TLB_FLAGS_MASK \
+(TLB_INVALID_MASK  \
+ | TLB_NOTDIRTY\
+ | TLB_MMIO\
+ | TLB_RECHECK \
+ | TLB_FORCE_SLOW)
 
 /**
  * tlb_hit_page: return true if page aligned @addr is a hit against the
-- 
2.23.0




  1   2   3   4   >