Re: [Qemu-devel] [PATCH v3 07/42] sdhci: refactor common sysbus/pci unrealize() into sdhci_unrealizefn()

2018-01-02 Thread Fam Zheng
On Fri, 12/29 14:48, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/sd/sdhci.c | 19 ---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index ad5853d527..06a1ec6f91 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -31,6 +31,7 @@
>  #include "qemu/bitops.h"
>  #include "hw/sd/sdhci.h"
>  #include "sdhci-internal.h"
> +#include "qapi/error.h"
>  #include "qemu/log.h"
>  
>  /* host controller debug messages */
> @@ -1203,15 +1204,17 @@ static void sdhci_realizefn(SDHCIState *s, Error 
> **errp)
>SDHC_REGISTERS_MAP_SIZE);
>  }
>  
> +static void sdhci_unrealizefn(SDHCIState *s, Error **errp)
> +{
> +g_free(s->fifo_buffer);

Set s->fifo_buffer to NULL to avoid double-free and/or use-after-free?
Especially since you call this from both the ->exit and the ->unrealize
callbacks.

> +}
> +
>  static void sdhci_uninitfn(SDHCIState *s)
>  {
>  timer_del(s->insert_timer);
>  timer_free(s->insert_timer);
>  timer_del(s->transfer_timer);
>  timer_free(s->transfer_timer);
> -
> -g_free(s->fifo_buffer);
> -s->fifo_buffer = NULL;
>  }
>  
>  static bool sdhci_pending_insert_vmstate_needed(void *opaque)
> @@ -1312,6 +1315,8 @@ static void sdhci_pci_realize(PCIDevice *dev, Error 
> **errp)
>  static void sdhci_pci_exit(PCIDevice *dev)
>  {
>  SDHCIState *s = PCI_SDHCI(dev);
> +
> +sdhci_unrealizefn(s, _abort);
>  sdhci_uninitfn(s);
>  }
>  
> @@ -1365,11 +1370,19 @@ static void sdhci_sysbus_realize(DeviceState *dev, 
> Error ** errp)
>  sysbus_init_mmio(sbd, >iomem);
>  }
>  
> +static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
> +{
> +SDHCIState *s = SYSBUS_SDHCI(dev);
> +
> +sdhci_unrealizefn(s, errp);
> +}
> +
>  static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
>  dc->realize = sdhci_sysbus_realize;
> +dc->unrealize = sdhci_sysbus_unrealize;
>  
>  sdhci_class_init(klass, data);
>  }
> -- 
> 2.15.1
> 
> 

Fam



Re: [Qemu-devel] [PATCH v3 06/42] sdhci: refactor common sysbus/pci realize() into sdhci_realizefn()

2018-01-02 Thread Fam Zheng
On Fri, 12/29 14:48, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Alistair Francis 
> ---
>  hw/sd/sdhci.c | 22 ++
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index 38d82b4c61..ad5853d527 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -1194,6 +1194,15 @@ static void sdhci_initfn(SDHCIState *s)
>  s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
> sdhci_data_transfer, s);
>  }
>  
> +static void sdhci_realizefn(SDHCIState *s, Error **errp)

errp is not used here. It doesn't hurt to have it but if the contract is "the
function MAY return error", the callers should check and handle it correctly
(like return early instead of continuing).

Fam

> +{
> +s->buf_maxsz = sdhci_get_fifolen(s);
> +s->fifo_buffer = g_malloc0(s->buf_maxsz);
> +
> +memory_region_init_io(>iomem, OBJECT(s), _mmio_ops, s, "sdhci",
> +  SDHC_REGISTERS_MAP_SIZE);
> +}
> +
>  static void sdhci_uninitfn(SDHCIState *s)
>  {
>  timer_del(s->insert_timer);
> @@ -1292,12 +1301,11 @@ static void sdhci_pci_realize(PCIDevice *dev, Error 
> **errp)
>  SDHCIState *s = PCI_SDHCI(dev);
>  dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
>  dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
> +
>  sdhci_initfn(s);
> -s->buf_maxsz = sdhci_get_fifolen(s);
> -s->fifo_buffer = g_malloc0(s->buf_maxsz);
> +sdhci_realizefn(s, errp);
> +
>  s->irq = pci_allocate_irq(dev);
> -memory_region_init_io(>iomem, OBJECT(s), _mmio_ops, s, "sdhci",
> -SDHC_REGISTERS_MAP_SIZE);
>  pci_register_bar(dev, 0, 0, >iomem);
>  }
>  
> @@ -1351,11 +1359,9 @@ static void sdhci_sysbus_realize(DeviceState *dev, 
> Error ** errp)
>  SDHCIState *s = SYSBUS_SDHCI(dev);
>  SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>  
> -s->buf_maxsz = sdhci_get_fifolen(s);
> -s->fifo_buffer = g_malloc0(s->buf_maxsz);
> +sdhci_realizefn(s, errp);
> +
>  sysbus_init_irq(sbd, >irq);
> -memory_region_init_io(>iomem, OBJECT(s), _mmio_ops, s, "sdhci",
> -SDHC_REGISTERS_MAP_SIZE);
>  sysbus_init_mmio(sbd, >iomem);
>  }
>  
> -- 
> 2.15.1
> 
> 



Re: [Qemu-devel] [PATCH v3 05/42] sdhci: refactor common sysbus/pci class_init() into sdhci_class_init()

2018-01-02 Thread Fam Zheng
On Fri, 12/29 14:48, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/sd/sdhci.c | 22 ++
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index a11469fbca..38d82b4c61 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -1275,6 +1275,16 @@ static Property sdhci_properties[] = {
>  DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static void sdhci_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +dc->vmsd = _vmstate;
> +dc->props = sdhci_properties;
> +dc->reset = sdhci_poweron_reset;
> +}
> +
>  /* --- qdev PCI --- */
>  
>  static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
> @@ -1299,7 +1309,6 @@ static void sdhci_pci_exit(PCIDevice *dev)
>  
>  static void sdhci_pci_class_init(ObjectClass *klass, void *data)
>  {
> -DeviceClass *dc = DEVICE_CLASS(klass);
>  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>  
>  k->realize = sdhci_pci_realize;
> @@ -1307,10 +1316,8 @@ static void sdhci_pci_class_init(ObjectClass *klass, 
> void *data)
>  k->vendor_id = PCI_VENDOR_ID_REDHAT;
>  k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
>  k->class_id = PCI_CLASS_SYSTEM_SDHCI;
> -set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> -dc->vmsd = _vmstate;
> -dc->props = sdhci_properties;
> -dc->reset = sdhci_poweron_reset;
> +
> +sdhci_class_init(klass, data);
>  }
>  
>  static const TypeInfo sdhci_pci_info = {
> @@ -1356,10 +1363,9 @@ static void sdhci_sysbus_class_init(ObjectClass 
> *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
> -dc->vmsd = _vmstate;
> -dc->props = sdhci_properties;
>  dc->realize = sdhci_sysbus_realize;
> -dc->reset = sdhci_poweron_reset;
> +
> +sdhci_class_init(klass, data);

Previously we don't do

set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

in this function. Again if this is intended it should be mentioned in the commit
message?

Fam

>  }
>  
>  static const TypeInfo sdhci_sysbus_info = {
> -- 
> 2.15.1
> 
> 



Re: [Qemu-devel] [PATCH v3 04/42] sdhci: refactor same sysbus/pci properties into a common one

2018-01-02 Thread Fam Zheng
On Fri, 12/29 14:48, Philippe Mathieu-Daudé wrote:
> add sysbus/pci/sdbus separator comments to keep it clearer
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/sd/sdhci.c | 21 ++---
>  1 file changed, 10 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index 365bc80009..a11469fbca 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -1266,13 +1266,17 @@ const VMStateDescription sdhci_vmstate = {
>  
>  /* Capabilities registers provide information on supported features of this
>   * specific host controller implementation */
> -static Property sdhci_pci_properties[] = {
> +static Property sdhci_properties[] = {
>  DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
>  SDHC_CAPAB_REG_DEFAULT),
>  DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
> +DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, 
> pending_insert_quirk,
> + false),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +/* --- qdev PCI --- */
> +
>  static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
>  {
>  SDHCIState *s = PCI_SDHCI(dev);
> @@ -1305,7 +1309,7 @@ static void sdhci_pci_class_init(ObjectClass *klass, 
> void *data)
>  k->class_id = PCI_CLASS_SYSTEM_SDHCI;
>  set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>  dc->vmsd = _vmstate;
> -dc->props = sdhci_pci_properties;
> +dc->props = sdhci_properties;
>  dc->reset = sdhci_poweron_reset;
>  }

This is effectively adding "pending-insert-quirk" property to the class. If it
is intended, should this be explained in the commit message?

>  
> @@ -1320,14 +1324,7 @@ static const TypeInfo sdhci_pci_info = {
>  },
>  };
>  
> -static Property sdhci_sysbus_properties[] = {
> -DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
> -SDHC_CAPAB_REG_DEFAULT),
> -DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
> -DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, 
> pending_insert_quirk,
> - false),
> -DEFINE_PROP_END_OF_LIST(),
> -};
> +/* --- qdev SysBus --- */
>  
>  static void sdhci_sysbus_init(Object *obj)
>  {
> @@ -1360,7 +1357,7 @@ static void sdhci_sysbus_class_init(ObjectClass *klass, 
> void *data)
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
>  dc->vmsd = _vmstate;
> -dc->props = sdhci_sysbus_properties;
> +dc->props = sdhci_properties;
>  dc->realize = sdhci_sysbus_realize;
>  dc->reset = sdhci_poweron_reset;
>  }
> @@ -1374,6 +1371,8 @@ static const TypeInfo sdhci_sysbus_info = {
>  .class_init = sdhci_sysbus_class_init,
>  };
>  
> +/* --- qdev bus master --- */
> +
>  static void sdhci_bus_class_init(ObjectClass *klass, void *data)
>  {
>  SDBusClass *sbc = SD_BUS_CLASS(klass);
> -- 
> 2.15.1
> 

Fam



Re: [Qemu-devel] [PATCH v1 05/21] RISC-V CPU Helpers

2018-01-02 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> +target_ulong mode = env->priv;
> +if (access_type != MMU_INST_FETCH) {
> +if (get_field(env->mstatus, MSTATUS_MPRV)) {
> +mode = get_field(env->mstatus, MSTATUS_MPP);
> +}
> +}
> +if (env->priv_ver >= PRIV_VERSION_1_10_0) {
> +if (get_field(env->satp, SATP_MODE) == VM_1_09_MBARE) {
> +mode = PRV_M;
> +}
> +} else {
> +if (get_field(env->mstatus, MSTATUS_VM) == VM_1_10_MBARE) {
> +mode = PRV_M;
> +}
> +}

This is replicating cpu_mmu_index.
Therefore you should be relying on mmu_idx.

> +/* check to make sure that mmu_idx and mode that we get matches */
> +if (unlikely(mode != mmu_idx)) {
> +fprintf(stderr, "MODE: mmu_idx mismatch\n");
> +exit(1);
> +}

As in the opposite of this.

> +
> +if (mode == PRV_M) {
> +target_ulong msb_mask = /*0x7FFF; */
> +(((target_ulong)2) << (TARGET_LONG_BITS - 1)) - 1;
> +*physical = address & msb_mask;

Or perhaps extract64(address, 0, TARGET_LONG_BITS - 1)?

> +if (env->priv_ver >= PRIV_VERSION_1_10_0) {
> +base = get_field(env->satp, SATP_PPN) << PGSHIFT;
> +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;
> +case VM_1_10_SV39:
> +  levels = 3; ptidxbits = 9; ptesize = 8; break;
> +case VM_1_10_SV48:
> +  levels = 4; ptidxbits = 9; ptesize = 8; break;
> +case VM_1_10_SV57:
> +  levels = 5; ptidxbits = 9; ptesize = 8; break;
> +default:
> +  printf("unsupported SATP_MODE value\n");
> +  exit(1);

Just qemu_log_mask with LOG_UNIMP or LOG_GUEST_ERROR, and then return
TRANSLATE_FAIL.  Printing to stdout and exiting isn't kosher.  Lots more
occurrences within this file.


> +static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
> +MMUAccessType access_type)
> +{
> +CPUState *cs = CPU(riscv_env_get_cpu(env));
> +int page_fault_exceptions =
> +(env->priv_ver >= PRIV_VERSION_1_10_0) &&
> +get_field(env->satp, SATP_MODE) != VM_1_10_MBARE;
> +int exception = 0;
> +if (access_type == MMU_INST_FETCH) { /* inst access */
> +exception = page_fault_exceptions ?
> +RISCV_EXCP_INST_PAGE_FAULT : RISCV_EXCP_INST_ACCESS_FAULT;
> +env->badaddr = address;
> +} else if (access_type == MMU_DATA_STORE) { /* store access */
> +exception = page_fault_exceptions ?
> +RISCV_EXCP_STORE_PAGE_FAULT : RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
> +env->badaddr = address;
> +} else if (access_type == MMU_DATA_LOAD) { /* load access */
> +exception = page_fault_exceptions ?
> +RISCV_EXCP_LOAD_PAGE_FAULT : RISCV_EXCP_LOAD_ACCESS_FAULT;
> +env->badaddr = address;
> +} else {
> +fprintf(stderr, "FAIL: invalid access_type\n");
> +exit(1);

Switch with a default: g_assert_not_reached(), since access_type is not
controlled by the guest.

> +void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
> +   MMUAccessType access_type, int mmu_idx,
> +   uintptr_t retaddr)
> +{
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +CPURISCVState *env = >env;
> +if (access_type == MMU_INST_FETCH) {
> +fprintf(stderr, "unaligned inst fetch not handled here. should not "
> +"trigger\n");
> +exit(1);

No exit.  Do something logical.

> +} else if (access_type == MMU_DATA_STORE) {
> +cs->exception_index = RISCV_EXCP_STORE_AMO_ADDR_MIS;
> +env->badaddr = addr;

Why does STORE imply AMO?  Why can't a normal store trigger an unaligned trap?

> +fprintf(stderr, "Invalid MMUAccessType\n");
> +exit(1);

I'll stop pointing these out, but there need to be zero instances of exit
within the backend.

> +void riscv_cpu_do_interrupt(CPUState *cs)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +CPURISCVState *env = >env;
> +
> +#ifdef RISCV_DEBUG_INTERRUPT
> +if (cs->exception_index & 0x7000) {
> +fprintf(stderr, "core   0: exception trap_%s, epc 0x" TARGET_FMT_lx 
> "\n"
> +, riscv_interrupt_names[cs->exception_index & 0x0fff],
> +env->pc);
> +} else {
> +fprintf(stderr, "core   0: exception trap_%s, epc 0x" TARGET_FMT_lx 
> "\n"
> +, riscv_excp_names[cs->exception_index], env->pc);
> +}
> +#endif
> +
> +if (cs->exception_index == RISCV_EXCP_BREAKPOINT) {
> +fprintf(stderr, "debug mode not implemented\n");
> +}
> +
> +/* skip dcsr cause check */
> +
> +target_ulong fixed_cause = 0;
> +if 

Re: [Qemu-devel] [RFC v2 0/4] enable numa configuration before machine is running from HMP/QMP

2018-01-02 Thread David Gibson
On Thu, Dec 28, 2017 at 06:22:55PM +0100, Igor Mammedov wrote:
> 
> As were suggested at (1) and at bof session where we discussed subj,
> I'm posting variant with late numa 'configuration' i.e. when QEMU is
> started with '-S' option in paused state and numa is configured via
> monitor/QMP before machine cpus are allowed to run.
> 
> Suggested idea was to try 'late' numa configuration as it might result in
> shortcut approach allowing us reuse current pause point (-S) versus adding
> another preconfig option with earlier pause point.
> So this series tries to show how feasible this approach.
> 
> Currently numa options mainly affect only firmware blobs (ACPI/FDT tables),
> it should have been possible to regenerate those blobs right before we start
> CPUs, which would allow us setup numa configuration at first pause point and
> get firmware blobs with updated numa information.
> 
> Series implements idea for x86 ans spapr machines and uses machine reset,
> to reconfigure firmware and other machine structures after each numa
> configuration command (HMP or QMP).
> 
> It was relatively not hard to implement for above machines as they already
> rebuild firmware blobs at reset time. But it still was a pain as QEMU isn't
> written with dynamic reconfiguration in mind and one need to update device
> state with new data (I think I've got it right but not 100% sure)
> 
> However when it comes to the last target supporting NUMA, ARM
> all simplification versus v1 goes down the drain, since FDT blob is build
> incrementally during machine_init(), -device, machine_done() time, and
> it turns out into huge refactoring to isolate scattered FDT pieces into
> single FDT build function (like we do for ACPI). It's job that we would need
> to do anyways for hotplug to work properly on ARM,

Kind of irrelevant to this series, but I agree.  pseries started out
with the FDT being almost static created at init time, with a few tiny
adjustments later on.  But as the platform developed we needed to move
more and more of the FDT generation to later on (reset time, roughly).
For a long time we had an ugly split between the "skeleton" built at
init time and the stuff built at reset time, until I eventually moved
it all to reset time.

I'm pretty sure ARM will want the same thing, for hotplug as you
mention, but also for other things.  I also think it'll save effort
over all to do it sooner rather than later.

I had stuff in the works for ages to make DT building easier,
including a full "live" DT model for qemu (fdt is a good format for
passing the DT from one unit to another, but it gets clunky to do lots
of manipulation with it).  Unfortunately I've been sufficiently busy
with other things that I haven't really gotten anywhere with that for
the last year or more.

> but I don't think it
> should get in the way of numa refactoring.
> So that was the point where I gave up and decided to post only x86/spapr
> pieces for demo purposes.

Fair enough.

> 
> I'm inclined towards avoiding 'v2 shortcut' and going in direction of v1,
> as I didn't see v2 as the right way in general, since one would have to:
>   - build machine / connect / initalize / devices one way and then find out
> devices / connections that need to be fixed/updated with new 
> configuration,
> it's very fragile and easy break.
> 
> If I remember correctly the bof session, consensus was that we would like to 
> have
> early configuration interface (like v1) in the end, so I'd rather send time
> on addressing v1 drawbacks instead of hacking machine init order to make numa 
> work
> in backwards way.
> 
> CC: ebl...@redhat.com
> CC: arm...@redhat.com
> CC: ehabk...@redhat.com
> CC: pkre...@redhat.com
> CC: da...@gibson.dropbear.id.au
> CC: peter.mayd...@linaro.org
> CC: pbonz...@redhat.com
> 
> [1]
> v1 for reference:
> [Qemu-devel] [RFC 0/6] enable numa configuration before machine_init() from 
> HMP/QMP
> https://lists.nongnu.org/archive/html/qemu-devel/2017-10/msg03583.html
> 
> PS:
> exercise wasn't waste as it resulted in cleanups that were already merged.
> 
> 
> Igor Mammedov (4):
>   numa: split out NumaOptions parsing into parse_NumaOptions()
>   HMP: add set-numa-node command
>   QMP: add set-numa-node command
>   numa: pc: reset machine if numa config has changed in prelaunch time
> 
>  hmp.h |  1 +
>  include/hw/boards.h   |  1 +
>  include/sysemu/numa.h |  1 +
>  hmp-commands.hx   | 13 +++
>  hmp.c | 23 +++
>  hw/core/machine.c |  3 ++-
>  hw/i386/pc.c  |  1 +
>  numa.c| 63 
> +++
>  qapi-schema.json  | 13 +++
>  vl.c  |  4 
>  10 files changed, 102 insertions(+), 21 deletions(-)
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ 

[Qemu-devel] [PATCH 10/11] migration: major cleanup for migrate iterations

2018-01-02 Thread Peter Xu
The major work for migration iterations are to move RAM/block/... data
via qemu_savevm_state_iterate().  Generalize those part into a single
function.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 90 +++
 1 file changed, 55 insertions(+), 35 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 2629f907e9..c6c39738d2 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2056,11 +2056,11 @@ static int migration_maybe_pause(MigrationState *s,
  *   The caller 'breaks' the loop when this returns.
  *
  * @s: Current migration state
- * @current_active_state: The migration state we expect to be in
  */
-static void migration_completion(MigrationState *s, int current_active_state)
+static void migration_completion(MigrationState *s)
 {
 int ret;
+int current_active_state = s->state;
 
 if (s->state == MIGRATION_STATUS_ACTIVE) {
 qemu_mutex_lock_iothread();
@@ -2199,6 +2199,51 @@ static void migration_update_statistics(MigrationState 
*s,
   bandwidth, threshold_size);
 }
 
+/* Migration thread iteration status */
+typedef enum {
+MIG_ITERATE_RESUME, /* Resume current iteration */
+MIG_ITERATE_SKIP,   /* Skip current iteration */
+MIG_ITERATE_BREAK,  /* Break the loop */
+} MigIterateState;
+
+/*
+ * Return true if continue to the next iteration directly, false
+ * otherwise.
+ */
+static MigIterateState migration_iteration_run(MigrationState *s)
+{
+uint64_t pending_size, pend_post, pend_nonpost;
+bool in_postcopy = s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE;
+
+qemu_savevm_state_pending(s->to_dst_file, s->threshold_size,
+  _nonpost, _post);
+pending_size = pend_nonpost + pend_post;
+
+trace_migrate_pending(pending_size, s->threshold_size,
+  pend_post, pend_nonpost);
+
+if (pending_size && pending_size >= s->threshold_size) {
+/* Still a significant amount to transfer */
+if (migrate_postcopy() && !in_postcopy &&
+pend_nonpost <= s->threshold_size &&
+atomic_read(>start_postcopy)) {
+if (postcopy_start(s)) {
+error_report("%s: postcopy failed to start", __func__);
+}
+return MIG_ITERATE_SKIP;
+}
+/* Just another iteration step */
+qemu_savevm_state_iterate(s->to_dst_file,
+s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
+} else {
+trace_migration_thread_low_pending(pending_size);
+migration_completion(s);
+return MIG_ITERATE_BREAK;
+}
+
+return MIG_ITERATE_RESUME;
+}
+
 /*
  * Master migration thread on the source VM.
  * It drives the migration and pumps the data down the outgoing channel.
@@ -2207,9 +2252,6 @@ static void *migration_thread(void *opaque)
 {
 MigrationState *s = opaque;
 int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
-bool entered_postcopy = false;
-/* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
-enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
 
 rcu_register_thread();
 
@@ -2249,43 +2291,21 @@ static void *migration_thread(void *opaque)
 while (s->state == MIGRATION_STATUS_ACTIVE ||
s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
 int64_t current_time;
-uint64_t pending_size;
 
 if (!qemu_file_rate_limit(s->to_dst_file)) {
-uint64_t pend_post, pend_nonpost;
-
-qemu_savevm_state_pending(s->to_dst_file, s->threshold_size,
-  _nonpost, _post);
-pending_size = pend_nonpost + pend_post;
-trace_migrate_pending(pending_size, s->threshold_size,
-  pend_post, pend_nonpost);
-if (pending_size && pending_size >= s->threshold_size) {
-/* Still a significant amount to transfer */
-
-if (migrate_postcopy() &&
-s->state != MIGRATION_STATUS_POSTCOPY_ACTIVE &&
-pend_nonpost <= s->threshold_size &&
-atomic_read(>start_postcopy)) {
-
-if (!postcopy_start(s)) {
-current_active_state = 
MIGRATION_STATUS_POSTCOPY_ACTIVE;
-entered_postcopy = true;
-}
-
-continue;
-}
-/* Just another iteration step */
-qemu_savevm_state_iterate(s->to_dst_file, entered_postcopy);
-} else {
-trace_migration_thread_low_pending(pending_size);
-migration_completion(s, current_active_state);
+MigIterateState iter_state = migration_iteration_run(s);
+if (iter_state == MIG_ITERATE_SKIP) {
+continue;
+} else if (iter_state == 

[Qemu-devel] [PATCH 11/11] migration: put the finish part into a new function

2018-01-02 Thread Peter Xu
This patch only moved the last part of migration_thread() into a new
function migration_iteration_finish() to make it much shorter.  With
previous works to remove some local variables, now it's fairly easy to
do that.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 80 +++
 1 file changed, 42 insertions(+), 38 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index c6c39738d2..51379bba2c 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2244,6 +2244,47 @@ static MigIterateState 
migration_iteration_run(MigrationState *s)
 return MIG_ITERATE_RESUME;
 }
 
+static void migration_iteration_finish(MigrationState *s)
+{
+/* If we enabled cpu throttling for auto-converge, turn it off. */
+cpu_throttle_stop();
+
+qemu_mutex_lock_iothread();
+switch (s->state) {
+case MIGRATION_STATUS_COMPLETED:
+migration_calculate_complete(s);
+runstate_set(RUN_STATE_POSTMIGRATE);
+break;
+
+case MIGRATION_STATUS_ACTIVE:
+assert(migrate_colo_enabled());
+migrate_start_colo_process(s);
+/*
+ * Fixme: we will run VM in COLO no matter its old running state.
+ * After exited COLO, we will keep running.
+ */
+s->old_vm_running = true;
+/* Fallthrough */
+case MIGRATION_STATUS_FAILED:
+case MIGRATION_STATUS_CANCELLED:
+if (s->old_vm_running) {
+vm_start();
+} else {
+if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
+runstate_set(RUN_STATE_POSTMIGRATE);
+}
+}
+break;
+
+default:
+/* Should not reach here, but if so, forgive the VM. */
+error_report("%s: Unknown ending state %d", __func__, s->state);
+break;
+}
+qemu_bh_schedule(s->cleanup_bh);
+qemu_mutex_unlock_iothread();
+}
+
 /*
  * Master migration thread on the source VM.
  * It drives the migration and pumps the data down the outgoing channel.
@@ -2322,44 +2363,7 @@ static void *migration_thread(void *opaque)
 }
 
 trace_migration_thread_after_loop();
-/* If we enabled cpu throttling for auto-converge, turn it off. */
-cpu_throttle_stop();
-
-qemu_mutex_lock_iothread();
-switch (s->state) {
-case MIGRATION_STATUS_COMPLETED:
-migration_calculate_complete(s);
-runstate_set(RUN_STATE_POSTMIGRATE);
-break;
-
-case MIGRATION_STATUS_ACTIVE:
-assert(migrate_colo_enabled());
-migrate_start_colo_process(s);
-/*
- * Fixme: we will run VM in COLO no matter its old running state.
- * After exited COLO, we will keep running.
- */
-s->old_vm_running = true;
-/* Fallthrough */
-case MIGRATION_STATUS_FAILED:
-case MIGRATION_STATUS_CANCELLED:
-if (s->old_vm_running) {
-vm_start();
-} else {
-if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
-runstate_set(RUN_STATE_POSTMIGRATE);
-}
-}
-break;
-
-default:
-/* Should not reach here, but if so, forgive the VM. */
-error_report("%s: Unknown ending state %d", __func__, s->state);
-break;
-}
-qemu_bh_schedule(s->cleanup_bh);
-qemu_mutex_unlock_iothread();
-
+migration_iteration_finish(s);
 rcu_unregister_thread();
 return NULL;
 }
-- 
2.14.3




[Qemu-devel] [PATCH 07/11] migration: introduce migrate_calculate_complete

2018-01-02 Thread Peter Xu
Generalize the calculation part when migration complete into a
function to simplify migration_thread().

Signed-off-by: Peter Xu 
---
 migration/migration.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 2d8b47197e..acef54748b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2151,6 +2151,19 @@ bool migrate_colo_enabled(void)
 return s->enabled_capabilities[MIGRATION_CAPABILITY_X_COLO];
 }
 
+static void migration_calculate_complete(MigrationState *s)
+{
+uint64_t bytes = qemu_ftell(s->to_dst_file);
+int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+
+s->mig_total_time = end_time - s->mig_start_time;
+s->downtime = end_time - s->vm_down_start_time;
+
+if (s->mig_total_time) {
+s->mbps = ((double) bytes * 8.0) / s->mig_total_time / 1000;
+}
+}
+
 /*
  * Master migration thread on the source VM.
  * It drives the migration and pumps the data down the outgoing channel.
@@ -2168,7 +2181,6 @@ static void *migration_thread(void *opaque)
  * measured bandwidth
  */
 int64_t threshold_size = 0;
-int64_t end_time;
 bool entered_postcopy = false;
 /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
 enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
@@ -2282,19 +2294,10 @@ static void *migration_thread(void *opaque)
 trace_migration_thread_after_loop();
 /* If we enabled cpu throttling for auto-converge, turn it off. */
 cpu_throttle_stop();
-end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 
 qemu_mutex_lock_iothread();
 if (s->state == MIGRATION_STATUS_COMPLETED) {
-uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
-s->mig_total_time = end_time - s->mig_start_time;
-if (!entered_postcopy) {
-s->downtime = end_time - s->vm_down_start_time;
-}
-if (s->mig_total_time) {
-s->mbps = (((double) transferred_bytes * 8.0) /
-   ((double) s->mig_total_time)) / 1000;
-}
+migration_calculate_complete(s);
 runstate_set(RUN_STATE_POSTMIGRATE);
 } else {
 if (s->state == MIGRATION_STATUS_ACTIVE) {
-- 
2.14.3




[Qemu-devel] [PATCH 08/11] migration: use switch at the end of migration

2018-01-02 Thread Peter Xu
It converts the old if clauses into switch, explicitly mentions the
possible migration states.  The old nested "if"s are not clear on what
we do on different states.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 32 +---
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index acef54748b..bfcba24caa 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2296,19 +2296,23 @@ static void *migration_thread(void *opaque)
 cpu_throttle_stop();
 
 qemu_mutex_lock_iothread();
-if (s->state == MIGRATION_STATUS_COMPLETED) {
+switch (s->state) {
+case MIGRATION_STATUS_COMPLETED:
 migration_calculate_complete(s);
 runstate_set(RUN_STATE_POSTMIGRATE);
-} else {
-if (s->state == MIGRATION_STATUS_ACTIVE) {
-assert(migrate_colo_enabled());
-migrate_start_colo_process(s);
-/*
-* Fixme: we will run VM in COLO no matter its old running state.
-* After exited COLO, we will keep running.
-*/
-s->old_vm_running = true;
-}
+break;
+
+case MIGRATION_STATUS_ACTIVE:
+assert(migrate_colo_enabled());
+migrate_start_colo_process(s);
+/*
+ * Fixme: we will run VM in COLO no matter its old running state.
+ * After exited COLO, we will keep running.
+ */
+s->old_vm_running = true;
+/* Fallthrough */
+case MIGRATION_STATUS_FAILED:
+case MIGRATION_STATUS_CANCELLED:
 if (s->old_vm_running) {
 vm_start();
 } else {
@@ -2316,6 +2320,12 @@ static void *migration_thread(void *opaque)
 runstate_set(RUN_STATE_POSTMIGRATE);
 }
 }
+break;
+
+default:
+/* Should not reach here, but if so, forgive the VM. */
+error_report("%s: Unknown ending state %d", __func__, s->state);
+break;
 }
 qemu_bh_schedule(s->cleanup_bh);
 qemu_mutex_unlock_iothread();
-- 
2.14.3




[Qemu-devel] [PATCH 09/11] migration: cleanup stats update into function

2018-01-02 Thread Peter Xu
We have quite a few lines in migration_thread() that calculates some
statistics for the migration interations.  Isolate it into a single
function to improve readability.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 82 +--
 migration/migration.h | 13 
 2 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index bfcba24caa..2629f907e9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1273,6 +1273,8 @@ MigrationState *migrate_init(void)
 s->mig_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 s->mig_total_time = 0;
 s->old_vm_running = false;
+s->initial_bytes = 0;
+s->threshold_size = 0;
 return s;
 }
 
@@ -2164,6 +2166,39 @@ static void migration_calculate_complete(MigrationState 
*s)
 }
 }
 
+static void migration_update_statistics(MigrationState *s,
+int64_t current_time)
+{
+uint64_t transferred = qemu_ftell(s->to_dst_file) - s->initial_bytes;
+uint64_t time_spent = current_time - s->initial_time;
+double bandwidth = (double)transferred / time_spent;
+int64_t threshold_size = bandwidth * s->parameters.downtime_limit;
+
+if (current_time < s->initial_time + BUFFER_DELAY) {
+return;
+}
+
+s->mbps = (((double) transferred * 8.0) /
+   ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
+
+/*
+ * if we haven't sent anything, we don't want to
+ * recalculate. 1 is a small enough number for our purposes
+ */
+if (ram_counters.dirty_pages_rate && transferred > 1) {
+s->expected_downtime = ram_counters.dirty_pages_rate *
+qemu_target_page_size() / bandwidth;
+}
+
+qemu_file_reset_rate_limit(s->to_dst_file);
+
+s->initial_time = current_time;
+s->initial_bytes = qemu_ftell(s->to_dst_file);
+
+trace_migrate_transferred(transferred, time_spent,
+  bandwidth, threshold_size);
+}
+
 /*
  * Master migration thread on the source VM.
  * It drives the migration and pumps the data down the outgoing channel.
@@ -2171,22 +2206,15 @@ static void migration_calculate_complete(MigrationState 
*s)
 static void *migration_thread(void *opaque)
 {
 MigrationState *s = opaque;
-/* Used by the bandwidth calcs, updated later */
-int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
-int64_t initial_bytes = 0;
-/*
- * The final stage happens when the remaining data is smaller than
- * this threshold; it's calculated from the requested downtime and
- * measured bandwidth
- */
-int64_t threshold_size = 0;
 bool entered_postcopy = false;
 /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
 enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
 
 rcu_register_thread();
 
+s->initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+
 qemu_savevm_state_header(s->to_dst_file);
 
 /*
@@ -2226,17 +2254,17 @@ static void *migration_thread(void *opaque)
 if (!qemu_file_rate_limit(s->to_dst_file)) {
 uint64_t pend_post, pend_nonpost;
 
-qemu_savevm_state_pending(s->to_dst_file, threshold_size,
+qemu_savevm_state_pending(s->to_dst_file, s->threshold_size,
   _nonpost, _post);
 pending_size = pend_nonpost + pend_post;
-trace_migrate_pending(pending_size, threshold_size,
+trace_migrate_pending(pending_size, s->threshold_size,
   pend_post, pend_nonpost);
-if (pending_size && pending_size >= threshold_size) {
+if (pending_size && pending_size >= s->threshold_size) {
 /* Still a significant amount to transfer */
 
 if (migrate_postcopy() &&
 s->state != MIGRATION_STATUS_POSTCOPY_ACTIVE &&
-pend_nonpost <= threshold_size &&
+pend_nonpost <= s->threshold_size &&
 atomic_read(>start_postcopy)) {
 
 if (!postcopy_start(s)) {
@@ -2261,33 +2289,15 @@ static void *migration_thread(void *opaque)
 trace_migration_thread_file_err();
 break;
 }
+
 current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
-if (current_time >= initial_time + BUFFER_DELAY) {
-uint64_t transferred_bytes = qemu_ftell(s->to_dst_file) -
- initial_bytes;
-uint64_t time_spent = current_time - initial_time;
-double bandwidth = (double)transferred_bytes / time_spent;
-threshold_size = bandwidth * s->parameters.downtime_limit;
-
-s->mbps = (((double) transferred_bytes * 8.0) /
-((double) 

[Qemu-devel] [PATCH 05/11] migration: move vm_old_running into global state

2018-01-02 Thread Peter Xu
Firstly, it was passed around.  Let's just move it into MigrationState
just like many other variables as state of migration.

One thing to mention is that for postcopy, we actually don't need this
knowledge at all since postcopy can't resume a VM even if it fails (we
can see that from the old code too: when we try to resume we also check
against "entered_postcopy" variable).  So further we do this:

- in postcopy_start(), we don't update vm_old_running since useless
- in migration_thread(), we don't need to check entered_postcopy when
  resume, since it's only used for precopy.

Comment this out too for that variable definition.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 17 +++--
 migration/migration.h |  6 ++
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index b684c2005d..62b3766852 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1272,6 +1272,7 @@ MigrationState *migrate_init(void)
 
 s->mig_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 s->mig_total_time = 0;
+s->old_vm_running = false;
 return s;
 }
 
@@ -1846,7 +1847,7 @@ static int 
await_return_path_close_on_source(MigrationState *ms)
  * Switch from normal iteration to postcopy
  * Returns non-0 on error
  */
-static int postcopy_start(MigrationState *ms, bool *old_vm_running)
+static int postcopy_start(MigrationState *ms)
 {
 int ret;
 QIOChannelBuffer *bioc;
@@ -1864,7 +1865,6 @@ static int postcopy_start(MigrationState *ms, bool 
*old_vm_running)
 trace_postcopy_start_set_run();
 
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
-*old_vm_running = runstate_is_running();
 global_state_store();
 ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 if (ret < 0) {
@@ -2055,11 +2055,9 @@ static int migration_maybe_pause(MigrationState *s,
  *
  * @s: Current migration state
  * @current_active_state: The migration state we expect to be in
- * @*old_vm_running: Pointer to old_vm_running flag
  * @*start_time: Pointer to time to update
  */
 static void migration_completion(MigrationState *s, int current_active_state,
- bool *old_vm_running,
  int64_t *start_time)
 {
 int ret;
@@ -2068,7 +2066,7 @@ static void migration_completion(MigrationState *s, int 
current_active_state,
 qemu_mutex_lock_iothread();
 *start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
-*old_vm_running = runstate_is_running();
+s->old_vm_running = runstate_is_running();
 ret = global_state_store();
 
 if (!ret) {
@@ -2174,7 +2172,6 @@ static void *migration_thread(void *opaque)
 int64_t threshold_size = 0;
 int64_t start_time = initial_time;
 int64_t end_time;
-bool old_vm_running = false;
 bool entered_postcopy = false;
 /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
 enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
@@ -2233,7 +2230,7 @@ static void *migration_thread(void *opaque)
 pend_nonpost <= threshold_size &&
 atomic_read(>start_postcopy)) {
 
-if (!postcopy_start(s, _vm_running)) {
+if (!postcopy_start(s)) {
 current_active_state = 
MIGRATION_STATUS_POSTCOPY_ACTIVE;
 entered_postcopy = true;
 }
@@ -2245,7 +2242,7 @@ static void *migration_thread(void *opaque)
 } else {
 trace_migration_thread_low_pending(pending_size);
 migration_completion(s, current_active_state,
- _vm_running, _time);
+ _time);
 break;
 }
 }
@@ -2311,9 +2308,9 @@ static void *migration_thread(void *opaque)
 * Fixme: we will run VM in COLO no matter its old running state.
 * After exited COLO, we will keep running.
 */
-old_vm_running = true;
+s->old_vm_running = true;
 }
-if (old_vm_running && !entered_postcopy) {
+if (s->old_vm_running) {
 vm_start();
 } else {
 if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
diff --git a/migration/migration.h b/migration/migration.h
index ac74a12713..0f5df2367c 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -111,6 +111,12 @@ struct MigrationState
 int64_t expected_downtime;
 bool enabled_capabilities[MIGRATION_CAPABILITY__MAX];
 int64_t setup_time;
+/*
+ * Whether the old VM is running for the last migration.  This is
+ * used to resume the VM when precopy failed or cancelled somehow.
+ * It's never used for postcopy.
+ */
+bool old_vm_running;
 
 /* Flag set once 

[Qemu-devel] [PATCH 06/11] migration: introduce vm_down_start_time

2018-01-02 Thread Peter Xu
Introduce MigrationState.vm_down_start_time to replace the local
variable "start_time" in migration_thread to avoid passing things around.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 12 
 migration/migration.h |  2 ++
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 62b3766852..2d8b47197e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2055,16 +2055,14 @@ static int migration_maybe_pause(MigrationState *s,
  *
  * @s: Current migration state
  * @current_active_state: The migration state we expect to be in
- * @*start_time: Pointer to time to update
  */
-static void migration_completion(MigrationState *s, int current_active_state,
- int64_t *start_time)
+static void migration_completion(MigrationState *s, int current_active_state)
 {
 int ret;
 
 if (s->state == MIGRATION_STATUS_ACTIVE) {
 qemu_mutex_lock_iothread();
-*start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+s->vm_down_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 s->old_vm_running = runstate_is_running();
 ret = global_state_store();
@@ -2170,7 +2168,6 @@ static void *migration_thread(void *opaque)
  * measured bandwidth
  */
 int64_t threshold_size = 0;
-int64_t start_time = initial_time;
 int64_t end_time;
 bool entered_postcopy = false;
 /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
@@ -2241,8 +2238,7 @@ static void *migration_thread(void *opaque)
 qemu_savevm_state_iterate(s->to_dst_file, entered_postcopy);
 } else {
 trace_migration_thread_low_pending(pending_size);
-migration_completion(s, current_active_state,
- _time);
+migration_completion(s, current_active_state);
 break;
 }
 }
@@ -2293,7 +2289,7 @@ static void *migration_thread(void *opaque)
 uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
 s->mig_total_time = end_time - s->mig_start_time;
 if (!entered_postcopy) {
-s->downtime = end_time - start_time;
+s->downtime = end_time - s->vm_down_start_time;
 }
 if (s->mig_total_time) {
 s->mbps = (((double) transferred_bytes * 8.0) /
diff --git a/migration/migration.h b/migration/migration.h
index 0f5df2367c..3ab5506233 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -107,6 +107,8 @@ struct MigrationState
 int64_t mig_start_time;
 /* Total time used by latest migration (ms) */
 int64_t mig_total_time;
+/* Timestamp when VM is down (ms) to migrate the last stuff */
+int64_t vm_down_start_time;
 int64_t downtime;
 int64_t expected_downtime;
 bool enabled_capabilities[MIGRATION_CAPABILITY__MAX];
-- 
2.14.3




[Qemu-devel] [PATCH 02/11] migration: qemu_savevm_state_cleanup() in cleanup

2018-01-02 Thread Peter Xu
Moving existing callers all into migrate_fd_cleanup().  It simplifies
migration_thread() a bit.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 0ee4b4c27c..edbda43246 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1077,6 +1077,8 @@ static void migrate_fd_cleanup(void *opaque)
 qemu_bh_delete(s->cleanup_bh);
 s->cleanup_bh = NULL;
 
+qemu_savevm_state_cleanup();
+
 if (s->to_dst_file) {
 Error *local_err = NULL;
 
@@ -2290,13 +2292,6 @@ static void *migration_thread(void *opaque)
 end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 
 qemu_mutex_lock_iothread();
-/*
- * The resource has been allocated by migration will be reused in COLO
- * process, so don't release them.
- */
-if (!enable_colo) {
-qemu_savevm_state_cleanup();
-}
 if (s->state == MIGRATION_STATUS_COMPLETED) {
 uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
 s->total_time = end_time - s->total_time;
@@ -2312,7 +2307,6 @@ static void *migration_thread(void *opaque)
 if (s->state == MIGRATION_STATUS_ACTIVE) {
 assert(enable_colo);
 migrate_start_colo_process(s);
-qemu_savevm_state_cleanup();
 /*
 * Fixme: we will run VM in COLO no matter its old running state.
 * After exited COLO, we will keep running.
-- 
2.14.3




[Qemu-devel] [PATCH 03/11] migration: remove "enable_colo" var

2018-01-02 Thread Peter Xu
It's only used once, clean it up a bit.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index edbda43246..20f7565527 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2177,7 +2177,6 @@ static void *migration_thread(void *opaque)
 bool entered_postcopy = false;
 /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
 enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
-bool enable_colo = migrate_colo_enabled();
 
 rcu_register_thread();
 
@@ -2305,7 +2304,7 @@ static void *migration_thread(void *opaque)
 runstate_set(RUN_STATE_POSTMIGRATE);
 } else {
 if (s->state == MIGRATION_STATUS_ACTIVE) {
-assert(enable_colo);
+assert(migrate_colo_enabled());
 migrate_start_colo_process(s);
 /*
 * Fixme: we will run VM in COLO no matter its old running state.
-- 
2.14.3




[Qemu-devel] [PATCH 04/11] migration: split use of MigrationState.total_time

2018-01-02 Thread Peter Xu
It was used either to:

1. store initial timestamp of migration start, and
2. store total time used by last migration

Let's provide two parameters for each of them.  Mix use of the two is
slightly misleading.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 13 +++--
 migration/migration.h |  5 -
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 20f7565527..b684c2005d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -613,7 +613,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 info->has_status = true;
 info->has_total_time = true;
 info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
-- s->total_time;
+- s->mig_start_time;
 info->has_expected_downtime = true;
 info->expected_downtime = s->expected_downtime;
 info->has_setup_time = true;
@@ -629,7 +629,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 case MIGRATION_STATUS_COMPLETED:
 info->has_status = true;
 info->has_total_time = true;
-info->total_time = s->total_time;
+info->total_time = s->mig_total_time;
 info->has_downtime = true;
 info->downtime = s->downtime;
 info->has_setup_time = true;
@@ -1270,7 +1270,8 @@ MigrationState *migrate_init(void)
 
 migrate_set_state(>state, MIGRATION_STATUS_NONE, 
MIGRATION_STATUS_SETUP);
 
-s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+s->mig_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+s->mig_total_time = 0;
 return s;
 }
 
@@ -2293,13 +2294,13 @@ static void *migration_thread(void *opaque)
 qemu_mutex_lock_iothread();
 if (s->state == MIGRATION_STATUS_COMPLETED) {
 uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
-s->total_time = end_time - s->total_time;
+s->mig_total_time = end_time - s->mig_start_time;
 if (!entered_postcopy) {
 s->downtime = end_time - start_time;
 }
-if (s->total_time) {
+if (s->mig_total_time) {
 s->mbps = (((double) transferred_bytes * 8.0) /
-   ((double) s->total_time)) / 1000;
+   ((double) s->mig_total_time)) / 1000;
 }
 runstate_set(RUN_STATE_POSTMIGRATE);
 } else {
diff --git a/migration/migration.h b/migration/migration.h
index 663415fe48..ac74a12713 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -103,7 +103,10 @@ struct MigrationState
 } rp_state;
 
 double mbps;
-int64_t total_time;
+/* Timestamp when recent migration starts (ms) */
+int64_t mig_start_time;
+/* Total time used by latest migration (ms) */
+int64_t mig_total_time;
 int64_t downtime;
 int64_t expected_downtime;
 bool enabled_capabilities[MIGRATION_CAPABILITY__MAX];
-- 
2.14.3




[Qemu-devel] [PATCH 01/11] migration: assert colo instead of check

2018-01-02 Thread Peter Xu
When reaching here if we are still "active" it means we must be in colo
state.  Assert it instead of check it in if condition.

Finally I want to use "switch" here rather than lots of complicated if
clauses.

Signed-off-by: Peter Xu 
---
 migration/migration.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/migration/migration.c b/migration/migration.c
index 4de3b551fe..0ee4b4c27c 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2309,7 +2309,8 @@ static void *migration_thread(void *opaque)
 }
 runstate_set(RUN_STATE_POSTMIGRATE);
 } else {
-if (s->state == MIGRATION_STATUS_ACTIVE && enable_colo) {
+if (s->state == MIGRATION_STATUS_ACTIVE) {
+assert(enable_colo);
 migrate_start_colo_process(s);
 qemu_savevm_state_cleanup();
 /*
-- 
2.14.3




[Qemu-devel] [PATCH 00/11] migration: cleanup migration_thread()

2018-01-02 Thread Peter Xu
Firstly this series is something as a first attempt of me to cleanup
some migration code.  It may not be a good idea, but I still think it
worth a try, so I posted it.  Let me know if any of you don't like it,
so I can stop.  At least after the series the migration_thread()
function can be far shorter and much easier for first-time readers
AFAICT.

For this single function, the most complexity part is quite a lot of
local variables crossly referenced everywhere, and during the cleanup
I do think the COLO part is hacky too.

There can be some functional changes too in the future:

- cancel migration as cleanup of QEMU quit
- add migration locks to protect migration internal states
- ...

But for this single series, there is still no functional change yet.

Please have a look.  Any feedback is welcomed.  Thanks,

Peter Xu (11):
  migration: assert colo instead of check
  migration: qemu_savevm_state_cleanup() in cleanup
  migration: remove "enable_colo" var
  migration: split use of MigrationState.total_time
  migration: move vm_old_running into global state
  migration: introduce vm_down_start_time
  migration: introduce migrate_calculate_complete
  migration: use switch at the end of migration
  migration: cleanup stats update into function
  migration: major cleanup for migrate iterations
  migration: put the finish part into a new function

 migration/migration.c | 289 --
 migration/migration.h |  26 -
 2 files changed, 187 insertions(+), 128 deletions(-)

-- 
2.14.3




Re: [Qemu-devel] [PATCH v1 02/21] RISC-V ELF Machine Definition

2018-01-02 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> Define RISC-V ELF machine EM_RISCV 243
> 
> Signed-off-by: Michael Clark 
> ---
>  include/elf.h | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v1 01/21] RISC-V Maintainers

2018-01-02 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> Add Michael Clark, Sagar Karandikar and Bastian Koppelmann as
> RISC-V Maintainers.
> 
> Signed-off-by: Michael Clark 
> ---
>  MAINTAINERS | 10 ++
>  1 file changed, 10 insertions(+)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v1 04/21] RISC-V Disassembler

2018-01-02 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> +static const char *rv_ireg_name_sym[] = {
> +"zero", "ra",   "sp",   "gp",   "tp",   "t0",   "t1",   "t2",
> +"s0",   "s1",   "a0",   "a1",   "a2",   "a3",   "a4",   "a5",
> +"a6",   "a7",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
> +"s8",   "s9",   "s10",  "s11",  "t3",   "t4",   "t5",   "t6",
> +NULL
> +};

static const char * const

But maybe even better as

static const char rv_ireg_name_sym[32][4]

and without the useless NULL.

Otherwise,

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v1 03/21] RISC-V CPU Core Definition

2018-01-02 Thread Richard Henderson
On 01/02/2018 04:44 PM, Michael Clark wrote:
> +#ifdef CONFIG_USER_ONLY
> +static bool riscv_cpu_has_work(CPUState *cs)
> +{
> +return 0;
> +}
> +#else
> +static bool riscv_cpu_has_work(CPUState *cs)
> +{
> +return cs->interrupt_request & CPU_INTERRUPT_HARD;
> +}
> +#endif

There's no need to conditionalize this.

> +static void riscv_cpu_reset(CPUState *cs)
> +{
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
> +CPURISCVState *env = >env;
> +
> +mcc->parent_reset(cs);
> +#ifndef CONFIG_USER_ONLY
> +tlb_flush(cs);

Flush is now generic.  Remove it from here.

> +static void riscv_cpu_realize(DeviceState *dev, Error **errp)
> +{
> +CPUState *cs = CPU(dev);
> +RISCVCPU *cpu = RISCV_CPU(dev);
> +RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
> +CPURISCVState *env = >env;
> +Error *local_err = NULL;
> +
> +cpu_exec_realizefn(cs, _err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return;
> +}
> +
> +if (env->misa & RVM) {
> +set_feature(env, RISCV_FEATURE_RVM);
> +}

What's the point of replicating this information?

> +static void cpu_register(const RISCVCPUInfo *info)
> +{
> +TypeInfo type_info = {
> +.name = g_strdup(info->name),
> +.parent = TYPE_RISCV_CPU,
> +.instance_size = sizeof(RISCVCPU),
> +.instance_init = info->initfn,
> +};
> +
> +type_register(_info);
> +g_free((void *)type_info.name);
> +}

I think type_register does its own strdup; you don't need to do your own.


> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> new file mode 100644
> index 000..0480127
> --- /dev/null
> +++ b/target/riscv/cpu.h
> @@ -0,0 +1,363 @@
> +#ifndef RISCV_CPU_H

Header comment and license?

> +#define TARGET_HAS_ICE 1

What's this for?

> +#define RV(x) (1L << (x - 'A'))

L is useless since the type of long is variable.  Either U or ULL.

> +typedef struct CPURISCVState CPURISCVState;
> +
> +#include "pmp.h"
> +
> +typedef struct CPURISCVState {

Duplicate typedef.

> +target_ulong gpr[32];
> +uint64_t fpr[32]; /* assume both F and D extensions */
> +target_ulong pc;
> +target_ulong load_res;
> +
> +target_ulong frm;
> +target_ulong fstatus;
> +target_ulong fflags;
> +
> +target_ulong badaddr;
> +
> +uint32_t mucounteren;
> +
> +target_ulong user_ver;
> +target_ulong priv_ver;
> +target_ulong misa_mask;
> +target_ulong misa;
> +
> +#ifdef CONFIG_USER_ONLY
> +uint32_t amoinsn;
> +target_long amoaddr;
> +target_long amotest;
> +#else
> +target_ulong priv;
> +
> +target_ulong mhartid;
> +target_ulong mstatus;
> +target_ulong mip;
> +target_ulong mie;
> +target_ulong mideleg;
> +
> +target_ulong sptbr;  /* until: priv-1.9.1 */
> +target_ulong satp;   /* since: priv-1.10.0 */
> +target_ulong sbadaddr;
> +target_ulong mbadaddr;
> +target_ulong medeleg;
> +
> +target_ulong stvec;
> +target_ulong sepc;
> +target_ulong scause;
> +
> +target_ulong mtvec;
> +target_ulong mepc;
> +target_ulong mcause;
> +target_ulong mtval;  /* since: priv-1.10.0 */
> +
> +uint32_t mscounteren;
> +target_ulong scounteren; /* since: priv-1.10.0 */
> +target_ulong mcounteren; /* since: priv-1.10.0 */
> +
> +target_ulong sscratch;
> +target_ulong mscratch;
> +
> +/* temporary htif regs */
> +uint64_t mfromhost;
> +uint64_t mtohost;
> +uint64_t timecmp;
> +
> +/* physical memory protection */
> +pmp_table_t pmp_state;
> +#endif
> +
> +float_status fp_status;
> +
> +/* Internal CPU feature flags. */
> +uint64_t features;
> +
> +/* QEMU */
> +CPU_COMMON
> +
> +/* Fields from here on are preserved across CPU reset. */
> +void *irq[8];
> +QEMUTimer *timer; /* Internal timer */

FWIW, other targets have moved this timer to RISCVCPU struct.

> +static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> +target_ulong *cs_base, uint32_t 
> *flags)
> +{
> +*pc = env->pc;
> +*cs_base = 0;
> +*flags = 0; /* necessary to avoid compiler warning */

Remove the comment -- the assignment is necessary full stop.

> +#define MSTATUS64_UXL   0x0003
> +#define MSTATUS64_SXL   0x000C

64-bit constants must use ULL.  Otherwise builds from a 32-bit host will fail.
There are lots more instances within this file.


r~



[Qemu-devel] [Bug 1087411] Re: pseries machine breaks in instalation of SLES11_SP2

2018-01-02 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1087411

Title:
  pseries machine breaks in instalation of SLES11_SP2

Status in QEMU:
  Expired

Bug description:
  QEMU version: 1.0, 1.1, and 1.2

  Host OS:
  Intel(R) Core(TM) i5-2520M CPU @ 2.50GH
   Linux tpad 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 
x86_64 x86_64 x86_64 GNU/Linux

  SLES Media:
  SLES-11-SP2-DVD-ppc64-GM-DVD1.iso: sha256 -> 
2247dd6bb495eb50860668e46f7d6ba004eece9909f347c8ce487fd6a5f65ee1

  Command line:
  ./ppc64-softmmu/qemu-system-ppc64 -machine type=pseries,usb=off -m 512 -net 
nic,vlan=0 -net tap -nographic -cdrom 
  /exports/isos/SLES-11-SP2-DVD-ppc64-GM-DVD1.iso -hda 
/exports/sles11_sp2.qcow2 -monitor unix:/dev/tty1,nowait,server

  Error message (after starting instalation ~23%):
  Installation of package ./suse/ppc64/vim-base-7.2-8.15.2.ppc64.rpm failed.
  Subprocess failed. Error: RPM failed: error: 
%post(vim-base-7.2-8.15.2.ppc64.rpm)

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1087411/+subscriptions



[Qemu-devel] [Bug 1188018] Re: qemu monitor does not suppot rbd "savevm" command

2018-01-02 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1188018

Title:
  qemu monitor does not suppot rbd "savevm" command

Status in QEMU:
  Expired

Bug description:
  1. I used ceph rbd as my block device, /usr/local/bin/qemu-system-
  x86_64 -drive
  format=rbd,file=rbd:rbd/sles.img:rbd_cache=true,cache=writeback -boot
  c  -m 1024 -enable-kvm -vnc 0.0.0.0:0 -monitor stdio

  2. when in monitor command line "savevm", it reports "Error -95 while
  writing VM" in the monitor

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1188018/+subscriptions



[Qemu-devel] [PULL 06/15] ppc/pnv: change powernv_ prefix to pnv_ for overall naming consistency

2018-01-02 Thread David Gibson
From: Cédric Le Goater 

The 'pnv' prefix is now used for all and the routines populating the
device tree start with 'pnv_dt'. The handler of the PnvXScomInterface
is also renamed to 'dt_xscom' which should reflect that it is
populating the device tree under the 'xscom@' node of the chip.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c   | 94 ++
 hw/ppc/pnv_bmc.c   |  2 +-
 hw/ppc/pnv_core.c  |  8 ++--
 hw/ppc/pnv_lpc.c   |  6 +--
 hw/ppc/pnv_psi.c   |  4 +-
 hw/ppc/pnv_xscom.c | 10 ++---
 include/hw/ppc/pnv.h   | 10 ++---
 include/hw/ppc/pnv_xscom.h |  4 +-
 8 files changed, 67 insertions(+), 71 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 94ffc8e137..9475e8479c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -77,8 +77,7 @@ static const char *pnv_chip_core_typename(const PnvChip *o)
  * that has a different "affinity". In practice, it means one range
  * per chip.
  */
-static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr start,
- hwaddr size)
+static void pnv_dt_memory(void *fdt, int chip_id, hwaddr start, hwaddr size)
 {
 char *mem_name;
 uint64_t mem_reg_property[2];
@@ -119,7 +118,7 @@ static int get_cpus_node(void *fdt)
  * device tree, used in XSCOM to address cores and in interrupt
  * servers.
  */
-static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
+static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
 {
 CPUState *cs = CPU(DEVICE(pc->threads));
 DeviceClass *dc = DEVICE_GET_CLASS(cs);
@@ -228,8 +227,8 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore 
*pc, void *fdt)
servers_prop, sizeof(servers_prop;
 }
 
-static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir,
- uint32_t nr_threads)
+static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
+   uint32_t nr_threads)
 {
 uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
 char *name;
@@ -277,13 +276,13 @@ static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
 return offset;
 }
 
-static void powernv_populate_chip(PnvChip *chip, void *fdt)
+static void pnv_dt_chip(PnvChip *chip, void *fdt)
 {
 const char *typename = pnv_chip_core_typename(chip);
 size_t typesize = object_type_get_instance_size(typename);
 int i;
 
-pnv_xscom_populate(chip, fdt, 0);
+pnv_dt_xscom(chip, fdt, 0);
 
 /* The default LPC bus of a multichip system is on chip 0. It's
  * recognized by the firmware (skiboot) using a "primary"
@@ -298,20 +297,18 @@ static void powernv_populate_chip(PnvChip *chip, void 
*fdt)
 for (i = 0; i < chip->nr_cores; i++) {
 PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
 
-powernv_create_core_node(chip, pnv_core, fdt);
+pnv_dt_core(chip, pnv_core, fdt);
 
 /* Interrupt Control Presenters (ICP). One per core. */
-powernv_populate_icp(chip, fdt, pnv_core->pir,
- CPU_CORE(pnv_core)->nr_threads);
+pnv_dt_icp(chip, fdt, pnv_core->pir, CPU_CORE(pnv_core)->nr_threads);
 }
 
 if (chip->ram_size) {
-powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
- chip->ram_size);
+pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
 }
 }
 
-static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off)
+static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
 {
 uint32_t io_base = d->ioport_id;
 uint32_t io_regs[] = {
@@ -331,7 +328,7 @@ static void powernv_populate_rtc(ISADevice *d, void *fdt, 
int lpc_off)
 _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00")));
 }
 
-static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
+static void pnv_dt_serial(ISADevice *d, void *fdt, int lpc_off)
 {
 const char compatible[] = "ns16550\0pnpPNP,501";
 uint32_t io_base = d->ioport_id;
@@ -362,7 +359,7 @@ static void powernv_populate_serial(ISADevice *d, void 
*fdt, int lpc_off)
 _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
 }
 
-static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
+static void pnv_dt_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
 {
 const char compatible[] = "bt\0ipmi-bt";
 uint32_t io_base;
@@ -401,17 +398,17 @@ typedef struct ForeachPopulateArgs {
 int offset;
 } ForeachPopulateArgs;
 
-static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
+static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
 {
 ForeachPopulateArgs *args = opaque;
 ISADevice *d = ISA_DEVICE(dev);
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) {
-powernv_populate_rtc(d, 

[Qemu-devel] [PULL 13/15] spapr_pci: use warn_report()

2018-01-02 Thread David Gibson
From: Greg Kurz 

These two are definitely warnings. Let's use the appropriate API.

Signed-off-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c  | 6 +++---
 hw/ppc/spapr_pci_vfio.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 88797b3d36..695c820911 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1696,9 +1696,9 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
 /* DMA setup */
 if (((sphb->page_size_mask & qemu_getrampagesize()) == 0)
 && kvm_enabled()) {
-error_report("System page size 0x%lx is not enabled in page_size_mask "
- "(0x%"PRIx64"). Performance may be slow",
- qemu_getrampagesize(), sphb->page_size_mask);
+warn_report("System page size 0x%lx is not enabled in page_size_mask "
+"(0x%"PRIx64"). Performance may be slow",
+qemu_getrampagesize(), sphb->page_size_mask);
 }
 
 for (i = 0; i < windows_supported; ++i) {
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 8448e0b024..1f775ea93d 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -50,7 +50,7 @@ static Property spapr_phb_vfio_properties[] = {
 static void spapr_phb_vfio_instance_init(Object *obj)
 {
 if (!qtest_enabled()) {
-error_report("spapr-pci-vfio-host-bridge is deprecated");
+warn_report("spapr-pci-vfio-host-bridge is deprecated");
 }
 }
 
-- 
2.14.3




[Qemu-devel] [PULL 14/15] hw/ide: Emulate SiI3112 SATA controller

2018-01-02 Thread David Gibson
From: BALATON Zoltan 

This is a common generic PCI SATA controller that is also used in PCs
but more importantly guests running on the Sam460ex board prefer this
card and have a driver for it (unlike for other SATA controllers
already emulated).

Signed-off-by: BALATON Zoltan 
Acked-by: John Snow 
Signed-off-by: David Gibson 
---
 MAINTAINERS|   6 +
 default-configs/ppcemb-softmmu.mak |   1 +
 hw/ide/Makefile.objs   |   1 +
 hw/ide/sii3112.c   | 368 +
 hw/ide/trace-events|   5 +
 5 files changed, 381 insertions(+)
 create mode 100644 hw/ide/sii3112.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 73a735..40cd7ee841 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -765,6 +765,12 @@ L: qemu-...@nongnu.org
 S: Odd Fixes
 F: hw/ppc/virtex_ml507.c
 
+sam460ex
+M: BALATON Zoltan 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/ide/sii3112.c
+
 SH4 Machines
 
 R2D
diff --git a/default-configs/ppcemb-softmmu.mak 
b/default-configs/ppcemb-softmmu.mak
index 13917fb7a3..5db4618a5a 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -16,3 +16,4 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_SM501=y
+CONFIG_IDE_SII3112=y
diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs
index f0edca3300..fc328ffbe8 100644
--- a/hw/ide/Makefile.objs
+++ b/hw/ide/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_MICRODRIVE) += microdrive.o
 common-obj-$(CONFIG_AHCI) += ahci.o
 common-obj-$(CONFIG_AHCI) += ich.o
 common-obj-$(CONFIG_ALLWINNER_A10) += ahci-allwinner.o
+common-obj-$(CONFIG_IDE_SII3112) += sii3112.o
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
new file mode 100644
index 00..e2f5562bb7
--- /dev/null
+++ b/hw/ide/sii3112.c
@@ -0,0 +1,368 @@
+/*
+ * QEMU SiI3112A PCI to Serial ATA Controller Emulation
+ *
+ * Copyright (C) 2017 BALATON Zoltan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* For documentation on this and similar cards see:
+ * http://wiki.osdev.org/User:Quok/Silicon_Image_Datasheets
+ */
+
+#include 
+#include 
+#include "trace.h"
+
+#define TYPE_SII3112_PCI "sii3112"
+#define SII3112_PCI(obj) OBJECT_CHECK(SiI3112PCIState, (obj), \
+ TYPE_SII3112_PCI)
+
+typedef struct SiI3112Regs {
+uint32_t confstat;
+uint32_t scontrol;
+uint16_t sien;
+uint8_t swdata;
+} SiI3112Regs;
+
+typedef struct SiI3112PCIState {
+PCIIDEState i;
+MemoryRegion mmio;
+SiI3112Regs regs[2];
+} SiI3112PCIState;
+
+/* The sii3112_reg_read and sii3112_reg_write functions implement the
+ * Internal Register Space - BAR5 (section 6.7 of the data sheet).
+ */
+
+static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+SiI3112PCIState *d = opaque;
+uint64_t val = 0;
+
+switch (addr) {
+case 0x00:
+val = d->i.bmdma[0].cmd;
+break;
+case 0x01:
+val = d->regs[0].swdata;
+break;
+case 0x02:
+val = d->i.bmdma[0].status;
+break;
+case 0x03:
+val = 0;
+break;
+case 0x04 ... 0x07:
+val = bmdma_addr_ioport_ops.read(>i.bmdma[0], addr - 4, size);
+break;
+case 0x08:
+val = d->i.bmdma[1].cmd;
+break;
+case 0x09:
+val = d->regs[1].swdata;
+break;
+case 0x0a:
+val = d->i.bmdma[1].status;
+break;
+case 0x0b:
+val = 0;
+break;
+case 0x0c ... 0x0f:
+val = bmdma_addr_ioport_ops.read(>i.bmdma[1], addr - 12, size);
+break;
+case 0x10:
+val = d->i.bmdma[0].cmd;
+val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
+val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 6) : 0); /*SATAINT1*/
+val |= (d->i.bmdma[1].status & BM_STATUS_INT ? (1 << 14) : 0);
+val |= d->i.bmdma[0].status << 16;
+val |= d->i.bmdma[1].status << 24;
+break;
+case 0x18:
+val = d->i.bmdma[1].cmd;
+val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
+val |= d->i.bmdma[1].status << 16;
+break;
+case 0x80 ... 0x87:
+if (size == 1) {
+val = ide_ioport_read(>i.bus[0], addr - 0x80);
+} else if (addr == 0x80) {
+val = (size == 2) ? ide_data_readw(>i.bus[0], 0) :
+ide_data_readl(>i.bus[0], 0);
+} else {
+val = (1ULL << (size * 8)) - 1;
+}
+break;
+case 0x8a:
+val = (size == 1) ? ide_status_read(>i.bus[0], 4) :
+(1ULL << (size * 8)) - 1;
+break;
+case 0xa0:
+val = d->regs[0].confstat;

[Qemu-devel] [PULL 11/15] spapr: Handle VMX/VSX presence as an spapr capability flag

2018-01-02 Thread David Gibson
We currently have some conditionals in the spapr device tree code to decide
whether or not to advertise the availability of the VMX (aka Altivec) and
VSX vector extensions to the guest, based on whether the guest cpu has
those features.

This can lead to confusion and subtle failures on migration, since it makes
a guest visible change based only on host capabilities.  We now have a
better mechanism for this, in spapr capabilities flags, which explicitly
depend on user options rather than host capabilities.

Rework the advertisement of VSX and VMX based on a new VSX capability.  We
no longer bother with a conditional for VMX support, because every CPU
that's ever been supported by the pseries machine type supports VMX.

NOTE: Some userspace distributions (e.g. RHEL7.4) already rely on
availability of VSX in libc, so using cap-vsx=off may lead to a fatal
SIGILL in init.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c | 20 +++-
 hw/ppc/spapr_caps.c| 25 +
 include/hw/ppc/spapr.h |  3 +++
 3 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 86fc83f9c2..693dd6f7b3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -557,14 +557,16 @@ static void spapr_populate_cpu_dt(CPUState *cs, void 
*fdt, int offset,
   segs, sizeof(segs;
 }
 
-/* Advertise VMX/VSX (vector extensions) if available
- *   0 / no property == no vector extensions
+/* Advertise VSX (vector extensions) if available
  *   1   == VMX / Altivec available
- *   2   == VSX available */
-if (env->insns_flags & PPC_ALTIVEC) {
-uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
-
-_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
+ *   2   == VSX available
+ *
+ * Only CPUs for which we create core types in spapr_cpu_core.c
+ * are possible, and all of those have VMX */
+if (spapr_has_cap(spapr, SPAPR_CAP_VSX)) {
+_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
+} else {
+_FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
 }
 
 /* Advertise DFP (Decimal Floating Point) if available
@@ -3832,7 +3834,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
  */
 mc->numa_mem_align_shift = 28;
 
-smc->default_caps = spapr_caps(0);
+smc->default_caps = spapr_caps(SPAPR_CAP_VSX);
 spapr_caps_add_properties(smc, _abort);
 }
 
@@ -3914,7 +3916,7 @@ static void spapr_machine_2_11_class_options(MachineClass 
*mc)
 sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
 
 spapr_machine_2_12_class_options(mc);
-smc->default_caps = spapr_caps(SPAPR_CAP_HTM);
+smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX);
 SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
 }
 
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index cad40fe49a..7c855c67ad 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -57,6 +57,19 @@ static void cap_htm_allow(sPAPRMachineState *spapr, Error 
**errp)
 }
 }
 
+static void cap_vsx_allow(sPAPRMachineState *spapr, Error **errp)
+{
+PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+CPUPPCState *env = >env;
+
+/* Allowable CPUs in spapr_cpu_core.c should already have gotten
+ * rid of anything that doesn't do VMX */
+g_assert(env->insns_flags & PPC_ALTIVEC);
+if (!(env->insns_flags2 & PPC2_VSX)) {
+error_setg(errp, "VSX support not available, try cap-vsx=off");
+}
+}
+
 static sPAPRCapabilityInfo capability_table[] = {
 {
 .name = "htm",
@@ -65,6 +78,13 @@ static sPAPRCapabilityInfo capability_table[] = {
 .allow = cap_htm_allow,
 /* TODO: add cap_htm_disallow */
 },
+{
+.name = "vsx",
+.description = "Allow Vector Scalar Extensions (VSX)",
+.flag = SPAPR_CAP_VSX,
+.allow = cap_vsx_allow,
+/* TODO: add cap_vsx_disallow */
+},
 };
 
 static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
@@ -81,6 +101,11 @@ static sPAPRCapabilities 
default_caps_with_cpu(sPAPRMachineState *spapr,
 caps.mask &= ~SPAPR_CAP_HTM;
 }
 
+if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
+  0, spapr->max_compat_pvr)) {
+caps.mask &= ~SPAPR_CAP_VSX;
+}
+
 return caps;
 }
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 5c85f39c3b..148a03d189 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -59,6 +59,9 @@ typedef enum {
 /* Hardware Transactional Memory */
 #define SPAPR_CAP_HTM   0x0001ULL
 
+/* Vector Scalar Extensions */
+#define SPAPR_CAP_VSX   0x0002ULL
+
 typedef struct sPAPRCapabilities sPAPRCapabilities;
 struct sPAPRCapabilities {
 uint64_t mask;
-- 
2.14.3




[Qemu-devel] [PULL 05/15] ppc4xx_i2c: Implement basic I2C functions

2018-01-02 Thread David Gibson
From: BALATON Zoltan 

Enough to please U-Boot and make it able to detect SDRAM SPD EEPROMs

Signed-off-by: François Revol 
Signed-off-by: BALATON Zoltan 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 hw/i2c/ppc4xx_i2c.c | 198 +---
 include/hw/i2c/ppc4xx_i2c.h |   3 +
 2 files changed, 171 insertions(+), 30 deletions(-)

diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c
index 5a6bde951e..e873a445da 100644
--- a/hw/i2c/ppc4xx_i2c.c
+++ b/hw/i2c/ppc4xx_i2c.c
@@ -2,6 +2,8 @@
  * PPC4xx I2C controller emulation
  *
  * Copyright (c) 2007 Jocelyn Mayer
+ * Copyright (c) 2012 François Revol
+ * Copyright (c) 2016 BALATON Zoltan
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -25,26 +27,118 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
+#include "qemu/log.h"
 #include "cpu.h"
 #include "hw/hw.h"
 #include "hw/i2c/ppc4xx_i2c.h"
 
-/*#define DEBUG_I2C*/
+#define PPC4xx_I2C_MEM_SIZE 0x12
 
-#define PPC4xx_I2C_MEM_SIZE 0x11
+#define IIC_CNTL_PT (1 << 0)
+#define IIC_CNTL_READ   (1 << 1)
+#define IIC_CNTL_CHT(1 << 2)
+#define IIC_CNTL_RPST   (1 << 3)
+
+#define IIC_STS_PT  (1 << 0)
+#define IIC_STS_ERR (1 << 2)
+#define IIC_STS_MDBS(1 << 5)
+
+#define IIC_EXTSTS_XFRA (1 << 0)
+
+#define IIC_XTCNTLSS_SRST   (1 << 0)
+
+static void ppc4xx_i2c_reset(DeviceState *s)
+{
+PPC4xxI2CState *i2c = PPC4xx_I2C(s);
+
+/* FIXME: Should also reset bus?
+ *if (s->address != ADDR_RESET) {
+ *i2c_end_transfer(s->bus);
+ *}
+ */
+
+i2c->mdata = 0;
+i2c->lmadr = 0;
+i2c->hmadr = 0;
+i2c->cntl = 0;
+i2c->mdcntl = 0;
+i2c->sts = 0;
+i2c->extsts = 0x8f;
+i2c->sdata = 0;
+i2c->lsadr = 0;
+i2c->hsadr = 0;
+i2c->clkdiv = 0;
+i2c->intrmsk = 0;
+i2c->xfrcnt = 0;
+i2c->xtcntlss = 0;
+i2c->directcntl = 0x0f;
+i2c->intr = 0;
+}
+
+static inline bool ppc4xx_i2c_is_master(PPC4xxI2CState *i2c)
+{
+return true;
+}
 
 static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
 {
 PPC4xxI2CState *i2c = PPC4xx_I2C(opaque);
 uint64_t ret;
 
-#ifdef DEBUG_I2C
-printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
 switch (addr) {
 case 0x00:
-/*i2c_readbyte(>mdata);*/
 ret = i2c->mdata;
+if (ppc4xx_i2c_is_master(i2c)) {
+ret = 0xff;
+
+if (!(i2c->sts & IIC_STS_MDBS)) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
+  "without starting transfer\n",
+  TYPE_PPC4xx_I2C, __func__);
+} else {
+int pending = (i2c->cntl >> 4) & 3;
+
+/* get the next byte */
+int byte = i2c_recv(i2c->bus);
+
+if (byte < 0) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed "
+  "for device 0x%02x\n", TYPE_PPC4xx_I2C,
+  __func__, i2c->lmadr);
+ret = 0xff;
+} else {
+ret = byte;
+/* Raise interrupt if enabled */
+/*ppc4xx_i2c_raise_interrupt(i2c)*/;
+}
+
+if (!pending) {
+i2c->sts &= ~IIC_STS_MDBS;
+/*i2c_end_transfer(i2c->bus);*/
+/*} else if (i2c->cntl & (IIC_CNTL_RPST | IIC_CNTL_CHT)) {*/
+} else if (pending) {
+/* current smbus implementation doesn't like
+   multibyte xfer repeated start */
+i2c_end_transfer(i2c->bus);
+if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) {
+/* if non zero is returned, the adress is not valid */
+i2c->sts &= ~IIC_STS_PT;
+i2c->sts |= IIC_STS_ERR;
+i2c->extsts |= IIC_EXTSTS_XFRA;
+} else {
+/*i2c->sts |= IIC_STS_PT;*/
+i2c->sts |= IIC_STS_MDBS;
+i2c->sts &= ~IIC_STS_ERR;
+i2c->extsts = 0;
+}
+}
+pending--;
+i2c->cntl = (i2c->cntl & 0xcf) | (pending << 4);
+}
+} else {
+qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
+  TYPE_PPC4xx_I2C, __func__);
+}
 break;
 case 0x02:
 ret = i2c->sdata;
@@ -88,13 +182,15 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr 
addr, unsigned 

[Qemu-devel] [PULL 04/15] sm501: Add some more unimplemented registers

2018-01-02 Thread David Gibson
From: BALATON Zoltan 

These are not really implemented (just return zero or default values)
but add these so guests accessing them can run.

Signed-off-by: BALATON Zoltan 
Signed-off-by: David Gibson 
---
 hw/display/sm501.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index b9b611131e..4f7dc59b25 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -795,6 +795,8 @@ static uint64_t sm501_system_config_read(void *opaque, 
hwaddr addr,
 case SM501_ARBTRTN_CONTROL:
 ret = s->arbitration_control;
 break;
+case SM501_COMMAND_LIST_STATUS:
+ret = 0x00180002; /* FIFOs are empty, everything idle */
 case SM501_IRQ_MASK:
 ret = s->irq_mask;
 break;
@@ -812,6 +814,9 @@ static uint64_t sm501_system_config_read(void *opaque, 
hwaddr addr,
 case SM501_POWER_MODE_CONTROL:
 ret = s->power_mode_control;
 break;
+case SM501_ENDIAN_CONTROL:
+ret = 0; /* Only default little endian mode is supported */
+break;
 
 default:
 printf("sm501 system config : not implemented register read."
@@ -865,6 +870,12 @@ static void sm501_system_config_write(void *opaque, hwaddr 
addr,
 case SM501_POWER_MODE_CONTROL:
 s->power_mode_control = value & 0x0003;
 break;
+case SM501_ENDIAN_CONTROL:
+if (value & 0x0001) {
+printf("sm501 system config : big endian mode not implemented.\n");
+abort();
+}
+break;
 
 default:
 printf("sm501 system config : not implemented register write."
@@ -924,6 +935,9 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr 
addr,
 case SM501_DC_PANEL_PANNING_CONTROL:
 ret = s->dc_panel_panning_control;
 break;
+case SM501_DC_PANEL_COLOR_KEY:
+/* Not implemented yet */
+break;
 case SM501_DC_PANEL_FB_ADDR:
 ret = s->dc_panel_fb_addr;
 break;
@@ -1035,6 +1049,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr 
addr,
 case SM501_DC_PANEL_PANNING_CONTROL:
 s->dc_panel_panning_control = value & 0xFF3FFF3F;
 break;
+case SM501_DC_PANEL_COLOR_KEY:
+/* Not implemented yet */
+break;
 case SM501_DC_PANEL_FB_ADDR:
 s->dc_panel_fb_addr = value & 0x8FF0;
 break;
-- 
2.14.3




[Qemu-devel] [PULL 07/15] spapr: Capabilities infrastructure

2018-01-02 Thread David Gibson
Because PAPR is a paravirtual environment access to certain CPU (or other)
facilities can be blocked by the hypervisor.  PAPR provides ways to
advertise in the device tree whether or not those features are available to
the guest.

In some places we automatically determine whether to make a feature
available based on whether our host can support it, in most cases this is
based on limitations in the available KVM implementation.

Although we correctly advertise this to the guest, it means that host
factors might make changes to the guest visible environment which is bad:
as well as generaly reducing reproducibility, it means that a migration
between different host environments can easily go bad.

We've mostly gotten away with it because the environments considered mature
enough to be well supported (basically, KVM on POWER8) have had consistent
feature availability.  But, it's still not right and some limitations on
POWER9 is going to make it more of an issue in future.

This introduces an infrastructure for defining "sPAPR capabilities".  These
are set by default based on the machine version, masked by the capabilities
of the chosen cpu, but can be overriden with machine properties.

The intention is at reset time we verify that the requested capabilities
can be supported on the host (considering TCG, KVM and/or host cpu
limitations).  If not we simply fail, rather than silently modifying the
advertised featureset to the guest.

This does mean that certain configurations that "worked" may now fail, but
such configurations were already more subtly broken.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/Makefile.objs   |   2 +-
 hw/ppc/spapr.c |   7 ++
 hw/ppc/spapr_caps.c| 181 +
 include/hw/ppc/spapr.h |  31 +
 4 files changed, 220 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/spapr_caps.c

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 7efc686748..1faff853b7 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -1,7 +1,7 @@
 # shared objects
 obj-y += ppc.o ppc_booke.o fdt.o
 # IBM pSeries (sPAPR)
-obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
+obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o
 obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6785a90c60..d472baef8d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1466,6 +1466,8 @@ static void spapr_machine_reset(void)
 /* Check for unknown sysbus devices */
 foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
 
+spapr_caps_reset(spapr);
+
 first_ppc_cpu = POWERPC_CPU(first_cpu);
 if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
 ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
@@ -2311,6 +2313,8 @@ static void spapr_machine_init(MachineState *machine)
 char *filename;
 Error *resize_hpt_err = NULL;
 
+spapr_caps_validate(spapr, _fatal);
+
 msi_nonbroken = true;
 
 QLIST_INIT(>phbs);
@@ -3819,6 +3823,9 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
  * in which LMBs are represented and hot-added
  */
 mc->numa_mem_align_shift = 28;
+
+smc->default_caps = spapr_caps(0);
+spapr_caps_add_properties(smc, _abort);
 }
 
 static const TypeInfo spapr_machine_info = {
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
new file mode 100644
index 00..968ba7b857
--- /dev/null
+++ b/hw/ppc/spapr_caps.c
@@ -0,0 +1,181 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition capabilities handling
+ *
+ * Copyright (c) 2017 David Gibson, Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"

[Qemu-devel] [PULL 15/15] target/ppc: more use of the PPC_*() macros

2018-01-02 Thread David Gibson
From: Cédric Le Goater 

Also introduce utilities to manipulate bitmasks (originaly from OPAL)
which be will be used in the model of the XIVE interrupt controller.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_lpc.c| 10 -
 target/ppc/cpu.h| 56 ++---
 target/ppc/int_helper.c |  2 +-
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index b777b78e18..c42b4a8f6c 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -146,13 +146,13 @@ static bool opb_write(PnvLpcController *lpc, uint32_t 
addr, uint8_t *data,
 return success;
 }
 
-#define ECCB_CTL_READ   (1ull << (63 - 15))
+#define ECCB_CTL_READ   PPC_BIT(15)
 #define ECCB_CTL_SZ_LSH (63 - 7)
-#define ECCB_CTL_SZ_MASK(0xfull << ECCB_CTL_SZ_LSH)
-#define ECCB_CTL_ADDR_MASK  0xu;
+#define ECCB_CTL_SZ_MASKPPC_BITMASK(4, 7)
+#define ECCB_CTL_ADDR_MASK  PPC_BITMASK(32, 63)
 
-#define ECCB_STAT_OP_DONE   (1ull << (63 - 52))
-#define ECCB_STAT_OP_ERR(1ull << (63 - 52))
+#define ECCB_STAT_OP_DONE   PPC_BIT(52)
+#define ECCB_STAT_OP_ERRPPC_BIT(52)
 #define ECCB_STAT_RD_DATA_LSH   (63 - 37)
 #define ECCB_STAT_RD_DATA_MASK  (0x << ECCB_STAT_RD_DATA_LSH)
 
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 370b05e76e..a5e49f23e9 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -93,6 +93,19 @@
 #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
 #define PPC_BITMASK32(bs, be)   ((PPC_BIT32(bs) - PPC_BIT32(be)) | \
  PPC_BIT32(bs))
+#define PPC_BITMASK8(bs, be)((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(bs))
+
+#if HOST_LONG_BITS == 32
+# define MASK_TO_LSH(m)  (__builtin_ffsll(m) - 1)
+#elif HOST_LONG_BITS == 64
+# define MASK_TO_LSH(m)  (__builtin_ffsl(m) - 1)
+#else
+# error Unknown sizeof long
+#endif
+
+#define GETFIELD(m, v)  (((v) & (m)) >> MASK_TO_LSH(m))
+#define SETFIELD(m, v, val) \
+(((v) & ~(m)) | typeof(v))(val)) << MASK_TO_LSH(m)) & (m)))
 
 /*/
 /* Exception vectors definitions */
@@ -2349,32 +2362,31 @@ enum {
 
 /* Processor Compatibility mask (PCR) */
 enum {
-PCR_COMPAT_2_05 = 1ull << (63-62),
-PCR_COMPAT_2_06 = 1ull << (63-61),
-PCR_COMPAT_2_07 = 1ull << (63-60),
-PCR_COMPAT_3_00 = 1ull << (63-59),
-PCR_VEC_DIS = 1ull << (63-0), /* Vec. disable (bit NA since 
POWER8) */
-PCR_VSX_DIS = 1ull << (63-1), /* VSX disable (bit NA since POWER8) 
*/
-PCR_TM_DIS  = 1ull << (63-2), /* Trans. memory disable (POWER8) */
+PCR_COMPAT_2_05 = PPC_BIT(62),
+PCR_COMPAT_2_06 = PPC_BIT(61),
+PCR_COMPAT_2_07 = PPC_BIT(60),
+PCR_COMPAT_3_00 = PPC_BIT(59),
+PCR_VEC_DIS = PPC_BIT(0), /* Vec. disable (bit NA since POWER8) */
+PCR_VSX_DIS = PPC_BIT(1), /* VSX disable (bit NA since POWER8) */
+PCR_TM_DIS  = PPC_BIT(2), /* Trans. memory disable (POWER8) */
 };
 
 /* HMER/HMEER */
 enum {
-HMER_MALFUNCTION_ALERT  = 1ull << (63 - 0),
-HMER_PROC_RECV_DONE = 1ull << (63 - 2),
-HMER_PROC_RECV_ERROR_MASKED = 1ull << (63 - 3),
-HMER_TFAC_ERROR = 1ull << (63 - 4),
-HMER_TFMR_PARITY_ERROR  = 1ull << (63 - 5),
-HMER_XSCOM_FAIL = 1ull << (63 - 8),
-HMER_XSCOM_DONE = 1ull << (63 - 9),
-HMER_PROC_RECV_AGAIN= 1ull << (63 - 11),
-HMER_WARN_RISE  = 1ull << (63 - 14),
-HMER_WARN_FALL  = 1ull << (63 - 15),
-HMER_SCOM_FIR_HMI   = 1ull << (63 - 16),
-HMER_TRIG_FIR_HMI   = 1ull << (63 - 17),
-HMER_HYP_RESOURCE_ERR   = 1ull << (63 - 20),
-HMER_XSCOM_STATUS_MASK  = 7ull << (63 - 23),
-HMER_XSCOM_STATUS_LSH   = (63 - 23),
+HMER_MALFUNCTION_ALERT  = PPC_BIT(0),
+HMER_PROC_RECV_DONE = PPC_BIT(2),
+HMER_PROC_RECV_ERROR_MASKED = PPC_BIT(3),
+HMER_TFAC_ERROR = PPC_BIT(4),
+HMER_TFMR_PARITY_ERROR  = PPC_BIT(5),
+HMER_XSCOM_FAIL = PPC_BIT(8),
+HMER_XSCOM_DONE = PPC_BIT(9),
+HMER_PROC_RECV_AGAIN= PPC_BIT(11),
+HMER_WARN_RISE  = PPC_BIT(14),
+HMER_WARN_FALL  = PPC_BIT(15),
+HMER_SCOM_FIR_HMI   = PPC_BIT(16),
+HMER_TRIG_FIR_HMI   = PPC_BIT(17),
+HMER_HYP_RESOURCE_ERR   = PPC_BIT(20),
+HMER_XSCOM_STATUS_MASK  = PPC_BITMASK(21, 23),
 };
 
 /* Alternate Interrupt Location (AIL) */
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 1c013a0ee3..3a50f1e1b7 100644
--- 

[Qemu-devel] [PULL 09/15] spapr: Validate capabilities on migration

2018-01-02 Thread David Gibson
Now that the "pseries" machine type implements optional capabilities (well,
one so far) there's the possibility of having different capabilities
available at either end of a migration.  Although arguably a user error,
it would be nice to catch this situation and fail as gracefully as we can.

This adds code to migrate the capabilities flags.  These aren't pulled
directly into the destination's configuration since what the user has
specified on the destination command line should take precedence.  However,
they are checked against the destination capabilities.

If the source was using a capability which is absent on the destination,
we fail the migration, since that could easily cause a guest crash or other
bad behaviour.  If the source lacked a capability which is present on the
destination we warn, but allow the migration to proceed.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c |  6 
 hw/ppc/spapr_caps.c| 96 --
 include/hw/ppc/spapr.h |  6 
 3 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f8fee8ebcf..86fc83f9c2 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1589,6 +1589,11 @@ static int spapr_post_load(void *opaque, int version_id)
 sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
 int err = 0;
 
+err = spapr_caps_post_migration(spapr);
+if (err) {
+return err;
+}
+
 if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
 CPUState *cs;
 CPU_FOREACH(cs) {
@@ -1755,6 +1760,7 @@ static const VMStateDescription vmstate_spapr = {
 _spapr_ov5_cas,
 _spapr_patb_entry,
 _spapr_pending_events,
+_spapr_caps,
 NULL
 }
 };
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 3b35b91a5b..cad40fe49a 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "sysemu/hw_accel.h"
@@ -83,6 +84,93 @@ static sPAPRCapabilities 
default_caps_with_cpu(sPAPRMachineState *spapr,
 return caps;
 }
 
+static bool spapr_caps_needed(void *opaque)
+{
+sPAPRMachineState *spapr = opaque;
+
+return (spapr->forced_caps.mask != 0) || (spapr->forbidden_caps.mask != 0);
+}
+
+/* This has to be called from the top-level spapr post_load, not the
+ * caps specific one.  Otherwise it wouldn't be called when the source
+ * caps are all defaults, which could still conflict with overridden
+ * caps on the destination */
+int spapr_caps_post_migration(sPAPRMachineState *spapr)
+{
+uint64_t allcaps = 0;
+int i;
+bool ok = true;
+sPAPRCapabilities dstcaps = spapr->effective_caps;
+sPAPRCapabilities srccaps;
+
+srccaps = default_caps_with_cpu(spapr, first_cpu);
+srccaps.mask |= spapr->mig_forced_caps.mask;
+srccaps.mask &= ~spapr->mig_forbidden_caps.mask;
+
+for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
+sPAPRCapabilityInfo *info = _table[i];
+
+allcaps |= info->flag;
+
+if ((srccaps.mask & info->flag) && !(dstcaps.mask & info->flag)) {
+error_report("cap-%s=on in incoming stream, but off in 
destination",
+ info->name);
+ok = false;
+}
+
+if (!(srccaps.mask & info->flag) && (dstcaps.mask & info->flag)) {
+warn_report("cap-%s=off in incoming stream, but on in destination",
+ info->name);
+}
+}
+
+if (spapr->mig_forced_caps.mask & ~allcaps) {
+error_report(
+"Unknown capabilities 0x%"PRIx64" enabled in incoming stream",
+spapr->mig_forced_caps.mask & ~allcaps);
+ok = false;
+}
+if (spapr->mig_forbidden_caps.mask & ~allcaps) {
+warn_report(
+"Unknown capabilities 0x%"PRIx64" disabled in incoming stream",
+spapr->mig_forbidden_caps.mask & ~allcaps);
+}
+
+return ok ? 0 : -EINVAL;
+}
+
+static int spapr_caps_pre_save(void *opaque)
+{
+sPAPRMachineState *spapr = opaque;
+
+spapr->mig_forced_caps = spapr->forced_caps;
+spapr->mig_forbidden_caps = spapr->forbidden_caps;
+return 0;
+}
+
+static int spapr_caps_pre_load(void *opaque)
+{
+sPAPRMachineState *spapr = opaque;
+
+spapr->mig_forced_caps = spapr_caps(0);
+spapr->mig_forbidden_caps = spapr_caps(0);
+return 0;
+}
+
+const VMStateDescription vmstate_spapr_caps = {
+.name = "spapr/caps",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = spapr_caps_needed,
+.pre_save = spapr_caps_pre_save,
+.pre_load = spapr_caps_pre_load,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(mig_forced_caps.mask, sPAPRMachineState),
+VMSTATE_UINT64(mig_forbidden_caps.mask, sPAPRMachineState),
+

[Qemu-devel] [PULL 08/15] spapr: Treat Hardware Transactional Memory (HTM) as an optional capability

2018-01-02 Thread David Gibson
This adds an spapr capability bit for Hardware Transactional Memory.  It is
enabled by default for pseries-2.11 and earlier machine types. with POWER8
or later CPUs (as it must be, since earlier qemu versions would implicitly
allow it).  However it is disabled by default for the latest pseries-2.12
machine type.

This means that with the latest machine type, HTM will not be available,
regardless of CPU, unless it is explicitly enabled on the command line.
That change is made on the basis that:

 * This way running with -M pseries,accel=tcg will start with whatever cpu
   and will provide the same guest visible model as with accel=kvm.
 - More specifically, this means existing make check tests don't have
   to be modified to use cap-htm=off in order to run with TCG

 * We hope to add a new "HTM without suspend" feature in the not too
   distant future which could work on both POWER8 and POWER9 cpus, and
   could be enabled by default.

 * Best guesses suggest that future POWER cpus may well only support the
   HTM-without-suspend model, not the (frankly, horribly overcomplicated)
   POWER8 style HTM with suspend.

 * Anecdotal evidence suggests problems with HTM being enabled when it
   wasn't wanted are more common than being missing when it was.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c | 15 ++-
 hw/ppc/spapr_caps.c| 29 -
 include/hw/ppc/spapr.h |  3 +++
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d472baef8d..f8fee8ebcf 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -253,7 +253,9 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, 
PowerPCCPU *cpu)
 }
 
 /* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
+static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+   PowerPCCPU *cpu,
+   void *fdt, int offset,
bool legacy_guest)
 {
 CPUPPCState *env = >env;
@@ -318,7 +320,7 @@ static void spapr_populate_pa_features(PowerPCCPU *cpu, 
void *fdt, int offset,
  */
 pa_features[3] |= 0x20;
 }
-if (kvmppc_has_cap_htm() && pa_size > 24) {
+if (spapr_has_cap(spapr, SPAPR_CAP_HTM) && pa_size > 24) {
 pa_features[24] |= 0x80;/* Transactional memory support */
 }
 if (legacy_guest && pa_size > 40) {
@@ -384,8 +386,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState 
*spapr)
 return ret;
 }
 
-spapr_populate_pa_features(cpu, fdt, offset,
- spapr->cas_legacy_guest_workaround);
+spapr_populate_pa_features(spapr, cpu, fdt, offset,
+   spapr->cas_legacy_guest_workaround);
 }
 return ret;
 }
@@ -579,7 +581,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, 
int offset,
   page_sizes_prop, page_sizes_prop_size)));
 }
 
-spapr_populate_pa_features(cpu, fdt, offset, false);
+spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
 
 _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
cs->cpu_index / vcpus_per_socket)));
@@ -3903,7 +3905,10 @@ static void 
spapr_machine_2_11_instance_options(MachineState *machine)
 
 static void spapr_machine_2_11_class_options(MachineClass *mc)
 {
+sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
 spapr_machine_2_12_class_options(mc);
+smc->default_caps = spapr_caps(SPAPR_CAP_HTM);
 SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
 }
 
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 968ba7b857..3b35b91a5b 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -24,6 +24,10 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "sysemu/hw_accel.h"
+#include "target/ppc/cpu.h"
+#include "cpu-models.h"
+#include "kvm_ppc.h"
 
 #include "hw/ppc/spapr.h"
 
@@ -40,18 +44,41 @@ typedef struct sPAPRCapabilityInfo {
 void (*disallow)(sPAPRMachineState *spapr, Error **errp);
 } sPAPRCapabilityInfo;
 
+static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
+{
+if (tcg_enabled()) {
+error_setg(errp,
+   "No Transactional Memory support in TCG, try cap-htm=off");
+} else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
+error_setg(errp,
+"KVM implementation does not support Transactional Memory, try cap-htm=off"
+);
+}
+}
+
 static sPAPRCapabilityInfo capability_table[] = {
+{
+.name = "htm",
+.description = "Allow Hardware Transactional Memory (HTM)",
+.flag = SPAPR_CAP_HTM,
+.allow = cap_htm_allow,
+/* TODO: add cap_htm_disallow */
+},
 };
 
 static sPAPRCapabilities 

[Qemu-devel] [PULL 03/15] sm501: Add panel hardware cursor registers also to read function

2018-01-02 Thread David Gibson
From: BALATON Zoltan 

These were forgotten when adding panel layer support in ffd39257018
"SM501 emulation for R2D-SH4".

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
[dwg: Added reference to earlier commit in message]
Signed-off-by: David Gibson 
---
 hw/display/sm501.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 7f1822421a..b9b611131e 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -956,6 +956,19 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr 
addr,
 ret = s->dc_panel_v_sync;
 break;
 
+case SM501_DC_PANEL_HWC_ADDR:
+ret = s->dc_panel_hwc_addr;
+break;
+case SM501_DC_PANEL_HWC_LOC:
+ret = s->dc_panel_hwc_location;
+break;
+case SM501_DC_PANEL_HWC_COLOR_1_2:
+ret = s->dc_panel_hwc_color_1_2;
+break;
+case SM501_DC_PANEL_HWC_COLOR_3:
+ret = s->dc_panel_hwc_color_3;
+break;
+
 case SM501_DC_VIDEO_CONTROL:
 ret = s->dc_video_control;
 break;
-- 
2.14.3




[Qemu-devel] [PULL 12/15] spapr: Handle Decimal Floating Point (DFP) as an optional capability

2018-01-02 Thread David Gibson
Decimal Floating Point has been available on POWER7 and later (server)
cpus.  However, it can be disabled on the hypervisor, meaning that it's
not available to guests.

We currently handle this by conditionally advertising DFP support in the
device tree depending on whether the guest CPU model supports it - which
can also depend on what's allowed in the host for -cpu host.  That can lead
to confusion on migration, since host properties are silently affecting
guest visible properties.

This patch handles it by treating it as an optional capability for the
pseries machine type.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 hw/ppc/spapr.c |  7 ---
 hw/ppc/spapr_caps.c| 18 ++
 include/hw/ppc/spapr.h |  3 +++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 693dd6f7b3..e22888ba06 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -572,7 +572,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, 
int offset,
 /* Advertise DFP (Decimal Floating Point) if available
  *   0 / no property == no DFP
  *   1   == DFP available */
-if (env->insns_flags2 & PPC2_DFP) {
+if (spapr_has_cap(spapr, SPAPR_CAP_DFP)) {
 _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
 }
 
@@ -3834,7 +3834,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
  */
 mc->numa_mem_align_shift = 28;
 
-smc->default_caps = spapr_caps(SPAPR_CAP_VSX);
+smc->default_caps = spapr_caps(SPAPR_CAP_VSX | SPAPR_CAP_DFP);
 spapr_caps_add_properties(smc, _abort);
 }
 
@@ -3916,7 +3916,8 @@ static void spapr_machine_2_11_class_options(MachineClass 
*mc)
 sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
 
 spapr_machine_2_12_class_options(mc);
-smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX);
+smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX
+   | SPAPR_CAP_DFP);
 SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
 }
 
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 7c855c67ad..9d070a306c 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -70,6 +70,16 @@ static void cap_vsx_allow(sPAPRMachineState *spapr, Error 
**errp)
 }
 }
 
+static void cap_dfp_allow(sPAPRMachineState *spapr, Error **errp)
+{
+PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+CPUPPCState *env = >env;
+
+if (!(env->insns_flags2 & PPC2_DFP)) {
+error_setg(errp, "DFP support not available, try cap-dfp=off");
+}
+}
+
 static sPAPRCapabilityInfo capability_table[] = {
 {
 .name = "htm",
@@ -85,6 +95,13 @@ static sPAPRCapabilityInfo capability_table[] = {
 .allow = cap_vsx_allow,
 /* TODO: add cap_vsx_disallow */
 },
+{
+.name = "dfp",
+.description = "Allow Decimal Floating Point (DFP)",
+.flag = SPAPR_CAP_DFP,
+.allow = cap_dfp_allow,
+/* TODO: add cap_dfp_disallow */
+},
 };
 
 static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
@@ -104,6 +121,7 @@ static sPAPRCapabilities 
default_caps_with_cpu(sPAPRMachineState *spapr,
 if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
   0, spapr->max_compat_pvr)) {
 caps.mask &= ~SPAPR_CAP_VSX;
+caps.mask &= ~SPAPR_CAP_DFP;
 }
 
 return caps;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 148a03d189..26ac17e641 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -62,6 +62,9 @@ typedef enum {
 /* Vector Scalar Extensions */
 #define SPAPR_CAP_VSX   0x0002ULL
 
+/* Decimal Floating Point */
+#define SPAPR_CAP_DFP   0x0004ULL
+
 typedef struct sPAPRCapabilities sPAPRCapabilities;
 struct sPAPRCapabilities {
 uint64_t mask;
-- 
2.14.3




[Qemu-devel] [PULL 10/15] target/ppc: Clean up probing of VMX, VSX and DFP availability on KVM

2018-01-02 Thread David Gibson
When constructing the "host" cpu class we modify whether the VMX and VSX
vector extensions and DFP (Decimal Floating Point) are available
based on whether KVM can support those instructions.  This can depend on
policy in the host kernel as well as on the actual host cpu capabilities.

However, the way we probe for this is not very nice: we explicitly check
the host's device tree.  That works in practice, but it's not really
correct, since the device tree is a property of the host kernel's platform
which we don't really know about.  We get away with it because the only
modern POWER platforms happen to encode VMX, VSX and DFP availability in
the device tree in the same way.

Arguably we should have an explicit KVM capability for this, but we haven't
needed one so far.  Barring specific KVM policies which don't yet exist,
each of these instruction classes will be available in the guest if and
only if they're available in the qemu userspace process.  We can determine
that from the ELF AUX vector we're supplied with.

Once reworked like this, there are no more callers for kvmppc_get_vmx() and
kvmppc_get_dfp() so remove them.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
---
 target/ppc/kvm.c | 27 ++-
 target/ppc/kvm_ppc.h |  2 --
 2 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4664a3ce9d..518dd06e98 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2011,16 +2011,6 @@ uint64_t kvmppc_get_clockfreq(void)
 return kvmppc_read_int_cpu_dt("clock-frequency");
 }
 
-uint32_t kvmppc_get_vmx(void)
-{
-return kvmppc_read_int_cpu_dt("ibm,vmx");
-}
-
-uint32_t kvmppc_get_dfp(void)
-{
-return kvmppc_read_int_cpu_dt("ibm,dfp");
-}
-
 static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
  {
  PowerPCCPU *cpu = ppc_env_get_cpu(env);
@@ -2404,23 +2394,18 @@ static void alter_insns(uint64_t *word, uint64_t flags, 
bool on)
 static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
 {
 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-uint32_t vmx = kvmppc_get_vmx();
-uint32_t dfp = kvmppc_get_dfp();
 uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size");
 uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size");
 
 /* Now fix up the class with information we can query from the host */
 pcc->pvr = mfpvr();
 
-if (vmx != -1) {
-/* Only override when we know what the host supports */
-alter_insns(>insns_flags, PPC_ALTIVEC, vmx > 0);
-alter_insns(>insns_flags2, PPC2_VSX, vmx > 1);
-}
-if (dfp != -1) {
-/* Only override when we know what the host supports */
-alter_insns(>insns_flags2, PPC2_DFP, dfp);
-}
+alter_insns(>insns_flags, PPC_ALTIVEC,
+qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC);
+alter_insns(>insns_flags2, PPC2_VSX,
+qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_VSX);
+alter_insns(>insns_flags2, PPC2_DFP,
+qemu_getauxval(AT_HWCAP) & PPC_FEATURE_HAS_DFP);
 
 if (dcache_size != -1) {
 pcc->l1_dcache_size = dcache_size;
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index d6be38ecaf..ecb55493cc 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -15,8 +15,6 @@
 
 uint32_t kvmppc_get_tbfreq(void);
 uint64_t kvmppc_get_clockfreq(void);
-uint32_t kvmppc_get_vmx(void);
-uint32_t kvmppc_get_dfp(void);
 bool kvmppc_get_host_model(char **buf);
 bool kvmppc_get_host_serial(char **buf);
 int kvmppc_get_hasidle(CPUPPCState *env);
-- 
2.14.3




[Qemu-devel] [PULL 01/15] target-ppc: optimize cmp translation

2018-01-02 Thread David Gibson
From: "pbonz...@redhat.com" 

We know that only one bit (in addition to SO) is going to be set in
the condition register, so do two movconds instead of three setconds,
three shifts and two ORs.

For ppc64-linux-user, the code size reduction is around 5% and the
performance improvement slightly less than 10%.  For softmmu, the
improvement is around 5%.

Signed-off-by: Paolo Bonzini 
Signed-off-by: David Gibson 
---
 target/ppc/translate.c | 29 -
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4075fc8589..8a6bd329d0 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -605,27 +605,22 @@ static opc_handler_t invalid_handler = {
 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
 {
 TCGv t0 = tcg_temp_new();
-TCGv_i32 t1 = tcg_temp_new_i32();
-
-tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
-
-tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
-tcg_gen_trunc_tl_i32(t1, t0);
-tcg_gen_shli_i32(t1, t1, CRF_LT_BIT);
-tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+TCGv t1 = tcg_temp_new();
+TCGv_i32 t = tcg_temp_new_i32();
 
-tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
-tcg_gen_trunc_tl_i32(t1, t0);
-tcg_gen_shli_i32(t1, t1, CRF_GT_BIT);
-tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+tcg_gen_movi_tl(t0, CRF_EQ);
+tcg_gen_movi_tl(t1, CRF_LT);
+tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU), t0, arg0, arg1, t1, 
t0);
+tcg_gen_movi_tl(t1, CRF_GT);
+tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU), t0, arg0, arg1, t1, 
t0);
 
-tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
-tcg_gen_trunc_tl_i32(t1, t0);
-tcg_gen_shli_i32(t1, t1, CRF_EQ_BIT);
-tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+tcg_gen_trunc_tl_i32(t, t0);
+tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
+tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t);
 
 tcg_temp_free(t0);
-tcg_temp_free_i32(t1);
+tcg_temp_free(t1);
+tcg_temp_free_i32(t);
 }
 
 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
-- 
2.14.3




[Qemu-devel] [PULL 00/15] ppc-for-2.12 queue 20180103

2018-01-02 Thread David Gibson

Peter, the pull request this supersedes apparently failed your tests
on an arm32 host, so it's very likely this one does as well.  I've
been unable to reproduce the problem on a handful of arm32 machines I
was able to borrow access to, and I'm beginning to suspect the problem
is something specific to the library/distro versions on your test
machine rather than something inherent to arm32.

I'm afraid I'm going to need help from you to fix this: either
debugging on your part, borrowed access or many more details of the
error.  At this point I simply have nothing whatsoever to go on to
debug the problem.


The following changes since commit 281f327487c9c9b1599f93c589a408bbf4a651b8:

  Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' 
into staging (2017-12-22 00:11:36 +)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.12-20180103

for you to fetch changes up to 28af7a42a98dd8d8c13eb0abac496165a8e04634:

  target/ppc: more use of the PPC_*() macros (2018-01-03 10:40:57 +1100)




ppc patch queue 2018-01-03

This pull request supersedes my one from 2017-12-19.  It has been
rebased and retested and has one extra patch, but is otherwise
unchanged.

Here's a second batch of patches for qemu-2.12.  Highlights are:
  * Optional capabilities for the "pseries" machine.  This removes
some places where we were changing guest visible properties based
on host capabilities, which makes life very bad for migration.
  * SLOF update
  * Significant TCG speedup from Paolo
  * Several new devices for embedded platforms
  * Some minor cleanups


Alexey Kardashevskiy (1):
  pseries: Update SLOF firmware image to qemu-slof-20171214

BALATON Zoltan (4):
  sm501: Add panel hardware cursor registers also to read function
  sm501: Add some more unimplemented registers
  ppc4xx_i2c: Implement basic I2C functions
  hw/ide: Emulate SiI3112 SATA controller

Cédric Le Goater (2):
  ppc/pnv: change powernv_ prefix to pnv_ for overall naming consistency
  target/ppc: more use of the PPC_*() macros

David Gibson (6):
  spapr: Capabilities infrastructure
  spapr: Treat Hardware Transactional Memory (HTM) as an optional capability
  spapr: Validate capabilities on migration
  target/ppc: Clean up probing of VMX, VSX and DFP availability on KVM
  spapr: Handle VMX/VSX presence as an spapr capability flag
  spapr: Handle Decimal Floating Point (DFP) as an optional capability

Greg Kurz (1):
  spapr_pci: use warn_report()

pbonz...@redhat.com (1):
  target-ppc: optimize cmp translation

 MAINTAINERS|   6 +
 default-configs/ppcemb-softmmu.mak |   1 +
 hw/display/sm501.c |  30 +++
 hw/i2c/ppc4xx_i2c.c| 198 +---
 hw/ide/Makefile.objs   |   1 +
 hw/ide/sii3112.c   | 368 +
 hw/ide/trace-events|   5 +
 hw/ppc/Makefile.objs   |   2 +-
 hw/ppc/pnv.c   |  94 +-
 hw/ppc/pnv_bmc.c   |   2 +-
 hw/ppc/pnv_core.c  |   8 +-
 hw/ppc/pnv_lpc.c   |  16 +-
 hw/ppc/pnv_psi.c   |   4 +-
 hw/ppc/pnv_xscom.c |  10 +-
 hw/ppc/spapr.c |  47 +++--
 hw/ppc/spapr_caps.c| 341 ++
 hw/ppc/spapr_pci.c |   6 +-
 hw/ppc/spapr_pci_vfio.c|   2 +-
 include/hw/i2c/ppc4xx_i2c.h|   3 +
 include/hw/ppc/pnv.h   |  10 +-
 include/hw/ppc/pnv_xscom.h |   4 +-
 include/hw/ppc/spapr.h |  46 +
 pc-bios/README |   2 +-
 pc-bios/slof.bin   | Bin 905200 -> 913880 bytes
 roms/SLOF  |   2 +-
 target/ppc/cpu.h   |  56 +++---
 target/ppc/int_helper.c|   2 +-
 target/ppc/kvm.c   |  27 +--
 target/ppc/kvm_ppc.h   |   2 -
 target/ppc/translate.c |  29 ++-
 30 files changed, 1135 insertions(+), 189 deletions(-)
 create mode 100644 hw/ide/sii3112.c
 create mode 100644 hw/ppc/spapr_caps.c



Re: [Qemu-devel] [PATCH v8 4/4] contrib/vhost-user-blk: introduce a vhost-user-blk sample application

2018-01-02 Thread Liu, Changpeng


> -Original Message-
> From: Liu, Changpeng
> Sent: Wednesday, January 3, 2018 10:07 AM
> To: 'Marc-André Lureau' 
> Cc: QEMU ; Harris, James R ;
> Michael S. Tsirkin ; Stefan Hajnoczi ;
> Paolo Bonzini ; Felipe Franciosi 
> Subject: RE: [Qemu-devel] [PATCH v8 4/4] contrib/vhost-user-blk: introduce a
> vhost-user-blk sample application
> 
> 
> 
> > -Original Message-
> > From: Marc-André Lureau [mailto:marcandre.lur...@gmail.com]
> > Sent: Tuesday, January 2, 2018 11:44 PM
> > To: Liu, Changpeng 
> > Cc: QEMU ; Harris, James R
> ;
> > Michael S. Tsirkin ; Stefan Hajnoczi ;
> > Paolo Bonzini ; Felipe Franciosi 
> > Subject: Re: [Qemu-devel] [PATCH v8 4/4] contrib/vhost-user-blk: introduce a
> > vhost-user-blk sample application
> >
> > On Tue, Jan 2, 2018 at 4:55 AM, Changpeng Liu 
> wrote:
> > > This commit introcudes a vhost-user-blk backend device, it uses UNIX'
> >
> > introcudes -> introduces
> Thanks.
> >
> > > domain socket to communicate with QEMU. The vhost-user-blk sample
> > > application should be used with QEMU vhost-user-blk-pci device.
> > >
> > > To use it, complie with:
> > > make vhost-user-blk
> > >
> > > and start like this:
> > > vhost-user-blk -b /dev/sdb -s /path/vhost.socket
> > >
> > > Signed-off-by: Changpeng Liu 
> > > ---
> > >  .gitignore  |   1 +
> > >  Makefile|   3 +
> > >  Makefile.objs   |   1 +
> > >  contrib/vhost-user-blk/Makefile.objs|   1 +
> > >  contrib/vhost-user-blk/vhost-user-blk.c | 543
> > 
> > >  5 files changed, 549 insertions(+)
> > >  create mode 100644 contrib/vhost-user-blk/Makefile.objs
> > >  create mode 100644 contrib/vhost-user-blk/vhost-user-blk.c
> > >
> > > diff --git a/.gitignore b/.gitignore
> > > index 433f64f..704b222 100644
> > > --- a/.gitignore
> > > +++ b/.gitignore
> > > @@ -54,6 +54,7 @@
> > >  /module_block.h
> > >  /scsi/qemu-pr-helper
> > >  /vhost-user-scsi
> > > +/vhost-user-blk
> > >  /fsdev/virtfs-proxy-helper
> > >  *.tmp
> > >  *.[1-9]
> > > diff --git a/Makefile b/Makefile
> > > index d86ecd2..f021fc8 100644
> > > --- a/Makefile
> > > +++ b/Makefile
> > > @@ -331,6 +331,7 @@ dummy := $(call unnest-vars,, \
> > >  ivshmem-server-obj-y \
> > >  libvhost-user-obj-y \
> > >  vhost-user-scsi-obj-y \
> > > +vhost-user-blk-obj-y \
> > >  qga-vss-dll-obj-y \
> > >  block-obj-y \
> > >  block-obj-m \
> > > @@ -562,6 +563,8 @@ ivshmem-server$(EXESUF): $(ivshmem-server-obj-y)
> > $(COMMON_LDADDS)
> > >  endif
> > >  vhost-user-scsi$(EXESUF): $(vhost-user-scsi-obj-y) libvhost-user.a
> > > $(call LINK, $^)
> > > +vhost-user-blk$(EXESUF): $(vhost-user-blk-obj-y) libvhost-user.a
> > > +   $(call LINK, $^)
> > >
> > >  module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-
> > host.mak
> > > $(call quiet-command,$(PYTHON) $< $@ \
> > > diff --git a/Makefile.objs b/Makefile.objs
> > > index 285c6f3..ae9aef7 100644
> > > --- a/Makefile.objs
> > > +++ b/Makefile.objs
> > > @@ -115,6 +115,7 @@ libvhost-user-obj-y = contrib/libvhost-user/
> > >  vhost-user-scsi.o-cflags := $(LIBISCSI_CFLAGS)
> > >  vhost-user-scsi.o-libs := $(LIBISCSI_LIBS)
> > >  vhost-user-scsi-obj-y = contrib/vhost-user-scsi/
> > > +vhost-user-blk-obj-y = contrib/vhost-user-blk/
> > >
> > >
> >
> 
> > ##
> > >  trace-events-subdirs =
> > > diff --git a/contrib/vhost-user-blk/Makefile.objs b/contrib/vhost-user-
> > blk/Makefile.objs
> > > new file mode 100644
> > > index 000..72e2cdc
> > > --- /dev/null
> > > +++ b/contrib/vhost-user-blk/Makefile.objs
> > > @@ -0,0 +1 @@
> > > +vhost-user-blk-obj-y = vhost-user-blk.o
> > > diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-
> > blk/vhost-user-blk.c
> > > new file mode 100644
> > > index 000..4649435
> > > --- /dev/null
> > > +++ b/contrib/vhost-user-blk/vhost-user-blk.c
> > > @@ -0,0 +1,543 @@
> > > +/*
> > > + * vhost-user-blk sample application
> > > + *
> > > + * Copyright (c) 2017 Intel Corporation. All rights reserved.
> > > + *
> > > + * Author:
> > > + *  Changpeng Liu 
> > > + *
> > > + * This work is based on the "vhost-user-scsi" sample and "virtio-blk" 
> > > driver
> > > + * implemention by:
> >
> > implemention -> implementation
> Thanks.
> >
> > > + *  Felipe Franciosi 
> > > + *  Anthony Liguori 
> > > + *
> > > + * This work 

Re: [Qemu-devel] [PATCH v14 8/9] hw/arm/virt: Add RAS platform version for migration

2018-01-02 Thread gengdongjiu
Igor,
   Thanks for the review and comments.

On 2017/12/28 22:58, Igor Mammedov wrote:
> On Thu, 28 Dec 2017 13:54:17 +0800
> Dongjiu Geng  wrote:
> 
>> Support this feature since version 2.10, disable it by
>> default in the old version.
> patch should go before acpi tables are actually added,
> otherwise it might break bisectability.
yes, it should. I will move this patch before APEI tables are added.
Thanks for the pointing out.

> 
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>> Address Shannon's comments to add platform version in [1].
>>
>> [1]: https://lkml.org/lkml/2017/8/25/821
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  hw/arm/virt-acpi-build.c | 14 +-
>>  hw/arm/virt.c|  4 
>>  include/hw/arm/virt.h|  1 +
>>  3 files changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 06c14b3..b6974ef 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -801,10 +801,11 @@ void virt_acpi_build(VirtMachineState *vms, 
>> AcpiBuildTables *tables)
>>  acpi_add_table(table_offsets, tables_blob);
>>  build_spcr(tables_blob, tables->linker, vms);
>>  
>> -acpi_add_table(table_offsets, tables_blob);
>> -build_hardware_error_table(tables->hardware_errors, tables->linker);
>> -build_apei_ghes(tables_blob, tables->hardware_errors, tables->linker);
>> -
>> +if (!vmc->no_ras) {
> 
> it's better to avoid no_foo, use something like
> 
> vmc->has_ras
> 
> instead
Ok, I will rename it.

> 
>> +acpi_add_table(table_offsets, tables_blob);
>> +build_hardware_error_table(tables->hardware_errors, tables->linker);
>> +build_apei_ghes(tables_blob, tables->hardware_errors, 
>> tables->linker);
>> +}
>>  
>>  if (nb_numa_nodes > 0) {
>>  acpi_add_table(table_offsets, tables_blob);
>> @@ -891,6 +892,7 @@ static const VMStateDescription vmstate_virt_acpi_build 
>> = {
>>  
>>  void virt_acpi_setup(VirtMachineState *vms)
>>  {
>> +VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
>>  AcpiBuildTables tables;
>>  AcpiBuildState *build_state;
>>  
>> @@ -922,7 +924,9 @@ void virt_acpi_setup(VirtMachineState *vms)
>>  fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, 
>> tables.tcpalog->data,
>>  acpi_data_len(tables.tcpalog));
>>  
>> -ghes_add_fw_cfg(vms->fw_cfg, tables.hardware_errors);
>> +if (!vmc->no_ras) {
>> +ghes_add_fw_cfg(vms->fw_cfg, tables.hardware_errors);
>> +}
>>  
>>  build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
>>ACPI_BUILD_RSDP_FILE, 0);
>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>> index 68495c2..ab79988 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -1732,8 +1732,12 @@ static void virt_2_9_instance_init(Object *obj)
>>  
>>  static void virt_machine_2_9_options(MachineClass *mc)
>>  {
>> +VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
>> +
>>  virt_machine_2_10_options(mc);
>>  SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_9);
>> +/* memory recovery feature was introduced with 2.10 */
>> +vmc->no_ras = true;
>>  }
>>  DEFINE_VIRT_MACHINE(2, 9)
>>  
>> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
>> index 33b0ff3..8fbd664 100644
>> --- a/include/hw/arm/virt.h
>> +++ b/include/hw/arm/virt.h
>> @@ -84,6 +84,7 @@ typedef struct {
>>  bool disallow_affinity_adjustment;
>>  bool no_its;
>>  bool no_pmu;
>> +bool no_ras;
>>  bool claim_edge_triggered_timers;
>>  } VirtMachineClass;
>>  
> 
> 
> .
> 




Re: [Qemu-devel] [PATCH v14 7/9] ARM: ACPI: Add GPIO notification type for hardware RAS error

2018-01-02 Thread gengdongjiu
On 2017/12/28 22:53, Igor Mammedov wrote:
> On Thu, 28 Dec 2017 13:54:16 +0800
> Dongjiu Geng  wrote:
> 
>> In ARM platform we implements a notification of error events
>> via a GPIO pin. For this GPIO-signaled events, we choose GPIO
>> pin 4 for hardware error device (PNP0C33), So _E04 should be
>> added to ACPI DSDT table. When GPIO-pin 4 signaled a events,
>> the guest ACPI driver will receive this notification and
>> handing the error.
>>
>> In order to better trigger the GPIO IRQ, we defined a notifier
>> hardware_error_notifiers. If Qemu wants to deliver a GPIO-Signal
>> notification, will call it.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>> 1. Address discussion result about guest APEI notification type for 
>> SIGBUS_MCEERR_AO SIGBUS in [1],
>>the discussion conclusion is using GPIO-Signal
>>
>> [1]:
>> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03397.html
>> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03467.html
>> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03601.html
>> https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg03775.html
>>
>> 2. The ASL dump for the GPIO and hardware error device
>>
>> 
>> Device (GPO0)
>> {
>> Name (_AEI, ResourceTemplate ()  // _AEI: ACPI Event Interrupts
>> {
>> .
>> GpioInt (Edge, ActiveHigh, Exclusive, PullUp, 0x,
>> "GPO0", 0x00, ResourceConsumer, ,
>> )
>> {   // Pin list
>> 0x0004
>> }
>> })
>> Method (_E04, 0, NotSerialized)  // _Exx: Edge-Triggered GPE
>> {
>> Notify (ERRD, 0x80) // Status Change
>> }
>> }
>> Device (ERRD)
>> {
>> Name (_HID, EisaId ("PNP0C33") /* Error Device */)  // _HID: Hardware ID
>> Name (_UID, Zero)  // _UID: Unique ID
>> Method (_STA, 0, NotSerialized)  // _STA: Status
>> {
>> Return (0x0F)
>> }
>> }
>>
>> 3. Below is the guest log when Qemu notifies guest using GPIO-signal after 
>> record a CPER
>> [  504.164899] {1}[Hardware Error]: Hardware error from APEI Generic 
>> Hardware Error Source: 7
>> [  504.166970] {1}[Hardware Error]: event severity: recoverable
>> [  504.251650] {1}[Hardware Error]:  Error 0, type: recoverable
>> [  504.252974] {1}[Hardware Error]:   section_type: memory error
>> [  504.254380] {1}[Hardware Error]:   physical_address: 0x03ec
>> [  504.255879] {1}[Hardware Error]:   error_type: 3, multi-bit ECC
>> ---
>>  hw/arm/virt-acpi-build.c | 31 ++-
>>  hw/arm/virt.c| 18 ++
>>  include/sysemu/sysemu.h  |  3 +++
>>  vl.c | 12 
>>  4 files changed, 63 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index b7d45cd..06c14b3 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -49,6 +49,7 @@
>>  
>>  #define ARM_SPI_BASE 32
>>  #define ACPI_POWER_BUTTON_DEVICE "PWRB"
>> +#define ACPI_HARDWARE_ERROR_DEVICE "ERRD"
>>  
>>  static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
>>  {
>> @@ -340,7 +341,13 @@ static void acpi_dsdt_add_gpio(Aml *scope, const 
>> MemMapEntry *gpio_memmap,
>>  
>>  Aml *aei = aml_resource_template();
>>  /* Pin 3 for power button */
>> -const uint32_t pin_list[1] = {3};
>> +uint32_t pin_list[1] = {3};
>> +aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
>> + AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1,
>> + "GPO0", NULL, 0));
>> +
>> +/* Pin 4 for hardware error device */
>> +pin_list[0] = 4;
>>  aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
>>   AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1,
>>   "GPO0", NULL, 0));
>> @@ -351,6 +358,13 @@ static void acpi_dsdt_add_gpio(Aml *scope, const 
>> MemMapEntry *gpio_memmap,
>>  aml_append(method, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
>>aml_int(0x80)));
>>  aml_append(dev, method);
>> +
>> +/* _E04 is handle for hardware error */
>> +method = aml_method("_E04", 0, AML_NOTSERIALIZED);
>> +aml_append(method, aml_notify(aml_name(ACPI_HARDWARE_ERROR_DEVICE),
>> +  aml_int(0x80)));
> aml_int(0x80) /* ACPI ... : Notification For Generic Error Sources */
sure. thanks

> 
>> +aml_append(dev, method);
>> +
>>  aml_append(scope, dev);
>>  }
>>  
>> @@ -363,6 +377,20 @@ static void acpi_dsdt_add_power_button(Aml *scope)
>>  aml_append(scope, dev);
>>  }
>>  
>> +static void acpi_dsdt_add_error_device(Aml *scope)
>> +{
>> +Aml *dev = aml_device(ACPI_HARDWARE_ERROR_DEVICE);
>> +Aml *method;
>> +
>> +aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C33")));
>> +aml_append(dev, 

Re: [Qemu-devel] dropped pkts with Qemu on tap interace (RX)

2018-01-02 Thread Wei Xu
On Tue, Jan 02, 2018 at 10:17:25PM +0100, Stefan Priebe - Profihost AG wrote:
> 
> Am 02.01.2018 um 18:04 schrieb Wei Xu:
> > On Tue, Jan 02, 2018 at 04:24:33PM +0100, Stefan Priebe - Profihost AG 
> > wrote:
> >> Hi,
> >> Am 02.01.2018 um 15:20 schrieb Wei Xu:
> >>> On Tue, Jan 02, 2018 at 12:17:29PM +0100, Stefan Priebe - Profihost AG 
> >>> wrote:
>  Hello,
> 
>  currently i'm trying to fix a problem where we have "random" missing
>  packets.
> 
>  We're doing an ssh connect from machine a to machine b every 5 minutes
>  via rsync and ssh.
> 
>  Sometimes it happens that we get this cron message:
>  "Connection to 192.168.0.2 closed by remote host.
>  rsync: connection unexpectedly closed (0 bytes received so far) [sender]
>  rsync error: unexplained error (code 255) at io.c(226) [sender=3.1.2]
>  ssh: connect to host 192.168.0.2 port 22: Connection refused"
> >>>
> >>> Hi Stefan,
> >>> What kind of virtio-net backend are you using? Can you paste your qemu
> >>> command line here?
> >>
> >> Sure netdev part:
> >> -netdev
> >> type=tap,id=net0,ifname=tap317i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on
> >> -device
> >> virtio-net-pci,mac=EA:37:42:5C:F3:33,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300
> >> -netdev
> >> type=tap,id=net1,ifname=tap317i1,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on,queues=4
> >> -device
> >> virtio-net-pci,mac=6A:8E:74:45:1A:0B,nedev=net1,bus=pci.0,addr=0x13,id=net1,vectors=10,mq=on,bootindex=301
> > 
> > According to what you have mentioned, the traffic is not heavy for the 
> > guests,
> > the dropping shouldn't happen for regular case.
> 
> The avg traffic is around 300kb/s.
> 
> > What is your hardware platform?
> 
> Dual Intel Xeon E5-2680 v4
> 
> > and Which versions are you using for both
> > guest/host kernel
> Kernel v4.4.103
> 
> > and qemu?
> 2.9.1
> 
> > Are there other VMs on the same host?
> Yes.

What about the CPU load? 

> 
> 
> >>> 'Connection refused' usually means that the client gets a TCP Reset rather
> >>> than losing packets, so this might not be a relevant issue.
> >>
> >> Mhm so you mean these might be two seperate ones?
> > 
> > Yes.
> > 
> >>
> >>> Also you can do a tcpdump on both guests and see what happened to SSH 
> >>> packets
> >>> (tcpdump -i tapXXX port 22).
> >>
> >> Sadly not as there's too much traffic on that part as rsync is syncing
> >> every 5 minutes through ssh.
> > 
> > You can do a tcpdump for the entire traffic from the guest and host and 
> > compare
> > what kind of packets are dropped if the traffic is not overloaded.
> 
> Are you sure? I don't get why the same amount and same kind of packets
> should be received by both tap which are connected to different bridges
> to different HW and physical interfaces.

Exactly, possibly this would be a host or guest kernel bug cos than qemu issue
you are using vhost kernel as the backend and the two stats are independent,
you might have to check out what is happening inside the traffic.

Wei



Re: [Qemu-devel] [PATCH] util/mmap-alloc: support MAP_SYNC in qemu_ram_mmap()

2018-01-02 Thread Haozhong Zhang
On 01/02/18 18:02 +0200, Michael S. Tsirkin wrote:
> On Wed, Dec 27, 2017 at 02:56:20PM +0800, Haozhong Zhang wrote:
> > When a file supporting DAX is used as vNVDIMM backend, mmap it with
> > MAP_SYNC flag in addition can guarantee the persistence of guest write
> > to the backend file without other QEMU actions (e.g., periodic fsync()
> > by QEMU).
> > 
> > By using MAP_SHARED_VALIDATE flag with MAP_SYNC, we can ensure mmap
> > with MAP_SYNC fails if MAP_SYNC is not supported by the kernel or the
> > backend file. On such failures, QEMU retries mmap without MAP_SYNC and
> > MAP_SHARED_VALIDATE.
> > 
> > Signed-off-by: Haozhong Zhang 
> 
> If users rely on MAP_SYNC then don't you need to fail allocation
> if you can't use it?

MAP_SYNC is supported since Linux kernel 4.15 and only needed for mmap
files on nvdimm. qemu_ram_mmap() has no way to check whether its
parameter 'fd' points to files on nvdimm, except by looking up
sysfs. However, accessing sysfs may be denied by certain SELinux
policies.

The missing of MAP_SYNC should not affect the primary functionality of
vNVDIMM when using files on host nvdimm as backend, except the
guarantee of write persistence in case of qemu/host crash.

We may check the kernel support of MAP_SYNC and the type of vNVDIMM
backend in some management utility (e.g., libvirt?), and deny to
launch QEMU if MAP_SYNC is not supported while files on host NVDIMM
are in use.

> 
> > ---
> >  util/mmap-alloc.c | 36 +++-
> >  1 file changed, 35 insertions(+), 1 deletion(-)
> > 
> > diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
> > index 2fd8cbcc6f..37b302f057 100644
> > --- a/util/mmap-alloc.c
> > +++ b/util/mmap-alloc.c
> > @@ -18,7 +18,18 @@
> >  
> >  #ifdef CONFIG_LINUX
> >  #include 
> > +
> > +/*
> > + * MAP_SHARED_VALIDATE and MAP_SYNC were introduced in 4.15 kernel, so
> > + * they may not be defined when compiling on older kernels.
> > + */
> > +#ifndef MAP_SHARED_VALIDATE
> > +#define MAP_SHARED_VALIDATE   0x3
> >  #endif
> > +#ifndef MAP_SYNC
> > +#define MAP_SYNC  0x8
> > +#endif
> > +#endif /* CONFIG_LINUX */
> >  
> >  size_t qemu_fd_getpagesize(int fd)
> >  {
> 
> This stuff is arch-specific. I think you want to import this into
> standard-headers rather than duplicate things from Linux.

I'll move them to osdep.h.

> 
> 
> > @@ -97,6 +108,7 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, 
> > bool shared)
> >  #endif
> >  size_t offset;
> >  void *ptr1;
> > +int xflags = 0;
> >  
> >  if (ptr == MAP_FAILED) {
> >  return MAP_FAILED;
> > @@ -107,12 +119,34 @@ void *qemu_ram_mmap(int fd, size_t size, size_t 
> > align, bool shared)
> >  assert(align >= getpagesize());
> >  
> >  offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
> > +
> > +#if defined(__linux__)
> > +/*
> > + * If 'fd' refers to a file supporting DAX, mmap it with MAP_SYNC
> > + * will guarantee the guest write persistence without other
> > + * actions in QEMU (e.g., fsync() in QEMU).
> > + *
> > + * MAP_SHARED_VALIDATE ensures mmap with MAP_SYNC fails if
> > + * MAP_SYNC is not supported by the kernel or the file.
> > + *
> > + * On failures of mmap with xflags, QEMU will retry mmap without
> > + * xflags.
> 
> If all you are doing is retrying without, then I don't think you
> even need VALIDATE.

Yes, MAP_SHARED_VALIDATE is not necessary. I'll remove it from xflags.

Thanks,
Haozhong

> 
> > + */
> > +xflags = shared ? (MAP_SHARED_VALIDATE | MAP_SYNC) : 0;
> > +#endif
> > +
> > + retry_mmap_fd:
> >  ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,
> >  MAP_FIXED |
> >  (fd == -1 ? MAP_ANONYMOUS : 0) |
> > -(shared ? MAP_SHARED : MAP_PRIVATE),
> > +(shared ? MAP_SHARED : MAP_PRIVATE) | xflags,
> >  fd, 0);
> >  if (ptr1 == MAP_FAILED) {
> > +if (xflags) {
> > +xflags = 0;
> > +goto retry_mmap_fd;
> > +}
> > +
> >  munmap(ptr, total);
> >  return MAP_FAILED;
> >  }
> > -- 
> > 2.14.1



Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Fam Zheng
On Wed, 01/03 15:54, Michael Clark wrote:
> On Wed, Jan 3, 2018 at 3:41 PM, Fam Zheng  wrote:
> 
> > On Wed, 01/03 15:00, Michael Clark wrote:
> > > So it's essentially one error, the single line case pattern for
> > > table-driven decode which flags for long lines and asks to separate break
> > > onto its own line.
> > >
> > > We have actually reduced the readability of other parts of the code to
> > > conform to this specific rule. In fact I spent a day and a half with
> > > checkpatch, but it didn't seem to make sense for the disassembler.
> > >
> > > The question is should one blindly comply with the rule for
> > > machine-generated tables. Editing the code manually introduces the
> > > potential for human error. I can, if needed, modify the disassembler
> > > generator to output code with the required verbosity.
> >
> > Thanks for taking a look! Practically, consistency with the rest of the
> > code and
> > human judgements (comments, explanation in replies etc.) often override the
> > checkpatch complaints. Checkpatch is not always right.
> 
> 
> Thanks.
> 
> Here is a run with [PATCH v1 04/21] removed to make the checkpatch output
> more readable. checkpatch is (perhaps incorrectly) flagging a request for
> space in a case value that is synthesised from a macro. Case values usually
> don't have space between the value and the colon. It's possibly because the
> case value is constructed from a macro and contains parenthesis. The other
> issue is consistency with existing source in scripts/qemu-binfmt-conf.sh as
> previously noted.

Agreed.

Fam



Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Michael Clark
On Wed, Jan 3, 2018 at 3:41 PM, Fam Zheng  wrote:

> On Wed, 01/03 15:00, Michael Clark wrote:
> > So it's essentially one error, the single line case pattern for
> > table-driven decode which flags for long lines and asks to separate break
> > onto its own line.
> >
> > We have actually reduced the readability of other parts of the code to
> > conform to this specific rule. In fact I spent a day and a half with
> > checkpatch, but it didn't seem to make sense for the disassembler.
> >
> > The question is should one blindly comply with the rule for
> > machine-generated tables. Editing the code manually introduces the
> > potential for human error. I can, if needed, modify the disassembler
> > generator to output code with the required verbosity.
>
> Thanks for taking a look! Practically, consistency with the rest of the
> code and
> human judgements (comments, explanation in replies etc.) often override the
> checkpatch complaints. Checkpatch is not always right.


Thanks.

Here is a run with [PATCH v1 04/21] removed to make the checkpatch output
more readable. checkpatch is (perhaps incorrectly) flagging a request for
space in a case value that is synthesised from a macro. Case values usually
don't have space between the value and the colon. It's possibly because the
case value is constructed from a macro and contains parenthesis. The other
issue is consistency with existing source in scripts/qemu-binfmt-conf.sh as
previously noted.


$ mv outgoing/v1-0004-RISC-V-Disassembler.patch
outgoing/v1-0004-RISC-V-Disassembler.patch.off
$ ./scripts/checkpatch.pl outgoing/*.patch
total: 0 errors, 0 warnings, 16 lines checked

outgoing/v1-0001-RISC-V-Maintainers.patch has no obvious style problems and
is ready for submission.
total: 0 errors, 0 warnings, 8 lines checked

outgoing/v1-0002-RISC-V-ELF-Machine-Definition.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 1112 lines checked

outgoing/v1-0003-RISC-V-CPU-Core-Definition.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 1279 lines checked

outgoing/v1-0005-RISC-V-CPU-Helpers.patch has no obvious style problems and
is ready for submission.
total: 0 errors, 0 warnings, 616 lines checked

outgoing/v1-0006-RISC-V-FPU-Support.patch has no obvious style problems and
is ready for submission.
total: 0 errors, 0 warnings, 59 lines checked

outgoing/v1-0007-RISC-V-GDB-Stub.patch has no obvious style problems and is
ready for submission.
ERROR: spaces required around that ':' (ctx:VxE)
#669: FILE: target/riscv/translate.c:257:
+CASE_OP_32_64(OPC_RISC_ADD):
^

ERROR: spaces required around that ':' (ctx:VxE)
#672: FILE: target/riscv/translate.c:260:
+CASE_OP_32_64(OPC_RISC_SUB):
^

ERROR: spaces required around that ':' (ctx:VxE)
#726: FILE: target/riscv/translate.c:314:
+CASE_OP_32_64(OPC_RISC_MUL):
^

total: 3 errors, 0 warnings, 2409 lines checked

outgoing/v1-0008-RISC-V-TCG-Code-Generation.patch has style problems,
please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
total: 0 errors, 0 warnings, 451 lines checked

outgoing/v1-0009-RISC-V-Physical-Memory-Protection.patch has no obvious
style problems and is ready for submission.
total: 0 errors, 0 warnings, 1704 lines checked

outgoing/v1-0010-RISC-V-Linux-User-Emulation.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 774 lines checked

outgoing/v1-0011-RISC-V-HTIF-Console.patch has no obvious style problems
and is ready for submission.
total: 0 errors, 0 warnings, 140 lines checked

outgoing/v1-0012-RISC-V-HART-Array.patch has no obvious style problems and
is ready for submission.
total: 0 errors, 0 warnings, 368 lines checked

outgoing/v1-0013-SiFive-RISC-V-CLINT-Block.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 649 lines checked

outgoing/v1-0014-SiFive-RISC-V-PLIC-Block.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 539 lines checked

outgoing/v1-0015-RISC-V-Spike-Machines.patch has no obvious style problems
and is ready for submission.
total: 0 errors, 0 warnings, 437 lines checked

outgoing/v1-0016-RISC-V-VirtIO-Machine.patch has no obvious style problems
and is ready for submission.
total: 0 errors, 0 warnings, 258 lines checked

outgoing/v1-0017-SiFive-RISC-V-UART-Device.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 150 lines checked

outgoing/v1-0018-SiFive-RISC-V-PRCI-Block.patch has no obvious style
problems and is ready for submission.
total: 0 errors, 0 warnings, 311 lines checked

outgoing/v1-0019-SiFive-Freedom-E300-RISC-V-Machine.patch has no obvious
style problems and is ready for submission.
total: 0 errors, 0 warnings, 407 lines 

Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Fam Zheng
On Wed, 01/03 15:00, Michael Clark wrote:
> So it's essentially one error, the single line case pattern for
> table-driven decode which flags for long lines and asks to separate break
> onto its own line.
> 
> We have actually reduced the readability of other parts of the code to
> conform to this specific rule. In fact I spent a day and a half with
> checkpatch, but it didn't seem to make sense for the disassembler.
> 
> The question is should one blindly comply with the rule for
> machine-generated tables. Editing the code manually introduces the
> potential for human error. I can, if needed, modify the disassembler
> generator to output code with the required verbosity.

Thanks for taking a look! Practically, consistency with the rest of the code and
human judgements (comments, explanation in replies etc.) often override the
checkpatch complaints. Checkpatch is not always right.

Fam



Re: [Qemu-devel] [PATCH] migration: fix small leaks

2018-01-02 Thread Peter Xu
On Tue, Jan 02, 2018 at 03:19:38PM +, Dr. David Alan Gilbert wrote:
> * Vladimir Sementsov-Ogievskiy (vsement...@virtuozzo.com) wrote:
> > 28.12.2017 05:19, Peter Xu wrote:
> > > On Wed, Dec 27, 2017 at 03:25:23PM +0300, Vladimir Sementsov-Ogievskiy 
> > > wrote:
> > > > Hi all!
> > > > 
> > > > Hmm, looks like leak is not fixed here: I've checked it while running 
> > > > iotest
> > > > 181, that
> > > > migration_instance_finalize is not called.
> > > > 
> > > > If I understand correct, to call it we need unref current_migration 
> > > > object
> > > > somewhere.
> > > > 
> > > > Or, may be I'm missing something..
> > > I think you are right.
> > > 
> > > It does not matter much though since we don't dynamically allocate
> > > migration object (there is only one and it lives forever).  Do you
> > > want to post a patch?  I guess the safest place to unref it is at the
> > > end of main() to make sure no one will be using it any more.
> > > 
> > > (Hmm, the incoming migration state is still static)
> > > 
> > > Thanks,
> > 
> > Ok, I'll send a patch.
> 
> Be very very careful that it doesn't crash in cases like quit in the main 
> thread
> while a migration is still running.

Agree.

> 
> I have no problem with this object living forever and letting it just
> die with exit().

Yes.  But if better, I am thinking whether we should always make sure
migration is completed/failed/cancelled before that point.  If we quit
QEMU with a working migration stream, logically we should stop it
before leaving, as part of QEMU's cleanup path.

-- 
Peter Xu



Re: [Qemu-devel] [PATCH v20 4/7] virtio-balloon: VIRTIO_BALLOON_F_SG

2018-01-02 Thread Tetsuo Handa
Matthew Wilcox wrote:
> The radix tree convention is objectively awful, which is why I'm working
> to change it.  Specifying the GFP flags at radix tree initialisation time
> rather than allocation time leads to all kinds of confusion.  The preload
> API is a pretty awful workaround, and it will go away once the XArray
> is working correctly.  That said, there's no alternative to it without
> making XBitmap depend on XArray, and I don't want to hold you up there.
> So there's an xb_preload for the moment.

I'm ready to propose cvbmp shown below as an alternative to xbitmap (but
specialized for virtio-balloon case). Wei, can you do some benchmarking
between xbitmap and cvbmp?

cvbmp: clustered values bitmap

This patch provides simple API for recording any "unsigned long" value and
for fetching recorded values in ascendant order, in order to allow handling
chunk of unique values efficiently.

The virtio-balloon driver manages memory pages (where the page frame number
is in unique "unsigned long" value range) between the host and the guest.
Currently that communication is using fixed sized array, and allowing that
communication to use scatter-gather API can improve performance a lot.

This patch is implemented for virtio-balloon driver as initial user. Since
the ballooning operation gathers many pages at once, gathered pages tend to
form a cluster (i.e. their values tend to fit bitmap based management).

This API will fail only when memory allocation failed while trying to record
an "unsigned long" value. All operations provided by this API never sleeps.
Also, this API does not provide exclusion control.
Therefore, the callers are responsible for e.g. inserting cond_resched() and
handling out of memory situation, and using rwlock or plain lock as needed.

Since virtio-balloon driver uses OOM notifier callback, in order to avoid
potential deadlock, the ballooning operation must not directly or indirectly
depend on __GFP_DIRECT_RECLAIM && !__GFP_NORETRY memory allocation.
Also, there should be no need to use __GFP_HIGH for memory allocation for
the ballooning operation, for if there is already little free memory such
that normal memory allocation requests will fail, the OOM notifier callback
will be fired by normal memory allocation requests, and the ballooning
operation will have to release memory just allocated. Therefore, this API
uses GFP_NOWAIT | __GFP_NOWARN for memory allocation.

If gathered pages tend to form a cluster, a bitmap for recording next
"unsigned long" value could be found at neighbor of the bitmap used for
recording previous "unsigned long" value. Therefore, this API uses
sequential seek rather than using some tree based algorithm (e.g. radix
tree or B+ tree) when finding a bitmap for recording an "unsigned long"
value. If values changes sequentially, this approach is much faster than
tree based algorithm.

/*
 * Clustered values bitmap.
 *
 * This file provides simple API for recording any "unsigned long" value and
 * for fetching recorded values in ascendant order, in order to allow handling
 * chunk of unique values efficiently.
 *
 * This API will fail only when memory allocation failed while trying to record
 * an "unsigned long" value. All operations provided by this API never sleeps.
 * Also, this API does not provide exclusion control.
 * Therefore, the callers are responsible for e.g. inserting cond_resched() and
 * handling out of memory situation, and using rwlock or plain lock as needed.
 */

/* Header file part. */

#include 
 
/* Tune this size between 8 and PAGE_SIZE * 8, in power of 2. */
#define CVBMP_SIZE 1024

struct cvbmp_node;
struct cvbmp_head {
/*
 * list[0] is used by currently used "struct cvbmp_node" list.
 * list[1] is used by currently unused "struct cvbmp_node" list.
 */
struct list_head list[2];
/*
 * Previously used "struct cvbmp_node" which is used as a hint for
 * next operation.
 */
struct cvbmp_node *last_used;
};

void cvbmp_init(struct cvbmp_head *head);
void cvbmp_destroy(struct cvbmp_head *head);
bool __must_check cvbmp_set_bit(struct cvbmp_head *head,
const unsigned long value);
bool cvbmp_test_bit(struct cvbmp_head *head, const unsigned long value);
void cvbmp_clear_bit(struct cvbmp_head *head, const unsigned long value);
unsigned long cvbmp_get_bit_range(struct cvbmp_head *head,
  unsigned long *start);
bool __must_check cvbmp_set_segment(struct cvbmp_head *head,
const unsigned long segment);
void cvbmp_clear_segment(struct cvbmp_head *head, const unsigned long segment);

/* C file part. */

#ifdef __KERNEL__
#include 
#include 
#include 
#define assert(x) WARN_ON(!x)
#else
#include 
#include 
#include 
#include 
#include 
#define kfree free
#define kzalloc(size, flag) calloc(size, 1)
#define 

[Qemu-devel] [PATCH v2.1 3/3] chardev: introduce qemu_chr_timeout_add() and use

2018-01-02 Thread Peter Xu
It's a replacement of g_timeout_add[_seconds]() for chardevs.  Chardevs
now can have dedicated gcontext, we should always bind chardev tasks
onto those gcontext rather than the default main context.  Since there
are quite a few of g_timeout_add[_seconds]() callers, a new function
qemu_chr_timeout_add() is introduced.

One thing to mention is that, terminal3270 is still always running on
main gcontext.  However let's convert that as well since it's still part
of chardev codes and in case one day we'll miss that when we move it out
of main gcontext too.

Signed-off-by: Peter Xu 
---

v2 -> v2.1: Sorry I forgot to do the move in char.h.  Did it in this
minor version.

 chardev/char-pty.c |  9 ++---
 chardev/char-socket.c  |  4 ++--
 chardev/char.c | 20 
 hw/char/terminal3270.c |  7 ---
 include/chardev/char.h |  3 +++
 5 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index dd17b1b823..cbd8ac5eb7 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -78,13 +78,8 @@ static void pty_chr_rearm_timer(Chardev *chr, int ms)
 s->timer_tag = 0;
 }
 
-if (ms == 1000) {
-name = g_strdup_printf("pty-timer-secs-%s", chr->label);
-s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
-} else {
-name = g_strdup_printf("pty-timer-ms-%s", chr->label);
-s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
-}
+name = g_strdup_printf("pty-timer-ms-%s", chr->label);
+s->timer_tag = qemu_chr_timeout_add(chr, ms, pty_chr_timer, chr);
 g_source_set_name_by_id(s->timer_tag, name);
 g_free(name);
 }
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 630a7f2995..5cca32f963 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -73,8 +73,8 @@ static void qemu_chr_socket_restart_timer(Chardev *chr)
 char *name;
 
 assert(s->connected == 0);
-s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
-   socket_reconnect_timeout, chr);
+s->reconnect_timer = qemu_chr_timeout_add(chr, s->reconnect_time * 1000,
+  socket_reconnect_timeout, chr);
 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
 g_source_set_name_by_id(s->reconnect_timer, name);
 g_free(name);
diff --git a/chardev/char.c b/chardev/char.c
index 8c3765ee99..a1de662fec 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -1084,6 +1084,26 @@ void qmp_chardev_send_break(const char *id, Error **errp)
 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
 }
 
+/*
+ * Add a timeout callback for the chardev (in milliseconds). Please
+ * use this to add timeout hook for chardev instead of g_timeout_add()
+ * and g_timeout_add_seconds(), to make sure the gcontext that the
+ * task bound to is correct.
+ */
+guint qemu_chr_timeout_add(Chardev *chr, guint ms, GSourceFunc func,
+   void *private)
+{
+GSource *source = g_timeout_source_new(ms);
+guint id;
+
+assert(func);
+g_source_set_callback(source, func, private, NULL);
+id = g_source_attach(source, chr->gcontext);
+g_source_unref(source);
+
+return id;
+}
+
 void qemu_chr_cleanup(void)
 {
 object_unparent(get_chardevs_root());
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index a109ce5987..250137b78b 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -94,8 +94,8 @@ static void terminal_read(void *opaque, const uint8_t *buf, 
int size)
 g_source_remove(t->timer_tag);
 t->timer_tag = 0;
 }
-t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
-
+t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600 * 1000,
+send_timing_mark_cb, t);
 memcpy(>inv[t->in_len], buf, size);
 t->in_len += size;
 if (t->in_len < 2) {
@@ -157,7 +157,8 @@ static void chr_event(void *opaque, int event)
  * char-socket.c. Once qemu receives the terminal-type of the
  * client, mark handshake done and trigger everything rolling again.
  */
-t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
+t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600 * 1000,
+send_timing_mark_cb, t);
 break;
 case CHR_EVENT_CLOSED:
 sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 778d610295..7f71f0def0 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -256,6 +256,9 @@ Chardev *qemu_chardev_new(const char *id, const char 
*typename,
 
 extern int term_escape_char;
 
+guint qemu_chr_timeout_add(Chardev *chr, guint ms, GSourceFunc func,
+   void *private);
+
 /* console.c */
 void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, 

Re: [Qemu-devel] [PATCH v14 2/9] ACPI: Add APEI GHES table generation and CPER record support

2018-01-02 Thread gengdongjiu
Hi Igor,
   sorry for my late response due to new year holiday.

On 2017/12/28 22:18, Igor Mammedov wrote:
> On Thu, 28 Dec 2017 13:54:11 +0800
> Dongjiu Geng  wrote:
> 
>> This implements APEI GHES Table generation and record CPER in
>> runtime via fw_cfg blobs.Now we only support two types of GHESv2,
>> which are GPIO-Signal and ARMv8 SEA. Afterwards, we can extend the
>> supported type if needed. For the CPER section type, currently it
> s/type/types/
Ok

> 
>> is memory section because kernel manly wants userspace to handle
> s/manly/mainly/
Ok

> 
>> the memory errors. 
> 
>> In order to simulation, we hard code the error
>> type to Multi-bit ECC.
> Not sure what this is about, care to elaborate?

please see Memory Error Record in [1], in which the "Memory Error Type" field 
is used to describe the
error type, such as  Multi-bit ECC or Parity Error etc. Because KVM or host 
does not pass the memory
error type to Qemu, so Qemu does not know what is the error type for the memory 
section. Hence we let QEMU simulate
the error type to Multi-bit ECC.

[1]:
UEFI Spec 2.6 Errata A:

"N.2.5 Memory Error Section"
-+---+--+---+
Mnemonic |   Byte Offset |  Byte Length |Description
|
-+---+--+---+
 |   |  .   |...
|
-+---+--+---+
Memory Error Type| 72|   1  |Identifies the type of error 
that occurred:|
 |   |  | 0 – Unknown   
   |
 |   |  | 1 – No error  
   |
 |   |  | 2 – Single-bit ECC
   |
 |   |  | 3 – Multi-bit ECC 
   |
 |   |  | 4 – Single-symbol ChipKill 
ECC   |
 |   |  | 5 – Multi-symbol ChipKill ECC 
   |
 |   |  | 6 – Master abort  
|
 |   |  | 7 – Target abort  
|
 |   |  | 8 – Parity Error  
|
 |   |  | 9 – Watchdog timeout  
|
 |   |  | 10 – Invalid address  
|
 |   |  | 11 – Mirror Broken
|
 |   |  | 12 – Memory Sparing   
|
 |   |  | 13 - Scrub corrected error
|
 |   |  | 14 - Scrub uncorrected error  
|
 |   |  | 15 - Physical Memory Map-out 
event|
 |   |  | All other values reserved.
|
-+---+--+---+
 |   |  .   |...
|
-+---+--+---+
> 
> 
>> For GHESv2 error source, the OSPM must acknowledges the error via
>> Read ACK register. So user space must check the ACK value before
>> recording a new CPER to avoid read-write race condition.
>>
>> Suggested-by: Laszlo Ersek 
>> Signed-off-by: Dongjiu Geng 
>> ---
>> The basic solution is suggested by Laszlo in [1]
>> [1]: https://lkml.org/lkml/2017/3/29/342
> 
> 
> patch is too big, it would be better if it were split in several parts.
Ok, I will split it.

> 
>> ---
>>  hw/acpi/aml-build.c |   2 +
>>  hw/acpi/hest_ghes.c | 390 
>> 
>>  hw/arm/virt-acpi-build.c|   8 +
>>  include/hw/acpi/aml-build.h |   1 +
>>  include/hw/acpi/hest_ghes.h |  82 ++
>>  5 files changed, 483 insertions(+)
>>  create mode 100644 hw/acpi/hest_ghes.c
>>  create mode 100644 include/hw/acpi/hest_ghes.h
>>
>> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
>> index 36a6cc4..6849e5f 100644
>> --- a/hw/acpi/aml-build.c
>> +++ b/hw/acpi/aml-build.c
>> @@ -1561,6 +1561,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
>>  tables->table_data = g_array_new(false, true /* clear */, 1);
>>  tables->tcpalog = g_array_new(false, true /* clear */, 1);
>>  tables->vmgenid = g_array_new(false, true /* clear */, 1);
>> +tables->hardware_errors = 

[Qemu-devel] [PATCH v2 0/3] chardev: convert leftover glib APIs to use dedicate gcontext

2018-01-02 Thread Peter Xu
v2:
- add r-bs
- fix patch 3 on some s->ms conversion [Marc-André]

There were existing work that tried to allow chardev to be run in a
dedicated gcontext rather than the default main context/thread.
Basically that work passed in the correct gcontext during
g_source_attach().  However, I found something missing along the way,
that some legacy glib APIs are used by chardev code which take the
main context as default:

   g_timeout_add_seconds
   g_timeout_add
   g_idle_add

To fully allow the chardevs to be run in dedicated gcontext, we need
to convert all these legacy APIs into g_source_attach() calls as well,
with the correct gcontext passed in.

This series tries to clean the rest of things up.

I picked up patch 1 from monitor-oob series into this series (which is
a missing of chardev frontend call fix for g_source_attach()), so that
this series can be a complete fix.

Please review.  Thanks,

Peter Xu (3):
  chardev: use backend chr context when watch for fe
  chardev: let g_idle_add() be with chardev gcontext
  chardev: introduce qemu_chr_timeout_add() and use

 chardev/char-fe.c  |  2 +-
 chardev/char-pty.c | 16 
 chardev/char-socket.c  |  4 ++--
 chardev/char.c | 20 
 hw/char/terminal3270.c |  7 ---
 include/chardev/char.h |  2 ++
 6 files changed, 37 insertions(+), 14 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v2 3/3] chardev: introduce qemu_chr_timeout_add() and use

2018-01-02 Thread Peter Xu
It's a replacement of g_timeout_add[_seconds]() for chardevs.  Chardevs
now can have dedicated gcontext, we should always bind chardev tasks
onto those gcontext rather than the default main context.  Since there
are quite a few of g_timeout_add[_seconds]() callers, a new function
qemu_chr_timeout_add() is introduced.

One thing to mention is that, terminal3270 is still always running on
main gcontext.  However let's convert that as well since it's still part
of chardev codes and in case one day we'll miss that when we move it out
of main gcontext too.

Signed-off-by: Peter Xu 
---
 chardev/char-pty.c |  9 ++---
 chardev/char-socket.c  |  4 ++--
 chardev/char.c | 20 
 hw/char/terminal3270.c |  7 ---
 include/chardev/char.h |  2 ++
 5 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index dd17b1b823..cbd8ac5eb7 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -78,13 +78,8 @@ static void pty_chr_rearm_timer(Chardev *chr, int ms)
 s->timer_tag = 0;
 }
 
-if (ms == 1000) {
-name = g_strdup_printf("pty-timer-secs-%s", chr->label);
-s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
-} else {
-name = g_strdup_printf("pty-timer-ms-%s", chr->label);
-s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
-}
+name = g_strdup_printf("pty-timer-ms-%s", chr->label);
+s->timer_tag = qemu_chr_timeout_add(chr, ms, pty_chr_timer, chr);
 g_source_set_name_by_id(s->timer_tag, name);
 g_free(name);
 }
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 630a7f2995..5cca32f963 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -73,8 +73,8 @@ static void qemu_chr_socket_restart_timer(Chardev *chr)
 char *name;
 
 assert(s->connected == 0);
-s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
-   socket_reconnect_timeout, chr);
+s->reconnect_timer = qemu_chr_timeout_add(chr, s->reconnect_time * 1000,
+  socket_reconnect_timeout, chr);
 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
 g_source_set_name_by_id(s->reconnect_timer, name);
 g_free(name);
diff --git a/chardev/char.c b/chardev/char.c
index 8c3765ee99..a1de662fec 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -1084,6 +1084,26 @@ void qmp_chardev_send_break(const char *id, Error **errp)
 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
 }
 
+/*
+ * Add a timeout callback for the chardev (in milliseconds). Please
+ * use this to add timeout hook for chardev instead of g_timeout_add()
+ * and g_timeout_add_seconds(), to make sure the gcontext that the
+ * task bound to is correct.
+ */
+guint qemu_chr_timeout_add(Chardev *chr, guint ms, GSourceFunc func,
+   void *private)
+{
+GSource *source = g_timeout_source_new(ms);
+guint id;
+
+assert(func);
+g_source_set_callback(source, func, private, NULL);
+id = g_source_attach(source, chr->gcontext);
+g_source_unref(source);
+
+return id;
+}
+
 void qemu_chr_cleanup(void)
 {
 object_unparent(get_chardevs_root());
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index a109ce5987..250137b78b 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -94,8 +94,8 @@ static void terminal_read(void *opaque, const uint8_t *buf, 
int size)
 g_source_remove(t->timer_tag);
 t->timer_tag = 0;
 }
-t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
-
+t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600 * 1000,
+send_timing_mark_cb, t);
 memcpy(>inv[t->in_len], buf, size);
 t->in_len += size;
 if (t->in_len < 2) {
@@ -157,7 +157,8 @@ static void chr_event(void *opaque, int event)
  * char-socket.c. Once qemu receives the terminal-type of the
  * client, mark handshake done and trigger everything rolling again.
  */
-t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
+t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600 * 1000,
+send_timing_mark_cb, t);
 break;
 case CHR_EVENT_CLOSED:
 sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 778d610295..4970e46457 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -258,5 +258,7 @@ extern int term_escape_char;
 
 /* console.c */
 void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);
+guint qemu_chr_timeout_add(Chardev *chr, guint ms, GSourceFunc func,
+   void *private);
 
 #endif
-- 
2.14.3




[Qemu-devel] [PATCH v2 2/3] chardev: let g_idle_add() be with chardev gcontext

2018-01-02 Thread Peter Xu
The idle task will be attached to main gcontext even if the chardev
backend is running in another gcontext.  Fix the only caller by
extending the g_idle_add() logic into the more powerful
g_source_attach().  It's basically g_idle_add_full() implementation, but
with the chardev's gcontext passed in.

Reviewed-by: Marc-André Lureau 
Signed-off-by: Peter Xu 
---
 chardev/char-pty.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 761ae6dec1..dd17b1b823 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -210,9 +210,14 @@ static void pty_chr_state(Chardev *chr, int connected)
 s->timer_tag = 0;
 }
 if (!s->connected) {
+GSource *source = g_idle_source_new();
+
 g_assert(s->open_tag == 0);
 s->connected = 1;
-s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
+g_source_set_callback(source, qemu_chr_be_generic_open_func,
+  chr, NULL);
+s->open_tag = g_source_attach(source, chr->gcontext);
+g_source_unref(source);
 }
 if (!chr->gsource) {
 chr->gsource = io_add_watch_poll(chr, s->ioc,
-- 
2.14.3




Re: [Qemu-devel] [Bug 1158912] Re: QEMU Version 1.4.0 - SLIRP hangs VM

2018-01-02 Thread Kenneth Salerno via Qemu-devel
Hi, you can close this bug.
Ken

Sent from Yahoo Mail on Android 
 
  On Tue, Jan 2, 2018 at 11:19 AM, Thomas Huth<1158...@bugs.launchpad.net> 
wrote:   Triaging old bug tickets... can you still reproduce this issue with the
latest version of QEMU? Or could we close this ticket nowadays?

** Changed in: qemu
      Status: New => Incomplete

-- 
You received this bug notification because you are subscribed to the bug
report.
https://bugs.launchpad.net/bugs/1158912

Title:
  QEMU Version 1.4.0 - SLIRP hangs VM

Status in QEMU:
  Incomplete

Bug description:
  (Note: problem is not present in version 1.3.0)

  Stacktrace: please see attached gdb log file.

  Steps to reproduce:

  1. gdb -x debug-qemu.gdb testing/qemu-1.4.0/ppc64-softmmu/qemu-system-
  ppc64

  Contents of debug-qemu.gdb:

  run -L ./testing/qemu-1.4.0/pc-bios  -name "[DEBUG] Software und
  System-Entwicklung IBM POWER7" -cpu POWER7_v2.3 -M pseries -m 1024
  -rtc base=utc -nodefaults -vga std -monitor vc -serial vc -netdev
  type=user,id=mynet0,hostfwd=tcp:127.0.0.1:9011-10.0.2.11:22 -device
  virtio-net-pci,netdev=mynet0 -drive file=images/suse-
  ppc.img,if=virtio,index=0,media=disk,cache=unsafe -kernel
  images/iso/suseboot/vmlinux -append "root=/dev/mapper/system-root ro
  audit=0 selinux=0 apparmor=0" -initrd images/iso/suseboot/initrd.img
  -drive if=scsi,bus=0,unit=0,media=cdrom

  
  2. build information
      QEMU: ppc64 full emulation, version 1.4.0
      Host OS: Windows XP
      Guest OS: openSUSE 12.2 kernel 3.4.6-2.10-ppc64

      PATH=/usr/i686-pc-mingw32/sys-root/mingw/bin:$PATH
      PKG_CONFIG_LIBDIR=/usr/i686-pc-mingw32/sys-root/mingw/lib/pkgconfig
      THREADS=4
      export PKG_CONFIG_LIBDIR
      
      sed -i 's/--static-libs/--static --libs/' configure
      CC=i686-pc-mingw32-gcc ./configure \
            --target-list=ppc64-softmmu \
            --enable-debug \
            --enable-sdl \
            --static \
            --enable-fdt && \
      sed -i 's/ -Wl,--dynamicbase//g; s/-Wl,--nxcompat //g;'  config-host.mak 
&& \
      make -j$THREADS && {
            echo "renaming binw.exe to bin.exe..."
            for i in `echo $TARGET_LIST | tr ',' ' '`; do
                  BINARCH=`echo $i | sed 's/-softmmu//'`
                  mv $i/qemu-system-${BINARCH}w.exe \
                          $i/qemu-system-$BINARCH.exe
            done
      }

    
  3. From VM: 
      Command to hang VM: zypper dup
      Last message before VM hang:  Retrieving repository 
'openSUSE-12.2-12.2-0' metadata ---[|]

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1158912/+subscriptions

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1158912

Title:
  QEMU Version 1.4.0 - SLIRP hangs VM

Status in QEMU:
  Incomplete

Bug description:
  (Note: problem is not present in version 1.3.0)

  Stacktrace: please see attached gdb log file.

  Steps to reproduce:

  1. gdb -x debug-qemu.gdb testing/qemu-1.4.0/ppc64-softmmu/qemu-system-
  ppc64

  Contents of debug-qemu.gdb:

  run -L ./testing/qemu-1.4.0/pc-bios  -name "[DEBUG] Software und
  System-Entwicklung IBM POWER7" -cpu POWER7_v2.3 -M pseries -m 1024
  -rtc base=utc -nodefaults -vga std -monitor vc -serial vc -netdev
  type=user,id=mynet0,hostfwd=tcp:127.0.0.1:9011-10.0.2.11:22 -device
  virtio-net-pci,netdev=mynet0 -drive file=images/suse-
  ppc.img,if=virtio,index=0,media=disk,cache=unsafe -kernel
  images/iso/suseboot/vmlinux -append "root=/dev/mapper/system-root ro
  audit=0 selinux=0 apparmor=0" -initrd images/iso/suseboot/initrd.img
  -drive if=scsi,bus=0,unit=0,media=cdrom

  
  2. build information
  QEMU: ppc64 full emulation, version 1.4.0
  Host OS: Windows XP
  Guest OS: openSUSE 12.2 kernel 3.4.6-2.10-ppc64

  PATH=/usr/i686-pc-mingw32/sys-root/mingw/bin:$PATH
  PKG_CONFIG_LIBDIR=/usr/i686-pc-mingw32/sys-root/mingw/lib/pkgconfig
  THREADS=4
  export PKG_CONFIG_LIBDIR
  
  sed -i 's/--static-libs/--static --libs/' configure
  CC=i686-pc-mingw32-gcc ./configure \
--target-list=ppc64-softmmu \
--enable-debug \
--enable-sdl \
--static \
--enable-fdt && \
  sed -i 's/ -Wl,--dynamicbase//g; s/-Wl,--nxcompat //g;'  config-host.mak 
&& \
  make -j$THREADS && {
echo "renaming binw.exe to bin.exe..."
for i in `echo $TARGET_LIST | tr ',' ' '`; do
   BINARCH=`echo $i | sed 's/-softmmu//'`
   mv $i/qemu-system-${BINARCH}w.exe \
  $i/qemu-system-$BINARCH.exe
done
  }

 
  3. From VM: 
  Command to hang VM: zypper dup
  Last message before VM hang:  Retrieving repository 
'openSUSE-12.2-12.2-0' metadata ---[|]

To manage notifications about this bug go to:

[Qemu-devel] [PATCH v2 1/3] chardev: use backend chr context when watch for fe

2018-01-02 Thread Peter Xu
In commit 6bbb6c0644 ("chardev: use per-dev context for
io_add_watch_poll", 2017-09-22) all the chardev watches are converted to
use per-chardev gcontext to support chardev to be run outside default
main thread.  However that's still missing one call from the frontend
code.  Touch that up.

Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Peter Xu 
---
 chardev/char-fe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index ee6d596100..c611b3fa3e 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -356,7 +356,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition 
cond,
 }
 
 g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
-tag = g_source_attach(src, NULL);
+tag = g_source_attach(src, s->gcontext);
 g_source_unref(src);
 
 return tag;
-- 
2.14.3




Re: [Qemu-devel] [Qemu-stable] [PATCH] usb-storage: Fix share-rw option parsing

2018-01-02 Thread Fam Zheng
On Mon, 12/18 22:01, Fam Zheng wrote:
> Because usb-storage creates an internal scsi device, we should propagate
> options. We already do so for bootindex etc, but failed to take care of
> share-rw. Fix it in an apparent way: add a new parameter to
> scsi_bus_legacy_add_drive and pass in s->conf.share_rw.
> 
> Cc: qemu-sta...@nongnu.org
> Signed-off-by: Fam Zheng 

Ping?



Re: [Qemu-devel] Problem to start VM with libiscsi + qemu upstream

2018-01-02 Thread Fam Zheng
On Tue, 01/02 21:58, Roy Shterman wrote:
> Hi all,
> 
> I'm trying to get VM started with libiscsi (iSCSI initiator) device. Every
> thing seems good from iSCSI point of view, but I'm stuck in VM boot,
> "Booting from Hard Disk".
> Any idea what can get wrong? how I can assure that the boot itself is from
> the wanted disk.
> Also will be helpful if someone can tell me how can I debug issues like
> that.

Do you still hit the hang if you remove the iscsi lun and only have the system
disk?

> 
> below my xml part of disks:
> 
> 
>   client
>   d4e60885-22be-4270-94ca-1be8209686d2
>   1048576
>   1048576
>   1
>   
> hvm
> 
>   
>   
> 
> 
> 
>   
>   
> 
>   
>   
> 
> 
> 
>   
>   destroy
>   restart
>   restart
>   
> /usr/bin/qemu-system-x86_64
> 
>   
>   
>   
>   
>function='0x0'/>
> 
> 
>   
>   
> 
>   
>   
>function='0x0'/>

My wild guess is this disk's PCI addr is lower than the system disk. Can you
swap "slot='0x06'" with the previous "slot='0x07'" and try again?

(Stuck may be from an unfunctional MBR in the iscsi lun?)

Fam

> 
> 
> 
>function='0x2'/>
> 
> 
>function='0x0'/>
> 
> 
>   
>   
>   
>function='0x0'/>
> 
> 
> Thanks,
> Roy



Re: [Qemu-devel] [PATCH v8 4/4] contrib/vhost-user-blk: introduce a vhost-user-blk sample application

2018-01-02 Thread Liu, Changpeng


> -Original Message-
> From: Marc-André Lureau [mailto:marcandre.lur...@gmail.com]
> Sent: Tuesday, January 2, 2018 11:44 PM
> To: Liu, Changpeng 
> Cc: QEMU ; Harris, James R ;
> Michael S. Tsirkin ; Stefan Hajnoczi ;
> Paolo Bonzini ; Felipe Franciosi 
> Subject: Re: [Qemu-devel] [PATCH v8 4/4] contrib/vhost-user-blk: introduce a
> vhost-user-blk sample application
> 
> On Tue, Jan 2, 2018 at 4:55 AM, Changpeng Liu  wrote:
> > This commit introcudes a vhost-user-blk backend device, it uses UNIX'
> 
> introcudes -> introduces
Thanks.
> 
> > domain socket to communicate with QEMU. The vhost-user-blk sample
> > application should be used with QEMU vhost-user-blk-pci device.
> >
> > To use it, complie with:
> > make vhost-user-blk
> >
> > and start like this:
> > vhost-user-blk -b /dev/sdb -s /path/vhost.socket
> >
> > Signed-off-by: Changpeng Liu 
> > ---
> >  .gitignore  |   1 +
> >  Makefile|   3 +
> >  Makefile.objs   |   1 +
> >  contrib/vhost-user-blk/Makefile.objs|   1 +
> >  contrib/vhost-user-blk/vhost-user-blk.c | 543
> 
> >  5 files changed, 549 insertions(+)
> >  create mode 100644 contrib/vhost-user-blk/Makefile.objs
> >  create mode 100644 contrib/vhost-user-blk/vhost-user-blk.c
> >
> > diff --git a/.gitignore b/.gitignore
> > index 433f64f..704b222 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -54,6 +54,7 @@
> >  /module_block.h
> >  /scsi/qemu-pr-helper
> >  /vhost-user-scsi
> > +/vhost-user-blk
> >  /fsdev/virtfs-proxy-helper
> >  *.tmp
> >  *.[1-9]
> > diff --git a/Makefile b/Makefile
> > index d86ecd2..f021fc8 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -331,6 +331,7 @@ dummy := $(call unnest-vars,, \
> >  ivshmem-server-obj-y \
> >  libvhost-user-obj-y \
> >  vhost-user-scsi-obj-y \
> > +vhost-user-blk-obj-y \
> >  qga-vss-dll-obj-y \
> >  block-obj-y \
> >  block-obj-m \
> > @@ -562,6 +563,8 @@ ivshmem-server$(EXESUF): $(ivshmem-server-obj-y)
> $(COMMON_LDADDS)
> >  endif
> >  vhost-user-scsi$(EXESUF): $(vhost-user-scsi-obj-y) libvhost-user.a
> > $(call LINK, $^)
> > +vhost-user-blk$(EXESUF): $(vhost-user-blk-obj-y) libvhost-user.a
> > +   $(call LINK, $^)
> >
> >  module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-
> host.mak
> > $(call quiet-command,$(PYTHON) $< $@ \
> > diff --git a/Makefile.objs b/Makefile.objs
> > index 285c6f3..ae9aef7 100644
> > --- a/Makefile.objs
> > +++ b/Makefile.objs
> > @@ -115,6 +115,7 @@ libvhost-user-obj-y = contrib/libvhost-user/
> >  vhost-user-scsi.o-cflags := $(LIBISCSI_CFLAGS)
> >  vhost-user-scsi.o-libs := $(LIBISCSI_LIBS)
> >  vhost-user-scsi-obj-y = contrib/vhost-user-scsi/
> > +vhost-user-blk-obj-y = contrib/vhost-user-blk/
> >
> >
> 
> ##
> >  trace-events-subdirs =
> > diff --git a/contrib/vhost-user-blk/Makefile.objs b/contrib/vhost-user-
> blk/Makefile.objs
> > new file mode 100644
> > index 000..72e2cdc
> > --- /dev/null
> > +++ b/contrib/vhost-user-blk/Makefile.objs
> > @@ -0,0 +1 @@
> > +vhost-user-blk-obj-y = vhost-user-blk.o
> > diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-
> blk/vhost-user-blk.c
> > new file mode 100644
> > index 000..4649435
> > --- /dev/null
> > +++ b/contrib/vhost-user-blk/vhost-user-blk.c
> > @@ -0,0 +1,543 @@
> > +/*
> > + * vhost-user-blk sample application
> > + *
> > + * Copyright (c) 2017 Intel Corporation. All rights reserved.
> > + *
> > + * Author:
> > + *  Changpeng Liu 
> > + *
> > + * This work is based on the "vhost-user-scsi" sample and "virtio-blk" 
> > driver
> > + * implemention by:
> 
> implemention -> implementation
Thanks.
> 
> > + *  Felipe Franciosi 
> > + *  Anthony Liguori 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 only.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "standard-headers/linux/virtio_blk.h"
> > +#include "contrib/libvhost-user/libvhost-user-glib.h"
> > +#include "contrib/libvhost-user/libvhost-user.h"
> > +
> > +#include 
> > +
> > +struct virtio_blk_inhdr {
> > +unsigned char status;
> > +};
> > +
> > +/* vhost user block device */
> > +typedef struct VubDev {
> > +VugDev parent;
> > +int blk_fd;
> > +struct virtio_blk_config blkcfg;
> > +char *blk_name;
> > +GMainLoop *loop;
> > +} VubDev;
> > +
> > +typedef struct VubReq {
> > +VuVirtqElement *elem;
> > +int64_t sector_num;
> > +

Re: [Qemu-devel] [PATCH 3/3] chardev: introduce qemu_chr_timeout_add() and use

2018-01-02 Thread Peter Xu
On Tue, Jan 02, 2018 at 05:10:01PM +0100, Marc-André Lureau wrote:
> Hi
> 
> On Thu, Dec 28, 2017 at 8:29 AM, Peter Xu  wrote:
> > It's a replacement of g_timeout_add[_seconds]() for chardevs.  Chardevs
> > now can have dedicated gcontext, we should always bind chardev tasks
> > onto those gcontext rather than the default main context.  Since there
> > are quite a few of g_timeout_add[_seconds]() callers, a new function
> > qemu_chr_timeout_add() is introduced.
> >
> > One thing to mention is that, terminal3270 is still always running on
> > main gcontext.  However let's convert that as well since it's still part
> > of chardev codes and in case one day we'll miss that when we move it out
> > of main gcontext too.
> >
> > Signed-off-by: Peter Xu 
> > ---
> >  chardev/char-pty.c |  9 ++---
> >  chardev/char-socket.c  |  4 ++--
> >  chardev/char.c | 20 
> >  hw/char/terminal3270.c |  7 ---
> >  include/chardev/char.h |  2 ++
> >  5 files changed, 30 insertions(+), 12 deletions(-)
> >
> > diff --git a/chardev/char-pty.c b/chardev/char-pty.c
> > index dd17b1b823..cbd8ac5eb7 100644
> > --- a/chardev/char-pty.c
> > +++ b/chardev/char-pty.c
> > @@ -78,13 +78,8 @@ static void pty_chr_rearm_timer(Chardev *chr, int ms)
> >  s->timer_tag = 0;
> >  }
> >
> > -if (ms == 1000) {
> > -name = g_strdup_printf("pty-timer-secs-%s", chr->label);
> > -s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
> > -} else {
> > -name = g_strdup_printf("pty-timer-ms-%s", chr->label);
> > -s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
> > -}
> > +name = g_strdup_printf("pty-timer-ms-%s", chr->label);
> > +s->timer_tag = qemu_chr_timeout_add(chr, ms, pty_chr_timer, chr);
> >  g_source_set_name_by_id(s->timer_tag, name);
> >  g_free(name);
> >  }
> > diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> > index 630a7f2995..644a620599 100644
> > --- a/chardev/char-socket.c
> > +++ b/chardev/char-socket.c
> > @@ -73,8 +73,8 @@ static void qemu_chr_socket_restart_timer(Chardev *chr)
> >  char *name;
> >
> >  assert(s->connected == 0);
> > -s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
> > -   socket_reconnect_timeout, 
> > chr);
> > +s->reconnect_timer = qemu_chr_timeout_add(chr, s->reconnect_time,
> 
> reconnect_time is in second, you should * 1000.

Yes.  Will fix them all.

> 
> > +  socket_reconnect_timeout, 
> > chr);
> >  name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
> >  g_source_set_name_by_id(s->reconnect_timer, name);
> >  g_free(name);
> > diff --git a/chardev/char.c b/chardev/char.c
> > index 8c3765ee99..a1de662fec 100644
> > --- a/chardev/char.c
> > +++ b/chardev/char.c
> > @@ -1084,6 +1084,26 @@ void qmp_chardev_send_break(const char *id, Error 
> > **errp)
> >  qemu_chr_be_event(chr, CHR_EVENT_BREAK);
> >  }
> >
> > +/*
> > + * Add a timeout callback for the chardev (in milliseconds). Please
> > + * use this to add timeout hook for chardev instead of g_timeout_add()
> > + * and g_timeout_add_seconds(), to make sure the gcontext that the
> > + * task bound to is correct.
> > + */
> > +guint qemu_chr_timeout_add(Chardev *chr, guint ms, GSourceFunc func,
> > +   void *private)
> > +{
> > +GSource *source = g_timeout_source_new(ms);
> > +guint id;
> > +
> > +assert(func);
> > +g_source_set_callback(source, func, private, NULL);
> > +id = g_source_attach(source, chr->gcontext);
> > +g_source_unref(source);
> > +
> > +return id;
> > +}
> > +
> >  void qemu_chr_cleanup(void)
> >  {
> >  object_unparent(get_chardevs_root());
> > diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
> > index a109ce5987..479e4554d6 100644
> > --- a/hw/char/terminal3270.c
> > +++ b/hw/char/terminal3270.c
> > @@ -94,8 +94,8 @@ static void terminal_read(void *opaque, const uint8_t 
> > *buf, int size)
> >  g_source_remove(t->timer_tag);
> >  t->timer_tag = 0;
> >  }
> > -t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
> > -
> > +t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600,
> 
> same here
> 
> > +send_timing_mark_cb, t);
> >  memcpy(>inv[t->in_len], buf, size);
> >  t->in_len += size;
> >  if (t->in_len < 2) {
> > @@ -157,7 +157,8 @@ static void chr_event(void *opaque, int event)
> >   * char-socket.c. Once qemu receives the terminal-type of the
> >   * client, mark handshake done and trigger everything rolling 
> > again.
> >   */
> > -t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
> > +t->timer_tag = qemu_chr_timeout_add(t->chr.chr, 600,
> 
> and again
> 
> > +

Re: [Qemu-devel] [PATCH 1/2] util/pmem: add function to make writes to pmem persistent

2018-01-02 Thread Haozhong Zhang
On 12/31/17 17:55 +0200, Michael S. Tsirkin wrote:
> On Mon, Dec 25, 2017 at 09:06:10AM +0800, Haozhong Zhang wrote:
> > The new function pmem_persistent() flushes the previous cached writes
> > on the specified memory buffer, which ensures the write persistence if
> > the buffer is in persistent memory.
> > 
> > Signed-off-by: Haozhong Zhang 
> > ---
> >  include/qemu/pmem.h |  25 ++
> >  util/Makefile.objs  |   1 +
> >  util/pmem.c | 132 
> > 
> >  3 files changed, 158 insertions(+)
> >  create mode 100644 include/qemu/pmem.h
> >  create mode 100644 util/pmem.c
> > 
> > diff --git a/include/qemu/pmem.h b/include/qemu/pmem.h
> > new file mode 100644
> > index 00..6593ae1d5c
> > --- /dev/null
> > +++ b/include/qemu/pmem.h
> > @@ -0,0 +1,25 @@
> > +/*
> > + * Helper functions to operate on persistent memory.
> > + *
> > + * Copyright (c) 2017 Intel Corporation.
> > + *
> > + * Author: Haozhong Zhang 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or 
> > later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#ifndef QEMU_PMEM_H
> > +#define QEMU_PMEM_H
> > +
> > +/**
> > + * Flush previous cached writes to the specified memory buffer. If the
> > + * buffer is in persistent memory, this function will ensure the write
> > + * persistence.
> > + *
> > + * @p: the pointer to the memory buffer
> > + * @len: the length in bytes of the memory buffer
> > + */
> > +void pmem_persistent(void *p, unsigned long len);
> > +
> > +#endif /* QEMU_PMEM_H */
> > diff --git a/util/Makefile.objs b/util/Makefile.objs
> > index 2973b0a323..2614a84a9e 100644
> > --- a/util/Makefile.objs
> > +++ b/util/Makefile.objs
> > @@ -41,6 +41,7 @@ util-obj-y += timed-average.o
> >  util-obj-y += base64.o
> >  util-obj-y += log.o
> >  util-obj-y += pagesize.o
> > +util-obj-y += pmem.o
> >  util-obj-y += qdist.o
> >  util-obj-y += qht.o
> >  util-obj-y += range.o
> > diff --git a/util/pmem.c b/util/pmem.c
> > new file mode 100644
> > index 00..44be1dde58
> > --- /dev/null
> > +++ b/util/pmem.c
> > @@ -0,0 +1,132 @@
> > +/*
> > + * Helper functions to operate on persistent memory.
> > + *
> > + * Copyright (c) 2017 Intel Corporation.
> > + *
> > + * Author: Haozhong Zhang 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or 
> > later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu-common.h"
> > +#include "qemu/pmem.h"
> > +
> > +static size_t cache_line_size;
> > +
> > +typedef void (*cache_flush_func_t)(void *p);
> > +typedef void (*store_fence_func_t)(void);
> > +
> > +static cache_flush_func_t cache_flush_func;
> > +static store_fence_func_t store_fence_func;
> > +
> > +#if defined(__x86_64__) || defined(__i386__)
> > +
> > +#define CPUID_1_0_EBX_CLSIZE_MASK   0xff00
> > +#define CPUID_1_0_EBX_CLSIZE_SHIFT  8
> > +#define CPUID_1_0_EDX_CLFLUSH   (1U << 19)
> > +#define CPUID_7_0_EBX_CLFLUSHOPT(1U << 23)
> > +#define CPUID_7_0_EBX_CLWB  (1U << 24)
> > +
> > +static inline void cpuid(uint32_t function, uint32_t count,
> > + uint32_t *eax, uint32_t *ebx,
> > + uint32_t *ecx, uint32_t *edx)
> > +{
> > +uint32_t vec[4];
> > +
> > +#ifdef __x86_64__
> > +asm volatile("cpuid"
> > + : "=a"(vec[0]), "=b"(vec[1]),
> > +   "=c"(vec[2]), "=d"(vec[3])
> > + : "0"(function), "c"(count) : "cc");
> > +#else
> > +asm volatile("pusha\n\t"
> > + "cpuid\n\t"
> > + "mov %%eax, 0(%2)\n\t"
> > + "mov %%ebx, 4(%2)\n\t"
> > + "mov %%ecx, 8(%2)\n\t"
> > + "mov %%edx, 12(%2)\n\t"
> > + "popa"
> > + : : "a"(function), "c"(count), "S"(vec)
> > + : "memory", "cc");
> > +#endif
> > +
> > +if (eax) {
> > +*eax = vec[0];
> > +}
> > +if (ebx) {
> > +*ebx = vec[1];
> > +}
> > +if (ecx) {
> > +*ecx = vec[2];
> > +}
> > +if (edx) {
> > +*edx = vec[3];
> > +}
> > +}
> > +
> > +static void clflush(void *p)
> > +{
> > +asm volatile("clflush %0" : "+m" (*(volatile char *)p));
> > +}
> > +
> > +static void clflushopt(void *p)
> > +{
> > +asm volatile(".byte 0x66; clflush %0" : "+m" (*(volatile char *)p));
> > +}
> > +
> > +static void clwb(void *p)
> > +{
> > +asm volatile(".byte 0x66; xsaveopt %0" : "+m" (*(volatile char *)p));
> > +}
> > +
> > +static void sfence(void)
> > +{
> > +asm volatile("sfence" : : : "memory");
> > +}
> > +
> > +static void __attribute__((constructor)) init_funcs(void)
> > +{
> > +uint32_t ebx, edx;
> > +
> > +cpuid(0x1, 0x0, NULL, , NULL, );
> > +
> > +cache_line_size = ((ebx & 

Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Michael Clark
So it's essentially one error, the single line case pattern for
table-driven decode which flags for long lines and asks to separate break
onto its own line.

We have actually reduced the readability of other parts of the code to
conform to this specific rule. In fact I spent a day and a half with
checkpatch, but it didn't seem to make sense for the disassembler.

The question is should one blindly comply with the rule for
machine-generated tables. Editing the code manually introduces the
potential for human error. I can, if needed, modify the disassembler
generator to output code with the required verbosity.

On Wed, Jan 3, 2018 at 2:46 PM, Michael Clark  wrote:

> Hi famz,
>
> If you read the patch logs, you'll see we mention that two of the patches
> don't pass checkpatch. The checkpatch warnings are in the patch comments.
>
> [0004/0021] RISC-V Disassembler violates some select standards for
> brevity. It is repetitive machine generated code. LOC will blow up.
> [0021/0021] RISC-V Build-Infrastructure scripts/qemu-binfmt-conf.sh
> violates the coding standard to be consistent with the rest of the file
>
> I checked other files in the disas/ directory and note that they also
> violate the 90 column rule. We've used a single line case format as in this
> case it is the sane thing to do. i.e. the checkpatch script is not able to
> exercise human jugdement.
>
> Please read the patch comments for 0004 and 0021 where I describe the
> rationale for the specific violations.
>
> I'm happy to change 0004 but we might explode what was originally ~2000
> lines into ~4000 lines or possible more.
>
> Making hex binary span lines in 0021 is risky, and scripts/qemu-binfmt
> -conf.sh already violates the coding standard.
>
> The other 19 patches (~12,000 LOC) have 0 warnings from checkpatch.
>
> Regards,
> Michael.
>
> On Wed, Jan 3, 2018 at 2:28 PM,  wrote:
>
>> Hi,
>>
>> This series seems to have some coding style problems. See output below for
>> more information:
>>
>> Type: series
>> Message-id: 1514940265-18093-1-git-send-email-...@sifive.com
>> Subject: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1
>>
>> === TEST SCRIPT BEGIN ===
>> #!/bin/bash
>>
>> BASE=base
>> n=1
>> total=$(git log --oneline $BASE.. | wc -l)
>> failed=0
>>
>> git config --local diff.renamelimit 0
>> git config --local diff.renames True
>>
>> commits="$(git log --format=%H --reverse $BASE..)"
>> for c in $commits; do
>> echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
>> if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback
>> -; then
>> failed=1
>> echo
>> fi
>> n=$((n+1))
>> done
>>
>> exit $failed
>> === TEST SCRIPT END ===
>>
>> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
>> Switched to a new branch 'test'
>> 4f446c5863 RISC-V Build Infrastructure
>> dc2bad7c46 SiFive Freedom U500 RISC-V Machine
>> e8c7a0bbdd SiFive Freedom E300 RISC-V Machine
>> a9b44928ef SiFive RISC-V PRCI Block
>> 4bd2745c81 SiFive RISC-V UART Device
>> b9c4953978 RISC-V VirtIO Machine
>> 6620d95309 RISC-V Spike Machines
>> 119e3a2f08 SiFive RISC-V PLIC Block
>> 93a3a277a0 SiFive RISC-V CLINT Block
>> b5519a281a RISC-V HART Array
>> 6c8f07e0a3 RISC-V HTIF Console
>> e65c25876b RISC-V Linux User Emulation
>> 0f54fcb416 RISC-V Physical Memory Protection
>> c281030b68 RISC-V TCG Code Generation
>> 53921ca558 RISC-V GDB Stub
>> 179acf20f4 RISC-V FPU Support
>> ba8be079a6 RISC-V CPU Helpers
>> 34f8b2462e RISC-V Disassembler
>> d8f0414bcc RISC-V CPU Core Definition
>> 0318b443cf RISC-V ELF Machine Definition
>> 05c32015d3 RISC-V Maintainers
>>
>> === OUTPUT BEGIN ===
>> Checking PATCH 1/21: RISC-V Maintainers...
>> Checking PATCH 2/21: RISC-V ELF Machine Definition...
>> Checking PATCH 3/21: RISC-V CPU Core Definition...
>> Checking PATCH 4/21: RISC-V Disassembler...
>> WARNING: line over 80 characters
>> #655: FILE: disas/riscv.c:605:
>> +static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra,
>> rvc_imm_eq_zero, rvc_end };
>>
>> ERROR: line over 90 characters
>> #656: FILE: disas/riscv.c:606:
>> +static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0,
>> rvc_imm_eq_zero, rvc_end };
>>
>> WARNING: line over 80 characters
>> #686: FILE: disas/riscv.c:636:
>> +static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra,
>> rvc_end };
>>
>> WARNING: line over 80 characters
>> #687: FILE: disas/riscv.c:637:
>> +static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero,
>> rvc_end };
>>
>> WARNING: line over 80 characters
>> #688: FILE: disas/riscv.c:638:
>> +static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0,
>> rvc_csr_eq_0xc00, rvc_end };
>>
>> WARNING: line over 80 characters
>> #689: FILE: disas/riscv.c:639:
>> +static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0,
>> rvc_csr_eq_0xc01, rvc_end };
>>
>> ERROR: line over 90 characters
>> #690: FILE: disas/riscv.c:640:
>> +static const 

Re: [Qemu-devel] [PATCH RESEND v4] vhost: set used memslots for vhost-user and vhost-kernel respectively

2018-01-02 Thread Zhoujian (jay)
Hi Igor,

> -Original Message-
> From: Igor Mammedov [mailto:imamm...@redhat.com]
> Sent: Tuesday, January 02, 2018 11:46 PM
> To: Zhoujian (jay) 
> Cc: qemu-devel@nongnu.org; Huangweidong (C) ;
> m...@redhat.com; wangxin (U) ; Gonglei (Arei)
> ; Liuzhe (Ahriy, Euler) 
> Subject: Re: [Qemu-devel] [PATCH RESEND v4] vhost: set used memslots for
> vhost-user and vhost-kernel respectively
> 
> On Sat, 30 Dec 2017 14:36:51 +0800
> Jay Zhou  wrote:
> 
> > Used_memslots is equal to dev->mem->nregions now, it is true for vhost
> > kernel, but not for vhost user, which uses the memory regions that
> > have file descriptor. In fact, not all of the memory regions have file
> > descriptor.
> 
> > It is usefully in some scenarios, e.g. used_memslots is 8, and only
> > 5 memory slots can be used by vhost user, it is failed to hotplug a
> > new DIMM memory because vhost_has_free_slot just returned false,
> > however we can hotplug it safely in fact.
> It's too long sentence. Please, split and rephrase it so it would be clear
> what is happening.

Will do.

> 
> > Meanwhile, instead of asserting in vhost_user_set_mem_table(), error
> > number is used to gracefully prevent device to start. This fixed the
> > VM crash issue.
> Fix should be in separate patch as I mentioned in previous review.
> It would useful for stable tree, so you should CC it as well.
> 

OK.

> 
> > Suggested-by: Igor Mammedov 
> > Signed-off-by: Jay Zhou 
> > Signed-off-by: Liuzhe 
> > ---
> >  hw/virtio/vhost-backend.c | 15 +++-
> >  hw/virtio/vhost-user.c| 74 +++-
> ---
> >  hw/virtio/vhost.c | 18 +-
> >  include/hw/virtio/vhost-backend.h |  6 ++--
> >  4 files changed, 78 insertions(+), 35 deletions(-)
> >
> > diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> > index 7f09efa..59def69 100644
> > --- a/hw/virtio/vhost-backend.c
> > +++ b/hw/virtio/vhost-backend.c
> > @@ -15,6 +15,8 @@
> >  #include "hw/virtio/vhost-backend.h"
> >  #include "qemu/error-report.h"
> >
> > +static unsigned int vhost_kernel_used_memslots;
> > +
> >  static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int
> request,
> >   void *arg)  { @@ -62,6 +64,11 @@ static
> > int vhost_kernel_memslots_limit(struct vhost_dev *dev)
> >  return limit;
> >  }
> >
> > +static bool vhost_kernel_has_free_memslots(struct vhost_dev *dev) {
> > +return vhost_kernel_used_memslots <
> > +vhost_kernel_memslots_limit(dev); }
> > +
> >  static int vhost_kernel_net_set_backend(struct vhost_dev *dev,
> >  struct vhost_vring_file
> > *file)  { @@ -233,11 +240,16 @@ static void
> > vhost_kernel_set_iotlb_callback(struct vhost_dev *dev,
> >  qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL,
> > NULL);  }
> >
> > +static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) {
> > +vhost_kernel_used_memslots = dev->mem->nregions; }
> > +
> >  static const VhostOps kernel_ops = {
> >  .backend_type = VHOST_BACKEND_TYPE_KERNEL,
> >  .vhost_backend_init = vhost_kernel_init,
> >  .vhost_backend_cleanup = vhost_kernel_cleanup,
> > -.vhost_backend_memslots_limit = vhost_kernel_memslots_limit,
> > +.vhost_backend_has_free_memslots =
> > + vhost_kernel_has_free_memslots,
> >  .vhost_net_set_backend = vhost_kernel_net_set_backend,
> >  .vhost_scsi_set_endpoint = vhost_kernel_scsi_set_endpoint,
> >  .vhost_scsi_clear_endpoint =
> > vhost_kernel_scsi_clear_endpoint, @@ -264,6 +276,7 @@ static const
> > VhostOps kernel_ops = {  #endif /* CONFIG_VHOST_VSOCK */
> >  .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
> >  .vhost_send_device_iotlb_msg =
> > vhost_kernel_send_device_iotlb_msg,
> > +.vhost_set_used_memslots = vhost_kernel_set_used_memslots,
> >  };
> >
> >  int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType
> > backend_type) diff --git a/hw/virtio/vhost-user.c
> > b/hw/virtio/vhost-user.c index 093675e..11c7d52 100644
> > --- a/hw/virtio/vhost-user.c
> > +++ b/hw/virtio/vhost-user.c
> > @@ -122,6 +122,8 @@ static VhostUserMsg m __attribute__ ((unused));
> >  /* The version of the protocol we support */
> >  #define VHOST_USER_VERSION(0x1)
> >
> > +static bool vhost_user_free_memslots = true;
> > +
> >  struct vhost_user {
> >  CharBackend *chr;
> >  int slave_fd;
> > @@ -289,12 +291,43 @@ static int vhost_user_set_log_base(struct
> vhost_dev *dev, uint64_t base,
> >  return 0;
> >  }
> >
> > +static int vhost_user_prepare_msg(struct vhost_dev *dev,
> VhostUserMemory *mem,
> > +  int *fds) {
> > +int i, fd;
> > +
> 

Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Michael Clark
Hi famz,

If you read the patch logs, you'll see we mention that two of the patches
don't pass checkpatch. The checkpatch warnings are in the patch comments.

[0004/0021] RISC-V Disassembler violates some select standards for brevity.
It is repetitive machine generated code. LOC will blow up.
[0021/0021] RISC-V Build-Infrastructure scripts/qemu-binfmt-conf.sh
violates the coding standard to be consistent with the rest of the file

I checked other files in the disas/ directory and note that they also
violate the 90 column rule. We've used a single line case format as in this
case it is the sane thing to do. i.e. the checkpatch script is not able to
exercise human jugdement.

Please read the patch comments for 0004 and 0021 where I describe the
rationale for the specific violations.

I'm happy to change 0004 but we might explode what was originally ~2000
lines into ~4000 lines or possible more.

Making hex binary span lines in 0021 is risky, and scripts/qemu-binfmt-conf.sh
already violates the coding standard.

The other 19 patches (~12,000 LOC) have 0 warnings from checkpatch.

Regards,
Michael.

On Wed, Jan 3, 2018 at 2:28 PM,  wrote:

> Hi,
>
> This series seems to have some coding style problems. See output below for
> more information:
>
> Type: series
> Message-id: 1514940265-18093-1-git-send-email-...@sifive.com
> Subject: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1
>
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
>
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
>
> git config --local diff.renamelimit 0
> git config --local diff.renames True
>
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
> echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
> if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback
> -; then
> failed=1
> echo
> fi
> n=$((n+1))
> done
>
> exit $failed
> === TEST SCRIPT END ===
>
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> Switched to a new branch 'test'
> 4f446c5863 RISC-V Build Infrastructure
> dc2bad7c46 SiFive Freedom U500 RISC-V Machine
> e8c7a0bbdd SiFive Freedom E300 RISC-V Machine
> a9b44928ef SiFive RISC-V PRCI Block
> 4bd2745c81 SiFive RISC-V UART Device
> b9c4953978 RISC-V VirtIO Machine
> 6620d95309 RISC-V Spike Machines
> 119e3a2f08 SiFive RISC-V PLIC Block
> 93a3a277a0 SiFive RISC-V CLINT Block
> b5519a281a RISC-V HART Array
> 6c8f07e0a3 RISC-V HTIF Console
> e65c25876b RISC-V Linux User Emulation
> 0f54fcb416 RISC-V Physical Memory Protection
> c281030b68 RISC-V TCG Code Generation
> 53921ca558 RISC-V GDB Stub
> 179acf20f4 RISC-V FPU Support
> ba8be079a6 RISC-V CPU Helpers
> 34f8b2462e RISC-V Disassembler
> d8f0414bcc RISC-V CPU Core Definition
> 0318b443cf RISC-V ELF Machine Definition
> 05c32015d3 RISC-V Maintainers
>
> === OUTPUT BEGIN ===
> Checking PATCH 1/21: RISC-V Maintainers...
> Checking PATCH 2/21: RISC-V ELF Machine Definition...
> Checking PATCH 3/21: RISC-V CPU Core Definition...
> Checking PATCH 4/21: RISC-V Disassembler...
> WARNING: line over 80 characters
> #655: FILE: disas/riscv.c:605:
> +static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra,
> rvc_imm_eq_zero, rvc_end };
>
> ERROR: line over 90 characters
> #656: FILE: disas/riscv.c:606:
> +static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0,
> rvc_imm_eq_zero, rvc_end };
>
> WARNING: line over 80 characters
> #686: FILE: disas/riscv.c:636:
> +static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra,
> rvc_end };
>
> WARNING: line over 80 characters
> #687: FILE: disas/riscv.c:637:
> +static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero,
> rvc_end };
>
> WARNING: line over 80 characters
> #688: FILE: disas/riscv.c:638:
> +static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc00, rvc_end };
>
> WARNING: line over 80 characters
> #689: FILE: disas/riscv.c:639:
> +static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc01, rvc_end };
>
> ERROR: line over 90 characters
> #690: FILE: disas/riscv.c:640:
> +static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc02, rvc_end };
>
> ERROR: line over 90 characters
> #691: FILE: disas/riscv.c:641:
> +static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc80, rvc_end };
>
> WARNING: line over 80 characters
> #692: FILE: disas/riscv.c:642:
> +static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc81, rvc_end };
>
> ERROR: line over 90 characters
> #693: FILE: disas/riscv.c:643:
> +static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0xc80, rvc_end };
>
> WARNING: line over 80 characters
> #694: FILE: disas/riscv.c:644:
> +static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0,
> rvc_csr_eq_0x003, rvc_end };
>
> WARNING: line over 80 characters
> #695: FILE: disas/riscv.c:645:
> +static const rvc_constraint 

Re: [Qemu-devel] [PATCH v8 3/4] contrib/libvhost-user: enable virtio config space messages

2018-01-02 Thread Liu, Changpeng


> -Original Message-
> From: Marc-André Lureau [mailto:marcandre.lur...@gmail.com]
> Sent: Tuesday, January 2, 2018 11:30 PM
> To: Liu, Changpeng 
> Cc: QEMU ; Harris, James R ;
> Michael S. Tsirkin ; Stefan Hajnoczi ;
> Paolo Bonzini ; Felipe Franciosi 
> Subject: Re: [Qemu-devel] [PATCH v8 3/4] contrib/libvhost-user: enable virtio
> config space messages
> 
> Hi
> 
> On Tue, Jan 2, 2018 at 4:55 AM, Changpeng Liu  wrote:
> > Enable VHOST_USER_GET_CONFIG/VHOST_USER_SET_CONFIG messages in
> > libvhost-user library, users can implement their own I/O target
> > based on the library. This enable the virtio config space delivered
> > between QEMU host device and the I/O target.
> >
> > Signed-off-by: Changpeng Liu 
> > ---
> >  contrib/libvhost-user/libvhost-user.c | 54
> +++
> >  contrib/libvhost-user/libvhost-user.h | 34 +-
> >  2 files changed, 87 insertions(+), 1 deletion(-)
> >
> > diff --git a/contrib/libvhost-user/libvhost-user.c 
> > b/contrib/libvhost-user/libvhost-
> user.c
> > index f409bd3..9e12eb1 100644
> > --- a/contrib/libvhost-user/libvhost-user.c
> > +++ b/contrib/libvhost-user/libvhost-user.c
> > @@ -84,6 +84,8 @@ vu_request_to_string(unsigned int req)
> >  REQ(VHOST_USER_SET_SLAVE_REQ_FD),
> >  REQ(VHOST_USER_IOTLB_MSG),
> >  REQ(VHOST_USER_SET_VRING_ENDIAN),
> > +REQ(VHOST_USER_GET_CONFIG),
> > +REQ(VHOST_USER_SET_CONFIG),
> >  REQ(VHOST_USER_MAX),
> >  };
> >  #undef REQ
> > @@ -798,6 +800,53 @@ vu_set_slave_req_fd(VuDev *dev, VhostUserMsg *vmsg)
> >  }
> >
> >  static bool
> > +vu_get_config(VuDev *dev, VhostUserMsg *vmsg)
> > +{
> > +int ret = -1;
> > +
> > +if (dev->iface->get_config) {
> > +ret = dev->iface->get_config(dev, vmsg->payload.config.region,
> > + vmsg->payload.config.size);
> > +}
> > +
> > +if (ret) {
> > +/* resize to zero to indicate an error to master */
> > +vmsg->size = 0;
> > +}
> > +
> > +return true;
> > +}
> > +
> > +static bool
> > +vu_set_config(VuDev *dev, VhostUserMsg *vmsg)
> > +{
> > +int ret = -1;
> > +bool reply_supported = !!(dev->protocol_features &
> > + (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK));
> > +
> 
> None of the other messages in libvhost-user support the REPLY_ACK
> flag. Do you need it? If not, please drop it.
Ok, will drop it.
> 
> If you need it, it's a better idea to make the reply explicit and
> mandatory in the protocol for SET_CONFIG.
> 
> > +if (dev->iface->set_config) {
> > +ret = dev->iface->set_config(dev, vmsg->payload.config.region,
> > + vmsg->payload.config.offset,
> > + vmsg->payload.config.size,
> > + vmsg->payload.config.flags);
> > +}
> > +
> > +vmsg->size = sizeof(vmsg->payload.u64);
> > +if (!ret) {
> > +vmsg->payload.u64 = 0;
> > +} else {
> > +/* indicate an error in case reply supported */
> > +vmsg->payload.u64 = 1;
> > +}
> > +
> > +if (reply_supported) {
> > +return true;
> > +}
> > +
> > +return false;
> > +}
> > +
> > +static bool
> >  vu_process_message(VuDev *dev, VhostUserMsg *vmsg)
> >  {
> >  int do_reply = 0;
> > @@ -862,6 +911,10 @@ vu_process_message(VuDev *dev, VhostUserMsg *vmsg)
> >  return vu_set_vring_enable_exec(dev, vmsg);
> >  case VHOST_USER_SET_SLAVE_REQ_FD:
> >  return vu_set_slave_req_fd(dev, vmsg);
> > +case VHOST_USER_GET_CONFIG:
> > +return vu_get_config(dev, vmsg);
> > +case VHOST_USER_SET_CONFIG:
> > +return vu_set_config(dev, vmsg);
> >  case VHOST_USER_NONE:
> >  break;
> >  default:
> > @@ -970,6 +1023,7 @@ vu_init(VuDev *dev,
> >  dev->iface = iface;
> >  dev->log_call_fd = -1;
> >  dev->slave_fd = -1;
> > +
> 
> unrelated coding style change, please drop
Thanks.
> 
> >  for (i = 0; i < VHOST_MAX_NR_VIRTQUEUE; i++) {
> >  dev->vq[i] = (VuVirtq) {
> >  .call_fd = -1, .kick_fd = -1, .err_fd = -1,
> > diff --git a/contrib/libvhost-user/libvhost-user.h 
> > b/contrib/libvhost-user/libvhost-
> user.h
> > index 2f5864b..b38959e 100644
> > --- a/contrib/libvhost-user/libvhost-user.h
> > +++ b/contrib/libvhost-user/libvhost-user.h
> > @@ -30,6 +30,16 @@
> >
> >  #define VHOST_MEMORY_MAX_NREGIONS 8
> >
> > +typedef enum VhostSetConfigType {
> > +VHOST_SET_CONFIG_TYPE_MASTER = 0,
> > +VHOST_SET_CONFIG_TYPE_MIGRATION = 1,
> > +} VhostSetConfigType;
> > +
> > +/*
> > + * Maximum size of virtio device config space
> > + */
> > +#define VHOST_USER_MAX_CONFIG_SIZE 256
> > +
> >  enum 

Re: [Qemu-devel] [PATCH v8 1/4] vhost-user: add new vhost user messages to support virtio config space

2018-01-02 Thread Liu, Changpeng


> -Original Message-
> From: Marc-André Lureau [mailto:marcandre.lur...@gmail.com]
> Sent: Tuesday, January 2, 2018 11:20 PM
> To: Liu, Changpeng 
> Cc: QEMU ; Harris, James R ;
> Michael S. Tsirkin ; Stefan Hajnoczi ;
> Paolo Bonzini ; Felipe Franciosi 
> Subject: Re: [Qemu-devel] [PATCH v8 1/4] vhost-user: add new vhost user 
> messages
> to support virtio config space
> 
>  Hi
> 
> On Tue, Jan 2, 2018 at 4:55 AM, Changpeng Liu  wrote:
> > Add VHOST_USER_GET_CONFIG/VHOST_USER_SET_CONFIG messages which can
> be
> > used for live migration of vhost user devices, also vhost user devices
> > can benefit from the messages to get/set virtio config space from/to the
> > I/O target. For the purpose to support virtio config space change,
> > VHOST_USER_SLAVE_CONFIG_CHANGE_MSG message is added as the event
> notifier
> > in case virtio config space change in the slave I/O target.
> >
> > Signed-off-by: Changpeng Liu 
> > ---
> >  docs/interop/vhost-user.txt   |  53 +
> >  hw/virtio/vhost-user.c| 118 
> > ++
> >  hw/virtio/vhost.c |  32 +++
> >  include/hw/virtio/vhost-backend.h |  12 
> >  include/hw/virtio/vhost.h |  15 +
> >  5 files changed, 230 insertions(+)
> >
> > diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
> > index 954771d..1788fff 100644
> > --- a/docs/interop/vhost-user.txt
> > +++ b/docs/interop/vhost-user.txt
> > @@ -116,6 +116,19 @@ Depending on the request type, payload can be:
> >  - 3: IOTLB invalidate
> >  - 4: IOTLB access fail
> >
> > + * Virtio device config space
> > +   ---
> > +   | offset | size | flags | payload |
> > +   ---
> > +
> > +   Offset: a 32-bit offset of virtio device's configuration space
> > +   Size: a 32-bit configuration space access size in bytes
> > +   Flags: a 32-bit value:
> > +- 0: Vhost master messages used for writeable fields
> > +- 1: Vhost master messages used for live migration
> > +   Payload: Size bytes array holding the contents of the virtio
> > +   device's configuration space
> > +
> >  In QEMU the vhost-user message is implemented with the following struct:
> >
> >  typedef struct VhostUserMsg {
> > @@ -129,6 +142,7 @@ typedef struct VhostUserMsg {
> >  VhostUserMemory memory;
> >  VhostUserLog log;
> >  struct vhost_iotlb_msg iotlb;
> > +VhostUserConfig config;
> >  };
> >  } QEMU_PACKED VhostUserMsg;
> >
> > @@ -596,6 +610,30 @@ Master message types
> >and expect this message once (per VQ) during device configuration
> >(ie. before the master starts the VQ).
> >
> > + * VHOST_USER_GET_CONFIG
> > +
> > +  Id: 24
> > +  Equivalent ioctl: N/A
> 
> Please document the Master payload. (msg.size != 0)
Ok, will add.
> 
> 
> > +  Slave payload: virtio device config space
> > +
> > +  Submitted by the vhost-user master to fetch the contents of the 
> > virtio
> > +  device configuration space, vhost-user slave's payload size MUST 
> > match
> > +  master's request, vhost-user slave uses zero length of payload to
> > +  indicate an error to vhost-user master. The vhost-user master may
> > +  cache the contents to avoid repeated VHOST_USER_GET_CONFIG calls.
> > +
> > +* VHOST_USER_SET_CONFIG
> > +
> > +  Id: 25
> > +  Equivalent ioctl: N/A
> 
> Same here
Ok.
> 
> > +  Master payload: virtio device config space
> > +
> > +  Submitted by the vhost-user master when the Guest changes the virtio
> > +  device configuration space and also can be used for live migration
> > +  on the destination host. The vhost-user slave must check the flags
> > +  field, and slaves MUST NOT accept SET_CONFIG for read-only
> > +  configuration space fields unless the live migration bit is set.
> > +
> >  Slave message types
> >  ---
> >
> > @@ -614,6 +652,21 @@ Slave message types
> >This request should be send only when VIRTIO_F_IOMMU_PLATFORM
> feature
> >has been successfully negotiated.
> >
> > +* VHOST_USER_SLAVE_CONFIG_CHANGE_MSG
> > +
> > + Id: 2
> > + Equivalent ioctl: N/A
> > + Slave payload: N/A
> > + Master payload: N/A
> > +
> > + Vhost-user slave sends such messages to notify that the virtio 
> > device's
> > + configuration space has changed, for those host devices which can 
> > support
> > + such feature, host driver can send VHOST_USER_GET_CONFIG message to
> slave
> > + to get the latest content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is
> > + negotiated, and slave set the VHOST_USER_NEED_REPLY flag, master must
> > + respond with zero when operation is 

Re: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread no-reply
Hi,

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

Type: series
Message-id: 1514940265-18093-1-git-send-email-...@sifive.com
Subject: [Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
4f446c5863 RISC-V Build Infrastructure
dc2bad7c46 SiFive Freedom U500 RISC-V Machine
e8c7a0bbdd SiFive Freedom E300 RISC-V Machine
a9b44928ef SiFive RISC-V PRCI Block
4bd2745c81 SiFive RISC-V UART Device
b9c4953978 RISC-V VirtIO Machine
6620d95309 RISC-V Spike Machines
119e3a2f08 SiFive RISC-V PLIC Block
93a3a277a0 SiFive RISC-V CLINT Block
b5519a281a RISC-V HART Array
6c8f07e0a3 RISC-V HTIF Console
e65c25876b RISC-V Linux User Emulation
0f54fcb416 RISC-V Physical Memory Protection
c281030b68 RISC-V TCG Code Generation
53921ca558 RISC-V GDB Stub
179acf20f4 RISC-V FPU Support
ba8be079a6 RISC-V CPU Helpers
34f8b2462e RISC-V Disassembler
d8f0414bcc RISC-V CPU Core Definition
0318b443cf RISC-V ELF Machine Definition
05c32015d3 RISC-V Maintainers

=== OUTPUT BEGIN ===
Checking PATCH 1/21: RISC-V Maintainers...
Checking PATCH 2/21: RISC-V ELF Machine Definition...
Checking PATCH 3/21: RISC-V CPU Core Definition...
Checking PATCH 4/21: RISC-V Disassembler...
WARNING: line over 80 characters
#655: FILE: disas/riscv.c:605:
+static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, 
rvc_end };

ERROR: line over 90 characters
#656: FILE: disas/riscv.c:606:
+static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, 
rvc_imm_eq_zero, rvc_end };

WARNING: line over 80 characters
#686: FILE: disas/riscv.c:636:
+static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, 
rvc_end };

WARNING: line over 80 characters
#687: FILE: disas/riscv.c:637:
+static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, 
rvc_end };

WARNING: line over 80 characters
#688: FILE: disas/riscv.c:638:
+static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc00, rvc_end };

WARNING: line over 80 characters
#689: FILE: disas/riscv.c:639:
+static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, 
rvc_end };

ERROR: line over 90 characters
#690: FILE: disas/riscv.c:640:
+static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc02, rvc_end };

ERROR: line over 90 characters
#691: FILE: disas/riscv.c:641:
+static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc80, rvc_end };

WARNING: line over 80 characters
#692: FILE: disas/riscv.c:642:
+static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc81, rvc_end };

ERROR: line over 90 characters
#693: FILE: disas/riscv.c:643:
+static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc80, rvc_end };

WARNING: line over 80 characters
#694: FILE: disas/riscv.c:644:
+static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, 
rvc_end };

WARNING: line over 80 characters
#695: FILE: disas/riscv.c:645:
+static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, 
rvc_end };

WARNING: line over 80 characters
#696: FILE: disas/riscv.c:646:
+static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0x001, rvc_end };

ERROR: line over 90 characters
#1095: FILE: disas/riscv.c:1045:
+{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, 
rv_op_addi, rv_op_addi },

WARNING: line over 80 characters
#1096: FILE: disas/riscv.c:1046:
+{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, 
rv_op_fld, 0 },

WARNING: line over 80 characters
#1097: FILE: disas/riscv.c:1047:
+{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, 
rv_op_lw },

WARNING: line over 80 characters
#1099: FILE: disas/riscv.c:1049:
+{ "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, 
rv_op_fsd, 0 },

WARNING: line over 80 characters
#1100: FILE: disas/riscv.c:1050:
+{ "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, 
rv_op_sw },

WARNING: line over 80 characters
#1102: FILE: disas/riscv.c:1052:
+{ "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi },

ERROR: line over 90 characters
#1103: FILE: disas/riscv.c:1053:
+{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi },

ERROR: line over 90 characters
#1105: FILE: 

Re: [Qemu-devel] [PATCH v3 00/42] SDHCI: housekeeping, add a qtest and fix few issues

2018-01-02 Thread Philippe Mathieu-Daudé
On 01/02/2018 09:15 PM, Alistair Francis wrote:
> We are making progress here. Do you think it would be worth splitting
> out the earlier patches that have been reviewed so far so they can be
> merged? A 42 patch series it pretty daunting and most of the first 20
> are pretty straightforward and have been reviewed.

Andreas or Eduardo could you help reviewing patches 4-7 please? These
are QOM-related changes.

Thanks!

Phil.



Re: [Qemu-devel] [PATCH] hw/ppc: Remove the deprecated spapr-pci-vfio-host-bridge device

2018-01-02 Thread David Gibson
On Mon, Dec 18, 2017 at 06:35:12PM +0100, Thomas Huth wrote:
> It's a deprecated dummy device since QEMU v2.6.0. That should have
> been enough time to allow the users to update their scripts in case
> they still use it, so let's remove this legacy code now.
> 
> Signed-off-by: Thomas Huth 

I'm afraid this has bitrotted due to ongoing changes in the
ppc-for-2.12 tree, can you rebase and resend, please.

> ---
>  hw/ppc/spapr_pci_vfio.c   | 47 
> ---
>  qemu-doc.texi |  5 -
>  scripts/device-crash-test |  1 -
>  3 files changed, 53 deletions(-)
> 
> diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
> index 8448e0b..053efb0 100644
> --- a/hw/ppc/spapr_pci_vfio.c
> +++ b/hw/ppc/spapr_pci_vfio.c
> @@ -29,31 +29,6 @@
>  #include "qemu/error-report.h"
>  #include "sysemu/qtest.h"
>  
> -#define TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE "spapr-pci-vfio-host-bridge"
> -
> -#define SPAPR_PCI_VFIO_HOST_BRIDGE(obj) \
> -OBJECT_CHECK(sPAPRPHBVFIOState, (obj), TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE)
> -
> -typedef struct sPAPRPHBVFIOState sPAPRPHBVFIOState;
> -
> -struct sPAPRPHBVFIOState {
> -sPAPRPHBState phb;
> -
> -int32_t iommugroupid;
> -};
> -
> -static Property spapr_phb_vfio_properties[] = {
> -DEFINE_PROP_INT32("iommu", sPAPRPHBVFIOState, iommugroupid, -1),
> -DEFINE_PROP_END_OF_LIST(),
> -};
> -
> -static void spapr_phb_vfio_instance_init(Object *obj)
> -{
> -if (!qtest_enabled()) {
> -error_report("spapr-pci-vfio-host-bridge is deprecated");
> -}
> -}
> -
>  bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
>  {
>  return vfio_eeh_as_ok(>iommu_as);
> @@ -218,25 +193,3 @@ int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
>  
>  return RTAS_OUT_SUCCESS;
>  }
> -
> -static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
> -{
> -DeviceClass *dc = DEVICE_CLASS(klass);
> -
> -dc->props = spapr_phb_vfio_properties;
> -}
> -
> -static const TypeInfo spapr_phb_vfio_info = {
> -.name  = TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE,
> -.parent= TYPE_SPAPR_PCI_HOST_BRIDGE,
> -.instance_size = sizeof(sPAPRPHBVFIOState),
> -.instance_init = spapr_phb_vfio_instance_init,
> -.class_init= spapr_phb_vfio_class_init,
> -};
> -
> -static void spapr_pci_vfio_register_types(void)
> -{
> -type_register_static(_phb_vfio_info);
> -}
> -
> -type_init(spapr_pci_vfio_register_types)
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index f7317df..14d818d 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -2533,11 +2533,6 @@ The ``host_net_remove'' command is replaced by the 
> ``netdev_del'' command.
>  The ``ivshmem'' device type is replaced by either the ``ivshmem-plain''
>  or ``ivshmem-doorbell`` device types.
>  
> -@subsection spapr-pci-vfio-host-bridge (since 2.6.0)
> -
> -The ``spapr-pci-vfio-host-bridge'' device type is replaced by
> -the ``spapr-pci-host-bridge'' device type.
> -
>  @section System emulator machines
>  
>  @subsection Xilinx EP108 (since 2.11.0)
> diff --git a/scripts/device-crash-test b/scripts/device-crash-test
> index 1aca55f..7417177 100755
> --- a/scripts/device-crash-test
> +++ b/scripts/device-crash-test
> @@ -119,7 +119,6 @@ ERROR_WHITELIST = [
>  {'device':'scsi-generic', 'expected':True},# drive property 
> not set
>  {'device':'scsi-hd', 'expected':True}, # drive property 
> not set
>  {'device':'spapr-pci-host-bridge', 'expected':True},   # BUID not 
> specified for PHB
> -{'device':'spapr-pci-vfio-host-bridge', 'expected':True}, # BUID not 
> specified for PHB
>  {'device':'spapr-rng', 'expected':True},   # spapr-rng needs 
> an RNG backend!
>  {'device':'spapr-vty', 'expected':True},   # chardev 
> property not set
>  {'device':'tpm-tis', 'expected':True}, # tpm_tis: 
> backend driver with id (null) could not be found

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


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v1 13/21] SiFive RISC-V CLINT Block

2018-01-02 Thread Michael Clark
The CLINT (Core Local Interruptor) device provides real-time clock, timer
and interprocessor interrupts based on SiFive's CLINT specification.

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_clint.c | 312 
 include/hw/riscv/sifive_clint.h |  56 
 2 files changed, 368 insertions(+)
 create mode 100644 hw/riscv/sifive_clint.c
 create mode 100644 include/hw/riscv/sifive_clint.h

diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
new file mode 100644
index 000..50d2a09
--- /dev/null
+++ b/hw/riscv/sifive_clint.c
@@ -0,0 +1,312 @@
+/*
+ * SiFive CLINT (Core Local Interruptor)
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * This provides real-time clock, timer and interprocessor interrupts.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "hw/sysbus.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_clint.h"
+#include "qemu/timer.h"
+
+/* See: riscv-pk/machine/sbi_entry.S and arch/riscv/kernel/time.c */
+#define TIMER_FREQ (10 * 1000 * 1000)
+
+uint64_t cpu_riscv_read_instret(CPURISCVState *env)
+{
+return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), TIMER_FREQ,
+NANOSECONDS_PER_SECOND);
+}
+
+uint64_t cpu_riscv_read_rtc(void)
+{
+return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), TIMER_FREQ,
+NANOSECONDS_PER_SECOND);
+}
+
+static void sifive_clint_irq_request(void *opaque, int irq, int level)
+{
+/* These are not the same irq numbers visible to the emulated processor. */
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = >env;
+CPUState *cs = CPU(cpu);
+
+/* The CLINT currently uses irq 0 */
+
+if (level) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+if (!env->mip && !env->mfromhost) {
+/* no interrupts pending, no host interrupt for HTIF, reset */
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}
+}
+}
+
+/*
+ * Called when timecmp is written to update the QEMU timer or immediately
+ * trigger timer interrupt if mtimecmp <= current timer value.
+ */
+static void sifive_clint_timer_update(CPURISCVState *env)
+{
+uint64_t next;
+uint64_t diff;
+
+uint64_t rtc_r = cpu_riscv_read_rtc();
+
+if (env->timecmp <= rtc_r) {
+/* if we're setting an MTIMECMP value in the "past",
+   immediately raise the timer interrupt */
+env->mip |= MIP_MTIP;
+qemu_irq_raise(env->irq[3]);
+return;
+}
+
+/* otherwise, set up the future timer interrupt */
+diff = env->timecmp - rtc_r;
+/* back to ns (note args switched in muldiv64) */
+next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+muldiv64(diff, NANOSECONDS_PER_SECOND, TIMER_FREQ);
+timer_mod(env->timer, next);
+}
+
+/*
+ * Called by the callback used when the timer set using timer_mod expires.
+ * Should raise the timer interrupt line
+ */
+static void sifive_clint_timer_expire(CPURISCVState *env)
+{
+/* do not call update here */
+env->mip |= MIP_MTIP;
+qemu_irq_raise(env->irq[3]);
+}
+
+static void sifive_clint_write_timecmp(CPURISCVState *env, uint64_t value)
+{
+env->timecmp = value;
+env->mip &= ~MIP_MTIP;
+sifive_clint_timer_update(env);
+}
+
+/*
+ * Callback used when the timer set using timer_mod expires.
+ */
+static void sifive_clint_timer_cb(void *opaque)
+{
+CPURISCVState *env;
+env = opaque;
+sifive_clint_timer_expire(env);
+}
+
+/* CPU wants to read rtc or timecmp register */
+static uint64_t sifive_clint_read(void *opaque, hwaddr addr, unsigned size)
+{
+SiFiveCLINTState *clint = opaque;
+if (addr >= clint->sip_base &&
+addr < clint->sip_base + (clint->num_harts << 2)) {
+size_t hartid = (addr - clint->sip_base) >> 2;
+  

[Qemu-devel] [PATCH v1 21/21] RISC-V Build Infrastructure

2018-01-02 Thread Michael Clark
This adds RISC-V into the build system enabling the following targets:

- riscv32-softmmu
- riscv64-softmmu
- riscv32-linux-user
- riscv64-linux-user

This adds defaults configs for RISC-V, enables the build for the RISC-V
CPU core, hardware, and Linux User Emulation. The 'qemu-binfmt-conf.sh'
script is updated to add the RISC-V ELF magic.

Expected checkpatch errors for consistency reasons:

ERROR: line over 90 characters
FILE: scripts/qemu-binfmt-conf.sh
Signed-off-by: Michael Clark 
---
 Makefile.objs  |  1 +
 arch_init.c|  2 ++
 configure  | 11 +++
 cpus.c |  6 ++
 default-configs/riscv32-linux-user.mak |  1 +
 default-configs/riscv32-softmmu.mak|  4 
 default-configs/riscv64-linux-user.mak |  1 +
 default-configs/riscv64-softmmu.mak|  4 
 hw/riscv/Makefile.objs | 12 
 include/sysemu/arch_init.h |  1 +
 qapi-schema.json   | 14 +-
 scripts/qemu-binfmt-conf.sh| 13 -
 target/riscv/Makefile.objs |  2 ++
 target/riscv/trace-events  |  1 +
 14 files changed, 71 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/riscv32-linux-user.mak
 create mode 100644 default-configs/riscv32-softmmu.mak
 create mode 100644 default-configs/riscv64-linux-user.mak
 create mode 100644 default-configs/riscv64-softmmu.mak
 create mode 100644 hw/riscv/Makefile.objs
 create mode 100644 target/riscv/Makefile.objs
 create mode 100644 target/riscv/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 285c6f3..ae8658e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -164,6 +164,7 @@ trace-events-subdirs += target/mips
 trace-events-subdirs += target/sparc
 trace-events-subdirs += target/s390x
 trace-events-subdirs += target/ppc
+trace-events-subdirs += target/riscv
 trace-events-subdirs += qom
 trace-events-subdirs += linux-user
 trace-events-subdirs += qapi
diff --git a/arch_init.c b/arch_init.c
index a0b8ed6..dcf356b 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -69,6 +69,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
 #define QEMU_ARCH QEMU_ARCH_PPC
+#elif defined(TARGET_RISCV)
+#define QEMU_ARCH QEMU_ARCH_RISCV
 #elif defined(TARGET_S390X)
 #define QEMU_ARCH QEMU_ARCH_S390X
 #elif defined(TARGET_SH4)
diff --git a/configure b/configure
index 100309c..832e025 100755
--- a/configure
+++ b/configure
@@ -6530,6 +6530,14 @@ case "$target_name" in
 echo "TARGET_ABI32=y" >> $config_target_mak
 gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml 
power-spe.xml power-vsx.xml"
   ;;
+  riscv32)
+TARGET_BASE_ARCH=riscv
+TARGET_ABI_DIR=riscv
+  ;;
+  riscv64)
+TARGET_BASE_ARCH=riscv
+TARGET_ABI_DIR=riscv
+  ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
 bflt="yes"
@@ -6692,6 +6700,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
 disas_config "PPC"
   ;;
+  riscv)
+disas_config "RISCV"
+  ;;
   s390*)
 disas_config "S390"
   ;;
diff --git a/cpus.c b/cpus.c
index 83700c1..702da8b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1909,6 +1909,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_SPARC)
 SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
 CPUSPARCState *env = _cpu->env;
+#elif defined(TARGET_RISCV)
+RISCVCPU *riscv_cpu = RISCV_CPU(cpu);
+CPURISCVState *env = _cpu->env;
 #elif defined(TARGET_MIPS)
 MIPSCPU *mips_cpu = MIPS_CPU(cpu);
 CPUMIPSState *env = _cpu->env;
@@ -1942,6 +1945,9 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 #elif defined(TARGET_TRICORE)
 info->value->arch = CPU_INFO_ARCH_TRICORE;
 info->value->u.tricore.PC = env->PC;
+#elif defined(TARGET_RISCV)
+info->value->arch = CPU_INFO_ARCH_RISCV;
+info->value->u.riscv.pc = env->pc;
 #else
 info->value->arch = CPU_INFO_ARCH_OTHER;
 #endif
diff --git a/default-configs/riscv32-linux-user.mak 
b/default-configs/riscv32-linux-user.mak
new file mode 100644
index 000..865b362
--- /dev/null
+++ b/default-configs/riscv32-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for riscv-linux-user
diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
new file mode 100644
index 000..f9e7421
--- /dev/null
+++ b/default-configs/riscv32-softmmu.mak
@@ -0,0 +1,4 @@
+# Default configuration for riscv-softmmu
+
+CONFIG_SERIAL=y
+CONFIG_VIRTIO=y
diff --git a/default-configs/riscv64-linux-user.mak 
b/default-configs/riscv64-linux-user.mak
new file mode 100644
index 000..865b362
--- /dev/null
+++ b/default-configs/riscv64-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for riscv-linux-user
diff --git a/default-configs/riscv64-softmmu.mak 
b/default-configs/riscv64-softmmu.mak
new file mode 100644
index 000..f9e7421
--- /dev/null
+++ b/default-configs/riscv64-softmmu.mak

[Qemu-devel] [PATCH v1 20/21] SiFive Freedom U500 RISC-V Machine

2018-01-02 Thread Michael Clark
This provides a RISC-V Board compatible with the the SiFive U500 SDK.
The following machine is implemented:

- 'sifive_u500'; CLINT, PLIC, UART, device-tree

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_u500.c | 338 +
 include/hw/riscv/sifive_u500.h |  69 +
 2 files changed, 407 insertions(+)
 create mode 100644 hw/riscv/sifive_u500.c
 create mode 100644 include/hw/riscv/sifive_u500.h

diff --git a/hw/riscv/sifive_u500.c b/hw/riscv/sifive_u500.c
new file mode 100644
index 000..9cc411e
--- /dev/null
+++ b/hw/riscv/sifive_u500.c
@@ -0,0 +1,338 @@
+/*
+ * QEMU RISC-V Board Compatible with SiFive U500 SDK
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * This provides a RISC-V Board compatible with the the SiFive U500 SDK
+ *
+ * 0) UART
+ * 1) CLINT (Core Level Interruptor)
+ * 2) PLIC (Platform Level Interrupt Controller)
+ *
+ * This board currently uses a hardcoded devicetree that indicates one hart.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/char/serial.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_plic.h"
+#include "hw/riscv/sifive_clint.h"
+#include "hw/riscv/sifive_uart.h"
+#include "hw/riscv/sifive_prci.h"
+#include "hw/riscv/sifive_u500.h"
+#include "chardev/char.h"
+#include "sysemu/arch_init.h"
+#include "sysemu/device_tree.h"
+#include "exec/address-spaces.h"
+#include "elf.h"
+
+static const struct MemmapEntry {
+hwaddr base;
+hwaddr size;
+} sifive_u500_memmap[] = {
+[SIFIVE_U500_DEBUG] ={0x0,  0x100 },
+[SIFIVE_U500_MROM] = { 0x1000, 0x2000 },
+[SIFIVE_U500_CLINT] ={  0x200,0x1 },
+[SIFIVE_U500_PLIC] = {  0xc00,  0x400 },
+[SIFIVE_U500_UART0] ={ 0x10013000, 0x1000 },
+[SIFIVE_U500_UART1] ={ 0x10023000, 0x1000 },
+[SIFIVE_U500_DRAM] = { 0x8000,0x0 },
+};
+
+static uint64_t identity_translate(void *opaque, uint64_t addr)
+{
+return addr;
+}
+
+static uint64_t load_kernel(const char *kernel_filename)
+{
+uint64_t kernel_entry, kernel_high;
+
+if (load_elf(kernel_filename, identity_translate, NULL,
+ _entry, NULL, _high,
+ /* little_endian = */ 0, ELF_MACHINE, 1, 0) < 0) {
+error_report("qemu: could not load kernel '%s'", kernel_filename);
+exit(1);
+}
+return kernel_entry;
+}
+
+static void create_fdt(SiFiveU500State *s, const struct MemmapEntry *memmap,
+uint64_t mem_size, const char *cmdline)
+{
+void *fdt;
+int cpu;
+uint32_t *cells;
+char *nodename;
+uint32_t plic_phandle;
+
+fdt = s->fdt = create_device_tree(>fdt_size);
+if (!fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+qemu_fdt_setprop_string(fdt, "/", "model", "ucbbar,spike-bare,qemu");
+qemu_fdt_setprop_string(fdt, "/", "compatible", "ucbbar,spike-bare-dev");
+qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+
+qemu_fdt_add_subnode(fdt, "/soc");
+qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
+qemu_fdt_setprop_string(fdt, "/soc", "compatible", 
"ucbbar,spike-bare-soc");
+qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
+
+nodename = g_strdup_printf("/memory@%lx",
+(long)memmap[SIFIVE_U500_DRAM].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+memmap[SIFIVE_U500_DRAM].base >> 32, memmap[SIFIVE_U500_DRAM].base,
+

[Qemu-devel] [PATCH v1 19/21] SiFive Freedom E300 RISC-V Machine

2018-01-02 Thread Michael Clark
This provides a RISC-V Board compatible with the the SiFive E300 SDK.
The following machine is implemented:

- 'sifive_e300'; CLINT, PLIC, UART, AON, GPIO, QSPI, PWM

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_e300.c | 232 +
 include/hw/riscv/sifive_e300.h |  79 ++
 2 files changed, 311 insertions(+)
 create mode 100644 hw/riscv/sifive_e300.c
 create mode 100644 include/hw/riscv/sifive_e300.h

diff --git a/hw/riscv/sifive_e300.c b/hw/riscv/sifive_e300.c
new file mode 100644
index 000..bbea55a
--- /dev/null
+++ b/hw/riscv/sifive_e300.c
@@ -0,0 +1,232 @@
+/*
+ * QEMU RISC-V Board Compatible with SiFive E300 SDK
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Provides a board compatible with the bsp in the SiFive E300 SDK:
+ *
+ * 0) UART
+ * 1) CLINT (Core Level Interruptor)
+ * 2) PLIC (Platform Level Interrupt Controller)
+ * 3) PRCI (Power, Reset, Clock, Interrupt)
+ * 4) Registers emulated as RAM: AON, GPIO, QSPI, PWM
+ * 5) Flash memory emulated as RAM
+ *
+ * The Mask ROM reset vector jumps to the flash payload at 0x2040_.
+ * The OTP ROM and Flash boot code will be emulated in a future version.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/char/serial.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_plic.h"
+#include "hw/riscv/sifive_clint.h"
+#include "hw/riscv/sifive_prci.h"
+#include "hw/riscv/sifive_uart.h"
+#include "hw/riscv/sifive_e300.h"
+#include "chardev/char.h"
+#include "sysemu/arch_init.h"
+#include "exec/address-spaces.h"
+#include "elf.h"
+
+static const struct MemmapEntry {
+hwaddr base;
+hwaddr size;
+} sifive_e300_memmap[] = {
+[SIFIVE_E300_DEBUG] ={0x0,  0x100 },
+[SIFIVE_E300_MROM] = { 0x1000, 0x2000 },
+[SIFIVE_E300_OTP] =  {0x2, 0x2000 },
+[SIFIVE_E300_CLINT] ={  0x200,0x1 },
+[SIFIVE_E300_PLIC] = {  0xc00,  0x400 },
+[SIFIVE_E300_AON] =  { 0x1000, 0x8000 },
+[SIFIVE_E300_PRCI] = { 0x10008000, 0x8000 },
+[SIFIVE_E300_OTP_CTRL] = { 0x1001, 0x1000 },
+[SIFIVE_E300_GPIO0] ={ 0x10012000, 0x1000 },
+[SIFIVE_E300_UART0] ={ 0x10013000, 0x1000 },
+[SIFIVE_E300_QSPI0] ={ 0x10014000, 0x1000 },
+[SIFIVE_E300_PWM0] = { 0x10015000, 0x1000 },
+[SIFIVE_E300_UART1] ={ 0x10023000, 0x1000 },
+[SIFIVE_E300_QSPI1] ={ 0x10024000, 0x1000 },
+[SIFIVE_E300_PWM1] = { 0x10025000, 0x1000 },
+[SIFIVE_E300_QSPI2] ={ 0x10034000, 0x1000 },
+[SIFIVE_E300_PWM2] = { 0x10035000, 0x1000 },
+[SIFIVE_E300_XIP] =  { 0x2000, 0x2000 },
+[SIFIVE_E300_DTIM] = { 0x8000, 0x4000 }
+};
+
+static uint64_t identity_translate(void *opaque, uint64_t addr)
+{
+return addr;
+}
+
+static uint64_t load_kernel(const char *kernel_filename)
+{
+uint64_t kernel_entry, kernel_high;
+
+if (load_elf(kernel_filename, identity_translate, NULL,
+ _entry, NULL, _high,
+ /* little_endian = */ 0, ELF_MACHINE, 1, 0) < 0) {
+error_report("qemu: could not load kernel '%s'", kernel_filename);
+exit(1);
+}
+return kernel_entry;
+}
+
+static void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
+ uintptr_t offset, uintptr_t length)
+{
+MemoryRegion *mock_mmio = g_new(MemoryRegion, 1);
+memory_region_init_ram(mock_mmio, NULL, name, length, _fatal);
+memory_region_add_subregion(parent, offset, mock_mmio);
+}
+
+static void riscv_sifive_e300_init(MachineState *machine)
+{
+const struct MemmapEntry *memmap 

[Qemu-devel] [PATCH v1 08/21] RISC-V TCG Code Generation

2018-01-02 Thread Michael Clark
TCG code generation for the RV32IMAFDC and RV64IMAFDC. The QEMU
RISC-V code generator has complete coverage for the Base ISA v2.2,
Privileged ISA v1.9.1 and Privileged ISA v1.10:

- RISC-V Instruction Set Manual Volume I: User-Level ISA Version 2.2
- RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.9.1
- RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.10

Signed-off-by: Michael Clark 
---
 target/riscv/instmap.h   |  377 +
 target/riscv/translate.c | 2032 ++
 2 files changed, 2409 insertions(+)
 create mode 100644 target/riscv/instmap.h
 create mode 100644 target/riscv/translate.c

diff --git a/target/riscv/instmap.h b/target/riscv/instmap.h
new file mode 100644
index 000..5121f63
--- /dev/null
+++ b/target/riscv/instmap.h
@@ -0,0 +1,377 @@
+/*
+ * RISC-V emulation for qemu: Instruction decode helpers
+ *
+ * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#define MASK_OP_MAJOR(op)  (op & 0x7F)
+enum {
+/* rv32i, rv64i, rv32m */
+OPC_RISC_LUI= (0x37),
+OPC_RISC_AUIPC  = (0x17),
+OPC_RISC_JAL= (0x6F),
+OPC_RISC_JALR   = (0x67),
+OPC_RISC_BRANCH = (0x63),
+OPC_RISC_LOAD   = (0x03),
+OPC_RISC_STORE  = (0x23),
+OPC_RISC_ARITH_IMM  = (0x13),
+OPC_RISC_ARITH  = (0x33),
+OPC_RISC_FENCE  = (0x0F),
+OPC_RISC_SYSTEM = (0x73),
+
+/* rv64i, rv64m */
+OPC_RISC_ARITH_IMM_W = (0x1B),
+OPC_RISC_ARITH_W = (0x3B),
+
+/* rv32a, rv64a */
+OPC_RISC_ATOMIC = (0x2F),
+
+/* floating point */
+OPC_RISC_FP_LOAD = (0x7),
+OPC_RISC_FP_STORE = (0x27),
+
+OPC_RISC_FMADD = (0x43),
+OPC_RISC_FMSUB = (0x47),
+OPC_RISC_FNMSUB = (0x4B),
+OPC_RISC_FNMADD = (0x4F),
+
+OPC_RISC_FP_ARITH = (0x53),
+};
+
+#define MASK_OP_ARITH(op)   (MASK_OP_MAJOR(op) | (op & ((0x7 << 12) | \
+(0x7F << 25
+enum {
+OPC_RISC_ADD   = OPC_RISC_ARITH | (0x0 << 12) | (0x00 << 25),
+OPC_RISC_SUB   = OPC_RISC_ARITH | (0x0 << 12) | (0x20 << 25),
+OPC_RISC_SLL   = OPC_RISC_ARITH | (0x1 << 12) | (0x00 << 25),
+OPC_RISC_SLT   = OPC_RISC_ARITH | (0x2 << 12) | (0x00 << 25),
+OPC_RISC_SLTU  = OPC_RISC_ARITH | (0x3 << 12) | (0x00 << 25),
+OPC_RISC_XOR   = OPC_RISC_ARITH | (0x4 << 12) | (0x00 << 25),
+OPC_RISC_SRL   = OPC_RISC_ARITH | (0x5 << 12) | (0x00 << 25),
+OPC_RISC_SRA   = OPC_RISC_ARITH | (0x5 << 12) | (0x20 << 25),
+OPC_RISC_OR= OPC_RISC_ARITH | (0x6 << 12) | (0x00 << 25),
+OPC_RISC_AND   = OPC_RISC_ARITH | (0x7 << 12) | (0x00 << 25),
+
+/* RV64M */
+OPC_RISC_MUL= OPC_RISC_ARITH | (0x0 << 12) | (0x01 << 25),
+OPC_RISC_MULH   = OPC_RISC_ARITH | (0x1 << 12) | (0x01 << 25),
+OPC_RISC_MULHSU = OPC_RISC_ARITH | (0x2 << 12) | (0x01 << 25),
+OPC_RISC_MULHU  = OPC_RISC_ARITH | (0x3 << 12) | (0x01 << 25),
+
+OPC_RISC_DIV= OPC_RISC_ARITH | (0x4 << 12) | (0x01 << 25),
+OPC_RISC_DIVU   = OPC_RISC_ARITH | (0x5 << 12) | (0x01 << 25),
+OPC_RISC_REM= OPC_RISC_ARITH | (0x6 << 12) | (0x01 << 25),
+OPC_RISC_REMU   = OPC_RISC_ARITH | (0x7 << 12) | (0x01 << 25),
+};
+
+
+#define MASK_OP_ARITH_IMM(op)   (MASK_OP_MAJOR(op) | (op & (0x7 << 12)))
+enum {
+OPC_RISC_ADDI   = OPC_RISC_ARITH_IMM | (0x0 << 12),
+OPC_RISC_SLTI   = OPC_RISC_ARITH_IMM | (0x2 << 12),
+OPC_RISC_SLTIU  = OPC_RISC_ARITH_IMM | (0x3 << 12),
+OPC_RISC_XORI   = OPC_RISC_ARITH_IMM | (0x4 << 12),
+OPC_RISC_ORI= OPC_RISC_ARITH_IMM | (0x6 << 12),
+OPC_RISC_ANDI   = OPC_RISC_ARITH_IMM | (0x7 << 12),
+OPC_RISC_SLLI   = OPC_RISC_ARITH_IMM | (0x1 << 12), /* additional part of
+   IMM */
+OPC_RISC_SHIFT_RIGHT_I = OPC_RISC_ARITH_IMM | (0x5 << 12) /* SRAI, SRLI */
+};
+
+#define MASK_OP_BRANCH(op) (MASK_OP_MAJOR(op) | (op & (0x7 << 12)))
+enum {
+OPC_RISC_BEQ  = OPC_RISC_BRANCH  | (0x0  << 12),
+OPC_RISC_BNE  = OPC_RISC_BRANCH  | (0x1  << 12),
+OPC_RISC_BLT  = OPC_RISC_BRANCH  | (0x4  << 12),
+OPC_RISC_BGE  = OPC_RISC_BRANCH  | (0x5  << 12),
+OPC_RISC_BLTU = OPC_RISC_BRANCH  | (0x6  << 12),
+OPC_RISC_BGEU = OPC_RISC_BRANCH  | (0x7  << 12)
+};
+
+enum {
+OPC_RISC_ADDIW   = 

[Qemu-devel] [PATCH v1 17/21] SiFive RISC-V UART Device

2018-01-02 Thread Michael Clark
QEMU model of the UART on the SiFive E300 and U500 series SOCs.
BBL supports the SiFive UART for early console access via the SBI
(Supervisor Binary Interface) and the linux kernel SBI console.

The SiFive UART implements the pre qom legacy interface consistent
with the 16550a UART in 'hw/char/serial.c'.

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_uart.c | 182 +
 include/hw/riscv/sifive_uart.h |  76 +
 2 files changed, 258 insertions(+)
 create mode 100644 hw/riscv/sifive_uart.c
 create mode 100644 include/hw/riscv/sifive_uart.h

diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c
new file mode 100644
index 000..0e73df6
--- /dev/null
+++ b/hw/riscv/sifive_uart.c
@@ -0,0 +1,182 @@
+/*
+ * QEMU model of the UART on the SiFive E300 and U500 series SOCs.
+ *
+ * Copyright (c) 2016 Stefan O'Rear
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_uart.h"
+
+/*
+ * Not yet implemented:
+ *
+ * Transmit FIFO using "qemu/fifo8.h"
+ * SIFIVE_UART_IE_TXWM interrupts
+ * SIFIVE_UART_IE_RXWM interrupts must honor fifo watermark
+ * Rx FIFO watermark interrupt trigger threshold
+ * Tx FIFO watermark interrupt trigger threshold.
+ */
+
+static void update_irq(SiFiveUARTState *s)
+{
+int cond = 0;
+if ((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len) {
+cond = 1;
+}
+if (cond) {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static uint64_t
+uart_read(void *opaque, hwaddr addr, unsigned int size)
+{
+SiFiveUARTState *s = opaque;
+unsigned char r;
+switch (addr) {
+case SIFIVE_UART_RXFIFO:
+if (s->rx_fifo_len) {
+r = s->rx_fifo[0];
+memmove(s->rx_fifo, s->rx_fifo + 1, s->rx_fifo_len - 1);
+s->rx_fifo_len--;
+qemu_chr_fe_accept_input(>chr);
+update_irq(s);
+return r;
+}
+return 0x8000;
+
+case SIFIVE_UART_TXFIFO:
+return 0; /* Should check tx fifo */
+case SIFIVE_UART_IE:
+return s->ie;
+case SIFIVE_UART_IP:
+return s->rx_fifo_len ? SIFIVE_UART_IP_RXWM : 0;
+case SIFIVE_UART_TXCTRL:
+return s->txctrl;
+case SIFIVE_UART_RXCTRL:
+return s->rxctrl;
+case SIFIVE_UART_DIV:
+return s->div;
+}
+
+hw_error("%s: bad read: addr=0x%x\n",
+__func__, (int)addr);
+return 0;
+}
+
+static void
+uart_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+SiFiveUARTState *s = opaque;
+uint32_t value = val64;
+unsigned char ch = value;
+
+switch (addr) {
+case SIFIVE_UART_TXFIFO:
+qemu_chr_fe_write(>chr, , 1);
+return;
+case SIFIVE_UART_IE:
+s->ie = val64;
+update_irq(s);
+return;
+case SIFIVE_UART_TXCTRL:
+s->txctrl = val64;
+return;
+case SIFIVE_UART_RXCTRL:
+s->rxctrl = val64;
+return;
+case SIFIVE_UART_DIV:
+s->div = val64;
+return;
+}
+hw_error("%s: bad write: addr=0x%x v=0x%x\n",
+__func__, (int)addr, (int)value);
+}
+
+static const MemoryRegionOps uart_ops = {
+.read = uart_read,
+.write = uart_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4
+}
+};
+
+static void uart_rx(void *opaque, const uint8_t *buf, int size)
+{
+SiFiveUARTState *s = opaque;
+
+/* Got a byte.  */
+if (s->rx_fifo_len >= sizeof(s->rx_fifo)) {
+printf("WARNING: UART dropped char.\n");
+return;
+}
+s->rx_fifo[s->rx_fifo_len++] = *buf;
+
+update_irq(s);
+}
+
+static int uart_can_rx(void 

[Qemu-devel] [PATCH v1 16/21] RISC-V VirtIO Machine

2018-01-02 Thread Michael Clark
RISC-V machine with device-tree, 16550a UART and VirtIO MMIO.
The following machine is implemented:

- 'virt'; CLINT, PLIC, 16550A UART, VirtIO MMIO, device-tree

Signed-off-by: Michael Clark 
---
 hw/riscv/virt.c | 364 
 include/hw/riscv/virt.h |  73 ++
 2 files changed, 437 insertions(+)
 create mode 100644 hw/riscv/virt.c
 create mode 100644 include/hw/riscv/virt.h

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
new file mode 100644
index 000..7c6fead
--- /dev/null
+++ b/hw/riscv/virt.c
@@ -0,0 +1,364 @@
+/*
+ * QEMU RISC-V VirtIO Board
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * RISC-V machine with 16550a UART and VirtIO MMIO
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/char/serial.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/riscv_htif.h"
+#include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_plic.h"
+#include "hw/riscv/sifive_clint.h"
+#include "hw/riscv/virt.h"
+#include "chardev/char.h"
+#include "sysemu/arch_init.h"
+#include "sysemu/device_tree.h"
+#include "exec/address-spaces.h"
+#include "elf.h"
+
+static const struct MemmapEntry {
+hwaddr base;
+hwaddr size;
+} virt_memmap[] = {
+[VIRT_DEBUG] ={0x0,  0x100 },
+[VIRT_MROM] = { 0x1000, 0x2000 },
+[VIRT_CLINT] ={  0x200,0x1 },
+[VIRT_PLIC] = {  0xc00,  0x400 },
+[VIRT_UART0] ={ 0x1000,  0x100 },
+[VIRT_VIRTIO] =   { 0x10001000, 0x1000 },
+[VIRT_DRAM] = { 0x8000,0x0 },
+};
+
+static uint64_t identity_translate(void *opaque, uint64_t addr)
+{
+return addr;
+}
+
+static uint64_t load_kernel(const char *kernel_filename)
+{
+uint64_t kernel_entry, kernel_high;
+
+if (load_elf(kernel_filename, identity_translate, NULL,
+ _entry, NULL, _high,
+ /* little_endian = */ 0, ELF_MACHINE, 1, 0) < 0) {
+error_report("qemu: could not load kernel '%s'", kernel_filename);
+exit(1);
+}
+return kernel_entry;
+}
+
+static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+uint64_t mem_size, const char *cmdline)
+{
+void *fdt;
+int cpu;
+uint32_t *cells;
+char *nodename;
+uint32_t plic_phandle, phandle = 1;
+int i;
+
+fdt = s->fdt = create_device_tree(>fdt_size);
+if (!fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+qemu_fdt_setprop_string(fdt, "/", "model", "riscv-virtio,qemu");
+qemu_fdt_setprop_string(fdt, "/", "compatible", "riscv-virtio");
+qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+
+qemu_fdt_add_subnode(fdt, "/soc");
+qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
+qemu_fdt_setprop_string(fdt, "/soc", "compatible", "riscv-virtio-soc");
+qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
+
+nodename = g_strdup_printf("/memory@%lx",
+(long)memmap[VIRT_DRAM].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+memmap[VIRT_DRAM].base >> 32, memmap[VIRT_DRAM].base,
+mem_size >> 32, mem_size);
+qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
+g_free(nodename);
+
+qemu_fdt_add_subnode(fdt, "/cpus");
+qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 1000);
+qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
+qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
+
+for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
+int cpu_phandle = phandle++;

[Qemu-devel] [PATCH v1 18/21] SiFive RISC-V PRCI Block

2018-01-02 Thread Michael Clark
Simple model of the PRCI  (Power, Reset, Clock, Interrupt) to emulate
register reads made by the SDK BSP.

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_prci.c | 107 +
 include/hw/riscv/sifive_prci.h |  43 +
 2 files changed, 150 insertions(+)
 create mode 100644 hw/riscv/sifive_prci.c
 create mode 100644 include/hw/riscv/sifive_prci.h

diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_prci.c
new file mode 100644
index 000..5c27696
--- /dev/null
+++ b/hw/riscv/sifive_prci.c
@@ -0,0 +1,107 @@
+/*
+ * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt)
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Simple model of the PRCI to emulate register reads made by the SDK BSP
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_prci.h"
+
+/* currently implements enough to mock freedom-e-sdk BSP clock programming */
+
+static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
+{
+if (addr == 0 /* PRCI_HFROSCCFG */) {
+return 1 << 31; /* ROSC_RDY */
+}
+if (addr == 8 /* PRCI_PLLCFG*/) {
+return 1 << 31; /* PLL_LOCK */
+}
+hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+return 0;
+}
+
+static void sifive_prci_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+/* discard writes */
+}
+
+static const MemoryRegionOps sifive_prci_ops = {
+.read = sifive_prci_read,
+.write = sifive_prci_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4
+}
+};
+
+static Property sifive_prci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sifive_prci_init(Object *obj)
+{
+SiFivePRCIState *s = SIFIVE_PRCI(obj);
+
+memory_region_init_io(>mmio, obj, _prci_ops, s,
+  TYPE_SIFIVE_PRCI, 0x8000);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
+}
+
+static void sifive_prci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->props = sifive_prci_properties;
+}
+
+static const TypeInfo sifive_prci_info = {
+.name  = TYPE_SIFIVE_PRCI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(SiFivePRCIState),
+.instance_init = sifive_prci_init,
+.class_init= sifive_prci_class_init,
+};
+
+static void sifive_prci_register_types(void)
+{
+type_register_static(_prci_info);
+}
+
+type_init(sifive_prci_register_types)
+
+
+/*
+ * Create PRCI device.
+ */
+DeviceState *sifive_prci_create(hwaddr addr)
+{
+DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_PRCI);
+qdev_init_nofail(dev);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+return dev;
+}
diff --git a/include/hw/riscv/sifive_prci.h b/include/hw/riscv/sifive_prci.h
new file mode 100644
index 000..0e032e5
--- /dev/null
+++ b/include/hw/riscv/sifive_prci.h
@@ -0,0 +1,43 @@
+/*
+ * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt) interface
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 

[Qemu-devel] [PATCH v1 15/21] RISC-V Spike Machines

2018-01-02 Thread Michael Clark
RISC-V machines compatble with Spike aka riscv-isa-sim, the RISC-V
Instruction Set Simulator. The following machines are implemented:

- 'spike_v1.9'; HTIF console, config-string, Privileged ISA Version 1.9.1
- 'spike_v1.10'; HTIF console, device-tree, Privileged ISA Version 1.10

Signed-off-by: Michael Clark 
---
 hw/riscv/spike_v1_09.c   | 207 ++
 hw/riscv/spike_v1_10.c   | 281 +++
 include/hw/riscv/spike.h |  51 +
 3 files changed, 539 insertions(+)
 create mode 100644 hw/riscv/spike_v1_09.c
 create mode 100644 hw/riscv/spike_v1_10.c
 create mode 100644 include/hw/riscv/spike.h

diff --git a/hw/riscv/spike_v1_09.c b/hw/riscv/spike_v1_09.c
new file mode 100644
index 000..9b32c6a
--- /dev/null
+++ b/hw/riscv/spike_v1_09.c
@@ -0,0 +1,207 @@
+/*
+ * QEMU RISC-V Spike Board
+ *
+ * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ * This provides a RISC-V Board with the following devices:
+ *
+ * 0) HTIF Test Pass/Fail Reporting (no syscall proxy)
+ * 1) HTIF Console
+ *
+ * These are created by htif_mm_init below.
+ *
+ * This board currently uses a hardcoded devicetree that indicates one hart.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/riscv_htif.h"
+#include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_clint.h"
+#include "hw/riscv/spike.h"
+#include "chardev/char.h"
+#include "sysemu/arch_init.h"
+#include "exec/address-spaces.h"
+#include "elf.h"
+
+static const struct MemmapEntry {
+hwaddr base;
+hwaddr size;
+} spike_memmap[] = {
+[SPIKE_MROM] = { 0x1000, 0x2000 },
+[SPIKE_CLINT] ={  0x200,0x1 },
+[SPIKE_DRAM] = { 0x8000,0x0 },
+};
+
+static uint64_t identity_translate(void *opaque, uint64_t addr)
+{
+return addr;
+}
+
+static uint64_t load_kernel(const char *kernel_filename)
+{
+uint64_t kernel_entry, kernel_high;
+
+if (load_elf(kernel_filename, identity_translate, NULL,
+ _entry, NULL, _high,
+ /* little_endian = */ 0, ELF_MACHINE, 1, 0) < 0) {
+error_report("qemu: could not load kernel '%s'", kernel_filename);
+exit(1);
+}
+return kernel_entry;
+}
+
+static void riscv_spike_board_init(MachineState *machine)
+{
+const struct MemmapEntry *memmap = spike_memmap;
+
+SpikeState *s = g_new0(SpikeState, 1);
+/* const char *cpu_model = machine->cpu_model; */
+/* const char *kernel_cmdline = machine->kernel_cmdline; */
+/* const char *initrd_filename = machine->initrd_filename; */
+MemoryRegion *system_memory = get_system_memory();
+MemoryRegion *main_mem = g_new(MemoryRegion, 1);
+MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+
+/* Initialize SOC */
+object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
+object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
+  _abort);
+object_property_set_str(OBJECT(>soc), TYPE_RISCV_CPU_IMAFDCSU_PRIV_1_09,
+"cpu-model", _abort);
+object_property_set_int(OBJECT(>soc), smp_cpus, "num-harts",
+_abort);
+object_property_set_bool(OBJECT(>soc), true, "realized",
+_abort);
+
+/* register system main memory (actual RAM) */
+memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
+   machine->ram_size, _fatal);
+memory_region_add_subregion(system_memory, DRAM_BASE, main_mem);
+
+/* boot rom */
+memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom",
+   0x4, _fatal);
+

[Qemu-devel] [PATCH v1 09/21] RISC-V Physical Memory Protection

2018-01-02 Thread Michael Clark
Implements the physical memory protection extension as specified in
Privileged ISA Version 1.10.

Signed-off-by: Michael Clark 
---
 target/riscv/pmp.c | 381 +
 target/riscv/pmp.h |  70 ++
 2 files changed, 451 insertions(+)
 create mode 100644 target/riscv/pmp.c
 create mode 100644 target/riscv/pmp.h

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
new file mode 100644
index 000..04f1df7
--- /dev/null
+++ b/target/riscv/pmp.c
@@ -0,0 +1,381 @@
+/*
+ * QEMU RISC-V PMP (Physical Memory Protection)
+ *
+ * Author: Daire McNamara, daire.mcnam...@emdalo.com
+ * Ivan Griffin, ivan.grif...@emdalo.com
+ *
+ * This provides a RISC-V Physical Memory Protection implementation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "qemu-common.h"
+
+/* #define DEBUG_PMP 1 */
+
+#ifndef CONFIG_USER_ONLY
+
+#ifdef DEBUG_PMP
+#define PMP_PRINTF(fmt, ...) \
+do { fprintf(stderr, "pmp: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define PMP_PRINTF(fmt, ...) \
+do {} while (0)
+#endif
+
+static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
+uint8_t val);
+static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
+static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
+
+/*
+ * Accessor method to extract address matching type 'a field' from cfg reg
+ */
+static inline uint8_t pmp_get_a_field(uint8_t cfg)
+{
+uint8_t a = cfg >> 3;
+return a & 0x3;
+}
+
+/*
+ * Check whether a PMP is locked or not.
+ */
+static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
+{
+
+if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
+return 1;
+}
+
+/* Top PMP has no 'next' to check */
+if ((pmp_index + 1u) >= MAX_RISCV_PMPS) {
+return 0;
+}
+
+/* In TOR mode, need to check the lock bit of the next pmp
+ * (if there is a next)
+ */
+const uint8_t a_field =
+pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
+if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
+ (PMP_AMATCH_TOR == a_field)) {
+return 1;
+}
+
+return 0;
+}
+
+/*
+ * Count the number of active rules.
+ */
+static inline uint32_t pmp_get_num_rules(CPURISCVState *env)
+{
+ return env->pmp_state.num_rules;
+}
+
+/*
+ * Accessor to get the cfg reg for a specific PMP/HART
+ */
+static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
+{
+if (pmp_index < MAX_RISCV_PMPS) {
+return env->pmp_state.pmp[pmp_index].cfg_reg;
+}
+
+return 0;
+}
+
+
+/*
+ * Accessor to set the cfg reg for a specific PMP/HART
+ * Bounds checks and relevant lock bit.
+ */
+static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
+{
+if (pmp_index < MAX_RISCV_PMPS) {
+if (!pmp_is_locked(env, pmp_index)) {
+env->pmp_state.pmp[pmp_index].cfg_reg = val;
+pmp_update_rule(env, pmp_index);
+} else {
+PMP_PRINTF("Ignoring pmpcfg write - locked\n");
+}
+} else {
+PMP_PRINTF("Ignoring pmpcfg write - out of bounds\n");
+}
+}
+
+static target_ulong pmp_get_napot_base_and_range(target_ulong reg,
+target_ulong *range)
+{
+/* construct a mask of all bits bar the top bit */
+target_ulong mask = 0u;
+target_ulong base = reg;
+target_ulong numbits = (sizeof(target_ulong) * 8u) + 2u;
+mask = (mask - 1u) >> 1;
+
+while (mask) {
+if ((reg & mask) == mask) {
+/* this is the mask to use */
+base = reg & ~mask;
+break;
+}
+mask >>= 1;
+numbits--;
+}
+
+*range = (1lu << numbits) - 1u;
+return base;
+}
+
+
+/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
+ *   end address values.
+ *   

[Qemu-devel] [PATCH v1 12/21] RISC-V HART Array

2018-01-02 Thread Michael Clark
Holds the state of a heterogenous array of RISC-V hardware threads.

Signed-off-by: Michael Clark 
---
 hw/riscv/riscv_hart.c | 95 +++
 include/hw/riscv/riscv_hart.h | 45 
 2 files changed, 140 insertions(+)
 create mode 100644 hw/riscv/riscv_hart.c
 create mode 100644 include/hw/riscv/riscv_hart.h

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
new file mode 100644
index 000..a7e079e
--- /dev/null
+++ b/hw/riscv/riscv_hart.c
@@ -0,0 +1,95 @@
+/*
+ * QEMU RISCV Hart Array
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Holds the state of a heterogenous array of RISC-V harts
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/riscv_hart.h"
+
+static Property riscv_harts_props[] = {
+DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
+DEFINE_PROP_STRING("cpu-model", RISCVHartArrayState, cpu_model),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void riscv_harts_cpu_reset(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+cpu_reset(CPU(cpu));
+}
+
+static void riscv_harts_realize(DeviceState *dev, Error **errp)
+{
+RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
+Error *err = NULL;
+int n;
+
+s->harts = g_new0(RISCVCPU, s->num_harts);
+
+for (n = 0; n < s->num_harts; n++) {
+
+object_initialize(>harts[n], sizeof(RISCVCPU), s->cpu_model);
+s->harts[n].env.mhartid = n;
+object_property_add_child(OBJECT(s), "harts[*]", OBJECT(>harts[n]),
+  _abort);
+qemu_register_reset(riscv_harts_cpu_reset, >harts[n]);
+object_property_set_bool(OBJECT(>harts[n]), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+}
+}
+
+static void riscv_harts_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->props = riscv_harts_props;
+dc->realize = riscv_harts_realize;
+}
+
+static void riscv_harts_init(Object *obj)
+{
+/* RISCVHartArrayState *s = SIFIVE_COREPLEX(obj); */
+}
+
+static const TypeInfo riscv_harts_info = {
+.name  = TYPE_RISCV_HART_ARRAY,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(RISCVHartArrayState),
+.instance_init = riscv_harts_init,
+.class_init= riscv_harts_class_init,
+};
+
+static void riscv_harts_register_types(void)
+{
+type_register_static(_harts_info);
+}
+
+type_init(riscv_harts_register_types)
diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
new file mode 100644
index 000..c45e987
--- /dev/null
+++ b/include/hw/riscv/riscv_hart.h
@@ -0,0 +1,45 @@
+/*
+ * QEMU RISC-V Hart Array interface
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Holds the state of a heterogenous array of RISC-V harts
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, 

[Qemu-devel] [PATCH v1 11/21] RISC-V HTIF Console

2018-01-02 Thread Michael Clark
HTIF (Host Target Interface) provides console emulation for QEMU. HTIF
allows identical copies of BBL (Berkeley Boot Loader) and linux to run
on both Spike and QEMU. BBL provides HTIF console access via the
SBI (Supervisor Binary Interface) and the linux kernel SBI console.

The HTIF interface reads the ELF kernel and locates the 'tohost' and
'fromhost' symbols which it uses for guest to host console MMIO.

The HTIT chardev implements the pre qom legacy interface consistent
with the 16550a UART in 'hw/char/serial.c'.

Signed-off-by: Michael Clark 
---
 hw/riscv/riscv_elf.c  | 244 ++
 hw/riscv/riscv_htif.c | 399 ++
 include/hw/riscv/riscv_elf.h  |  69 
 include/hw/riscv/riscv_htif.h |  62 +++
 4 files changed, 774 insertions(+)
 create mode 100644 hw/riscv/riscv_elf.c
 create mode 100644 hw/riscv/riscv_htif.c
 create mode 100644 include/hw/riscv/riscv_elf.h
 create mode 100644 include/hw/riscv/riscv_htif.h

diff --git a/hw/riscv/riscv_elf.c b/hw/riscv/riscv_elf.c
new file mode 100644
index 000..355a5a1
--- /dev/null
+++ b/hw/riscv/riscv_elf.c
@@ -0,0 +1,244 @@
+/*
+ * elf.c - A simple package for manipulating symbol tables in elf binaries.
+ *
+ * Taken from
+ * https://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15213-f03/www/
+ * ftrace/elf.c
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hw/riscv/riscv_elf.h"
+
+/*
+ * elf_open - Map a binary into the address space and extract the
+ * locations of the static and dynamic symbol tables and their string
+ * tables. Return this information in a Elf object file handle that will
+ * be passed to all of the other elf functions.
+ */
+Elf_obj64 *elf_open64(const char *filename)
+{
+int i, fd;
+struct stat sbuf;
+Elf_obj64 *ep;
+Elf64_Shdr *shdr;
+
+ep = g_new(Elf_obj64, 1);
+
+/* Do some consistency checks on the binary */
+fd = open(filename, O_RDONLY);
+if (fd == -1) {
+fprintf(stderr, "Can't open \"%s\": %s\n", filename, strerror(errno));
+exit(1);
+}
+if (fstat(fd, ) == -1) {
+fprintf(stderr, "Can't stat \"%s\": %s\n", filename, strerror(errno));
+exit(1);
+}
+if (sbuf.st_size < sizeof(Elf64_Ehdr)) {
+fprintf(stderr, "\"%s\" is not an ELF binary object\n", filename);
+exit(1);
+}
+
+/* It looks OK, so map the Elf binary into our address space */
+ep->mlen = sbuf.st_size;
+ep->maddr = mmap(NULL, ep->mlen, PROT_READ, MAP_SHARED, fd, 0);
+if (ep->maddr == (void *)-1) {
+fprintf(stderr, "Can't mmap \"%s\": %s\n", filename, strerror(errno));
+exit(1);
+}
+close(fd);
+
+/* The Elf binary begins with the Elf header */
+ep->ehdr = ep->maddr;
+
+/* check we have a 64-bit little-endian RISC-V ELF object */
+if (ep->ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
+ep->ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
+ep->ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
+ep->ehdr->e_ident[EI_MAG3] != ELFMAG3 ||
+ep->ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
+ep->ehdr->e_ident[EI_DATA] != ELFDATA2LSB ||
+ep->ehdr->e_machine != EM_RISCV)
+{
+fprintf(stderr, "\"%s\" is not a 64-bit RISC-V ELF object\n", 
filename);
+exit(1);
+}
+
+/*
+ * Find the static and dynamic symbol tables and their string
+ * tables in the the mapped binary. The sh_link field in symbol
+ * table section headers gives the section index of the string
+ * table for that symbol table.
+ */
+shdr = (Elf64_Shdr *)(ep->maddr + ep->ehdr->e_shoff);
+for (i = 0; i < ep->ehdr->e_shnum; i++) {
+if (shdr[i].sh_type == SHT_SYMTAB) {   /* Static symbol table */
+ep->symtab = (Elf64_Sym *)(ep->maddr + shdr[i].sh_offset);
+ep->symtab_end = (Elf64_Sym *)((char *)ep->symtab +
+ shdr[i].sh_size);
+ep->strtab = (char *)(ep->maddr + shdr[shdr[i].sh_link].sh_offset);
+}
+if (shdr[i].sh_type == SHT_DYNSYM) {   /* Dynamic symbol table */
+ep->dsymtab = (Elf64_Sym *)(ep->maddr + shdr[i].sh_offset);
+ep->dsymtab_end = (Elf64_Sym *)((char *)ep->dsymtab +
+  shdr[i].sh_size);
+ep->dstrtab = (char *)(ep->maddr + 
shdr[shdr[i].sh_link].sh_offset);
+}
+}
+return ep;
+}
+
+Elf_obj32 *elf_open32(const char *filename)
+{
+int i, fd;
+struct stat sbuf;
+Elf_obj32 *ep;
+Elf32_Shdr *shdr;
+
+ep = g_new(Elf_obj32, 1);
+
+/* Do some consistency checks on the binary */
+fd = open(filename, O_RDONLY);
+if (fd == -1) {
+fprintf(stderr, "Can't open \"%s\": %s\n", filename, strerror(errno));
+exit(1);
+}
+if (fstat(fd, ) == -1) {
+fprintf(stderr, "Can't stat \"%s\": %s\n", filename, strerror(errno));

[Qemu-devel] [PATCH v1 14/21] SiFive RISC-V PLIC Block

2018-01-02 Thread Michael Clark
The PLIC (Platform Level Interrupt Controller) device provides a
parameterizable interrupt controller based on SiFive's PLIC specification.

Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_plic.c | 558 +
 include/hw/riscv/sifive_plic.h |  91 +++
 2 files changed, 649 insertions(+)
 create mode 100644 hw/riscv/sifive_plic.c
 create mode 100644 include/hw/riscv/sifive_plic.h

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
new file mode 100644
index 000..771dce0
--- /dev/null
+++ b/hw/riscv/sifive_plic.c
@@ -0,0 +1,558 @@
+/*
+ * SiFive PLIC (Platform Level Interrupt Controller)
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * This provides a parameterizable interrupt controller based on SiFive's PLIC.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "hw/sysbus.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_plic.h"
+
+/* #define RISCV_DEBUG_PLIC */
+
+static PLICMode char_to_mode(char c)
+{
+switch (c) {
+case 'U': return PLICMode_U;
+case 'S': return PLICMode_S;
+case 'H': return PLICMode_H;
+case 'M': return PLICMode_M;
+default:
+error_report("plic: invalid mode '%c'", c);
+exit(1);
+}
+}
+
+#if defined RISCV_DEBUG_PLIC
+
+static char mode_to_char(PLICMode m)
+{
+switch (m) {
+case PLICMode_U: return 'U';
+case PLICMode_S: return 'S';
+case PLICMode_H: return 'H';
+case PLICMode_M: return 'M';
+default: return '?';
+}
+}
+
+static void sifive_plic_print_state(SiFivePLICState *plic)
+{
+int i;
+int addrid;
+
+/* pending */
+printf("pending   : ");
+for (i = plic->bitfield_words - 1; i >= 0; i--) {
+printf("%08x", plic->pending[i]);
+}
+printf("\n");
+
+/* pending */
+printf("claimed   : ");
+for (i = plic->bitfield_words - 1; i >= 0; i--) {
+printf("%08x", plic->claimed[i]);
+}
+printf("\n");
+
+for (addrid = 0; addrid < plic->num_addrs; addrid++) {
+printf("hart%d-%c enable: ",
+plic->addr_config[addrid].hartid,
+mode_to_char(plic->addr_config[addrid].mode));
+for (i = plic->bitfield_words - 1; i >= 0; i--) {
+printf("%08x", plic->enable[addrid * plic->bitfield_words + i]);
+}
+printf("\n");
+}
+}
+
+#endif
+
+static
+void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool pending)
+{
+qemu_mutex_lock(>lock);
+uint32_t word = irq >> 5;
+if (pending) {
+plic->pending[word] |= (1 << (irq & 31));
+} else {
+plic->pending[word] &= ~(1 << (irq & 31));
+}
+qemu_mutex_unlock(>lock);
+}
+
+static
+void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool claimed)
+{
+qemu_mutex_lock(>lock);
+uint32_t word = irq >> 5;
+if (claimed) {
+plic->claimed[word] |= (1 << (irq & 31));
+} else {
+plic->claimed[word] &= ~(1 << (irq & 31));
+}
+qemu_mutex_unlock(>lock);
+}
+
+static
+int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
+{
+int i, j, count = 0;
+for (i = 0; i < plic->bitfield_words; i++) {
+uint32_t pending_enabled_not_claimed =
+(plic->pending[i] & ~plic->claimed[i]) &
+plic->enable[addrid * plic->bitfield_words + i];
+if (!pending_enabled_not_claimed) {
+continue;
+}
+for (j = 0; j < 32; j++) {
+int irq = (i << 5) + j;
+uint32_t prio = plic->source_priority[irq];
+int enabled = pending_enabled_not_claimed & (1 << j);
+if (enabled && prio > plic->target_priority[addrid]) {
+count++;
+}
+}
+}
+return count;
+}
+
+static void sifive_plic_update(SiFivePLICState *plic)
+{
+int addrid;
+
+/* raise irq on harts 

[Qemu-devel] [PATCH v1 04/21] RISC-V Disassembler

2018-01-02 Thread Michael Clark
The RISC-V disassembler has no dependencies outside of the 'disas'
directory so it can be applied independently. The majority of the
disassembler is machine-generated from instruction set metadata:

- https://github.com/michaeljclark/riscv-meta

Expected checkpatch errors for consistency and brevity reasons:

ERROR: line over 90 characters
ERROR: trailing statements should be on next line
ERROR: space prohibited between function name and open parenthesis '('
Signed-off-by: Michael Clark 
---
 disas.c |2 +
 disas/Makefile.objs |1 +
 disas/riscv.c   | 2966 +++
 include/disas/bfd.h |2 +
 4 files changed, 2971 insertions(+)
 create mode 100644 disas/riscv.c

diff --git a/disas.c b/disas.c
index d4ad108..5325b7e 100644
--- a/disas.c
+++ b/disas.c
@@ -522,6 +522,8 @@ void disas(FILE *out, void *code, unsigned long size)
 # ifdef _ARCH_PPC64
 s.info.cap_mode = CS_MODE_64;
 # endif
+#elif defined(__riscv__)
+print_insn = print_insn_riscv;
 #elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
 print_insn = print_insn_arm_a64;
 s.info.cap_arch = CS_ARCH_ARM64;
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 194648f..95c64cf 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -17,6 +17,7 @@ common-obj-$(CONFIG_MIPS_DIS) += mips.o
 common-obj-$(CONFIG_NIOS2_DIS) += nios2.o
 common-obj-$(CONFIG_MOXIE_DIS) += moxie.o
 common-obj-$(CONFIG_PPC_DIS) += ppc.o
+common-obj-$(CONFIG_RISCV_DIS) += riscv.o
 common-obj-$(CONFIG_S390_DIS) += s390.o
 common-obj-$(CONFIG_SH4_DIS) += sh4.o
 common-obj-$(CONFIG_SPARC_DIS) += sparc.o
diff --git a/disas/riscv.c b/disas/riscv.c
new file mode 100644
index 000..126d352
--- /dev/null
+++ b/disas/riscv.c
@@ -0,0 +1,2966 @@
+/*
+ * QEMU RISC-V Disassembler
+ *
+ * Copyright (c) 2016-2017 Michael Clark 
+ * Copyright (c) 2017 SiFive, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+
+
+/* types */
+
+typedef uint64_t rv_inst;
+typedef uint16_t rv_opcode;
+
+/* enums */
+
+typedef enum {
+rv32,
+rv64,
+rv128
+} rv_isa;
+
+typedef enum {
+rv_rm_rne = 0,
+rv_rm_rtz = 1,
+rv_rm_rdn = 2,
+rv_rm_rup = 3,
+rv_rm_rmm = 4,
+rv_rm_dyn = 7,
+} rv_rm;
+
+typedef enum {
+rv_fence_i = 8,
+rv_fence_o = 4,
+rv_fence_r = 2,
+rv_fence_w = 1,
+} rv_fence;
+
+typedef enum {
+rv_ireg_zero,
+rv_ireg_ra,
+rv_ireg_sp,
+rv_ireg_gp,
+rv_ireg_tp,
+rv_ireg_t0,
+rv_ireg_t1,
+rv_ireg_t2,
+rv_ireg_s0,
+rv_ireg_s1,
+rv_ireg_a0,
+rv_ireg_a1,
+rv_ireg_a2,
+rv_ireg_a3,
+rv_ireg_a4,
+rv_ireg_a5,
+rv_ireg_a6,
+rv_ireg_a7,
+rv_ireg_s2,
+rv_ireg_s3,
+rv_ireg_s4,
+rv_ireg_s5,
+rv_ireg_s6,
+rv_ireg_s7,
+rv_ireg_s8,
+rv_ireg_s9,
+rv_ireg_s10,
+rv_ireg_s11,
+rv_ireg_t3,
+rv_ireg_t4,
+rv_ireg_t5,
+rv_ireg_t6,
+} rv_ireg;
+
+typedef enum {
+rvc_end,
+rvc_simm_6,
+rvc_imm_6,
+rvc_imm_7,
+rvc_imm_8,
+rvc_imm_9,
+rvc_imm_10,
+rvc_imm_12,
+rvc_imm_18,
+rvc_imm_nz,
+rvc_imm_x2,
+rvc_imm_x4,
+rvc_imm_x8,
+rvc_imm_x16,
+rvc_rd_b3,
+rvc_rs1_b3,
+rvc_rs2_b3,
+rvc_rd_eq_rs1,
+rvc_rd_eq_ra,
+rvc_rd_eq_sp,
+rvc_rd_eq_x0,
+rvc_rs1_eq_sp,
+rvc_rs1_eq_x0,
+rvc_rs2_eq_x0,
+rvc_rd_ne_x0_x2,
+rvc_rd_ne_x0,
+rvc_rs1_ne_x0,
+rvc_rs2_ne_x0,
+rvc_rs2_eq_rs1,
+rvc_rs1_eq_ra,
+rvc_imm_eq_zero,
+rvc_imm_eq_n1,
+rvc_imm_eq_p1,
+rvc_csr_eq_0x001,
+rvc_csr_eq_0x002,
+rvc_csr_eq_0x003,
+rvc_csr_eq_0xc00,
+rvc_csr_eq_0xc01,
+rvc_csr_eq_0xc02,
+rvc_csr_eq_0xc80,
+rvc_csr_eq_0xc81,
+rvc_csr_eq_0xc82,
+} rvc_constraint;
+
+typedef enum {
+rv_codec_illegal,
+rv_codec_none,

[Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-02 Thread Michael Clark
Helper routines for FPU instructions and NaN definitions.

Signed-off-by: Michael Clark 
---
 fpu/softfloat-specialize.h |   7 +-
 target/riscv/fpu_helper.c  | 591 +
 2 files changed, 595 insertions(+), 3 deletions(-)
 create mode 100644 target/riscv/fpu_helper.c

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index de2c5d5..49ee578 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -114,7 +114,8 @@ float32 float32_default_nan(float_status *status)
 #if defined(TARGET_SPARC) || defined(TARGET_M68K)
 return const_float32(0x7FFF);
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
-  defined(TARGET_XTENSA) || defined(TARGET_S390X) || 
defined(TARGET_TRICORE)
+  defined(TARGET_XTENSA) || defined(TARGET_S390X) || \
+  defined(TARGET_TRICORE) || defined(TARGET_RISCV)
 return const_float32(0x7FC0);
 #elif defined(TARGET_HPPA)
 return const_float32(0x7FA0);
@@ -139,7 +140,7 @@ float64 float64_default_nan(float_status *status)
 #if defined(TARGET_SPARC) || defined(TARGET_M68K)
 return const_float64(LIT64(0x7FFF));
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
-  defined(TARGET_S390X)
+  defined(TARGET_S390X) || defined(TARGET_RISCV)
 return const_float64(LIT64(0x7FF8));
 #elif defined(TARGET_HPPA)
 return const_float64(LIT64(0x7FF4));
@@ -189,7 +190,7 @@ float128 float128_default_nan(float_status *status)
 r.high = LIT64(0x7FFF7FFF);
 } else {
 r.low = LIT64(0x);
-#if defined(TARGET_S390X) || defined(TARGET_PPC)
+#if defined(TARGET_S390X) || defined(TARGET_PPC) || defined(TARGET_RISCV)
 r.high = LIT64(0x7FFF8000);
 #else
 r.high = LIT64(0x8000);
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
new file mode 100644
index 000..ada985f
--- /dev/null
+++ b/target/riscv/fpu_helper.c
@@ -0,0 +1,591 @@
+/*
+ * RISC-V FPU Emulation Helpers for QEMU.
+ *
+ * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "cpu.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+
+/* convert RISC-V rounding mode to IEEE library numbers */
+unsigned int ieee_rm[] = {
+float_round_nearest_even,
+float_round_to_zero,
+float_round_down,
+float_round_up,
+float_round_ties_away
+};
+
+/* obtain rm value to use in computation
+ * as the last step, convert rm codes to what the softfloat library expects
+ * Adapted from Spike's decode.h:RM
+ */
+#define RM ({ \
+if (rm == 7) {\
+rm = env->frm;   \
+} \
+if (rm > 4) { \
+helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
+} \
+ieee_rm[rm]; })
+
+#ifndef CONFIG_USER_ONLY
+#define require_fp if (!(env->mstatus & MSTATUS_FS)) { \
+helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
+}
+#else
+#define require_fp /* nop */
+#endif
+
+/* convert softfloat library flag numbers to RISC-V */
+unsigned int softfloat_flags_to_riscv(unsigned int flags)
+{
+int rv_flags = 0;
+rv_flags |= (flags & float_flag_inexact) ? 1 : 0;
+rv_flags |= (flags & float_flag_underflow) ? 2 : 0;
+rv_flags |= (flags & float_flag_overflow) ? 4 : 0;
+rv_flags |= (flags & float_flag_divbyzero) ? 8 : 0;
+rv_flags |= (flags & float_flag_invalid) ? 16 : 0;
+return rv_flags;
+}
+
+/* adapted from Spike's decode.h:set_fp_exceptions */
+#define set_fp_exceptions() do { \
+env->fflags |= softfloat_flags_to_riscv(get_float_exception_flags(\
+>fp_status)); \
+set_float_exception_flags(0, >fp_status); \
+} while (0)
+
+uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+uint64_t frs3, uint64_t rm)
+{
+require_fp;
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_muladd(frs1, frs2, frs3, 0, >fp_status);
+

[Qemu-devel] [PATCH v1 07/21] RISC-V GDB Stub

2018-01-02 Thread Michael Clark
GDB Register read and write routines.

Signed-off-by: Michael Clark 
---
 target/riscv/gdbstub.c | 59 ++
 1 file changed, 59 insertions(+)
 create mode 100644 target/riscv/gdbstub.c

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
new file mode 100644
index 000..12d1d9f
--- /dev/null
+++ b/target/riscv/gdbstub.c
@@ -0,0 +1,59 @@
+/*
+ * RISC-V GDB Server Stub
+ *
+ * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+#include "cpu.h"
+
+int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+/* TODO proper x0 handling */
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+
+if (n < 32) {
+return gdb_get_regl(mem_buf, env->gpr[n]);
+} else if (n == 32) {
+return gdb_get_regl(mem_buf, env->pc);
+} else if (n < 65) {
+return gdb_get_reg64(mem_buf, env->fpr[n - 33]);
+}
+return 0;
+}
+
+int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+/* TODO proper x0 handling */
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+
+if (n < 32) {
+env->gpr[n] = ldtul_p(mem_buf);
+return sizeof(target_ulong);
+} else if (n == 32) {
+env->pc = ldtul_p(mem_buf);
+return sizeof(target_ulong);
+} else if (n < 65) {
+env->fpr[n - 33] = ldq_p(mem_buf); /* always 64-bit */
+return sizeof(uint64_t);
+}
+return 0;
+}
-- 
2.7.0




[Qemu-devel] [PATCH v1 10/21] RISC-V Linux User Emulation

2018-01-02 Thread Michael Clark
Implementation of linux user emulation for RISC-V.

Signed-off-by: Michael Clark 
---
 linux-user/elfload.c  |  22 +++
 linux-user/main.c | 130 -
 linux-user/riscv/syscall_nr.h | 275 +++
 linux-user/riscv/target_cpu.h |  18 +++
 linux-user/riscv/target_signal.h  |  23 +++
 linux-user/riscv/target_structs.h |  46 ++
 linux-user/riscv/target_syscall.h |  56 
 linux-user/riscv/termbits.h   | 220 
 linux-user/signal.c   | 260 ++
 linux-user/syscall.c  |   2 +
 linux-user/syscall_defs.h |  13 +-
 target/riscv/cpu_user.h   |  29 
 target/riscv/user_atomic.c| 291 ++
 target/riscv/user_syscall.c   |  40 ++
 14 files changed, 1387 insertions(+), 38 deletions(-)
 create mode 100644 linux-user/riscv/syscall_nr.h
 create mode 100644 linux-user/riscv/target_cpu.h
 create mode 100644 linux-user/riscv/target_signal.h
 create mode 100644 linux-user/riscv/target_structs.h
 create mode 100644 linux-user/riscv/target_syscall.h
 create mode 100644 linux-user/riscv/termbits.h
 create mode 100644 target/riscv/cpu_user.h
 create mode 100644 target/riscv/user_atomic.c
 create mode 100644 target/riscv/user_syscall.c

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 20f3d8c..178af56 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1272,6 +1272,28 @@ static inline void init_thread(struct target_pt_regs 
*regs,
 
 #endif /* TARGET_TILEGX */
 
+#ifdef TARGET_RISCV
+
+#define ELF_START_MMAP 0x8000
+#define ELF_ARCH  EM_RISCV
+
+#ifdef TARGET_RISCV32
+#define ELF_CLASS ELFCLASS32
+#else
+#define ELF_CLASS ELFCLASS64
+#endif
+
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->sepc = infop->entry;
+regs->sp = infop->start_stack;
+}
+
+#define ELF_EXEC_PAGESIZE 4096
+
+#endif /* TARGET_RISCV */
+
 #ifdef TARGET_HPPA
 
 #define ELF_START_MMAP  0x8000
diff --git a/linux-user/main.c b/linux-user/main.c
index 71696ed..8900141 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -227,7 +227,7 @@ void cpu_loop(CPUX86State *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case 0x80:
 /* linux syscall from int $0x80 */
 ret = do_syscall(env,
@@ -585,7 +585,7 @@ void cpu_loop(CPUARMState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_UDEF:
 case EXCP_NOCP:
 case EXCP_INVSTATE:
@@ -1379,7 +1379,7 @@ void cpu_loop(CPUPPCState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case POWERPC_EXCP_NONE:
 /* Just go on */
 break;
@@ -2251,7 +2251,7 @@ void cpu_loop(CPUMIPSState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_SYSCALL:
 env->active_tc.PC += 4;
 # ifdef TARGET_ABI_MIPSO32
@@ -2957,7 +2957,7 @@ void cpu_loop(CPUM68KState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-switch(trapnr) {
+switch (trapnr) {
 case EXCP_ILLEGAL:
 {
 if (ts->sim_syscalls) {
@@ -3640,6 +3640,121 @@ void cpu_loop(CPUTLGState *env)
 
 #endif
 
+#ifdef TARGET_RISCV
+
+void cpu_loop(CPURISCVState *env)
+{
+CPUState *cs = CPU(riscv_env_get_cpu(env));
+int trapnr, signum, sigcode;
+target_ulong sigaddr;
+target_ulong ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+
+signum = 0;
+sigcode = 0;
+sigaddr = 0;
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case RISCV_EXCP_U_ECALL:
+env->pc += 4;
+if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
+/* kernel-assisted AMO not suitable for do_syscall */
+start_exclusive();
+ret = riscv_flush_icache_syscall(env,
+ env->gpr[xA7],
+ env->gpr[xA0],
+ env->gpr[xA1],
+ env->gpr[xA2],
+ env->gpr[xA3]);
+end_exclusive();
+} else {
+ret = do_syscall(env,
+ env->gpr[xA7],
+ env->gpr[xA0],
+ env->gpr[xA1],
+ 

[Qemu-devel] [PATCH v1 05/21] RISC-V CPU Helpers

2018-01-02 Thread Michael Clark
Privileged control and status register helpers and page fault handling.

Signed-off-by: Michael Clark 
---
 target/riscv/helper.c| 494 +
 target/riscv/helper.h|  78 ++
 target/riscv/op_helper.c | 707 +++
 3 files changed, 1279 insertions(+)
 create mode 100644 target/riscv/helper.c
 create mode 100644 target/riscv/helper.h
 create mode 100644 target/riscv/op_helper.c

diff --git a/target/riscv/helper.c b/target/riscv/helper.c
new file mode 100644
index 000..34da7dd
--- /dev/null
+++ b/target/riscv/helper.c
@@ -0,0 +1,494 @@
+/*
+ *  RISC-V emulation helpers for qemu.
+ *
+ *  Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+
+/*#define RISCV_DEBUG_INTERRUPT */
+
+bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+#if !defined(CONFIG_USER_ONLY)
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+int interruptno = cpu_riscv_hw_interrupts_pending(env);
+if (interruptno + 1) {
+cs->exception_index = 0x7000U | interruptno;
+riscv_cpu_do_interrupt(cs);
+return true;
+}
+}
+#endif
+return false;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+
+/* get_physical_address - get the physical address for this virtual address
+ *
+ * Do a page table walk to obtain the physical address corresponding to a
+ * virtual address. Returns 0 if the translation was successful
+ *
+ * Adapted from Spike's mmu_t::translate and mmu_t::walk
+ *
+ */
+static int get_physical_address(CPURISCVState *env, hwaddr *physical,
+int *prot, target_ulong address,
+int access_type, int mmu_idx)
+{
+/* NOTE: the env->pc value visible here will not be
+ * correct, but the value visible to the exception handler
+ * (riscv_cpu_do_interrupt) is correct */
+
+*prot = 0;
+CPUState *cs = CPU(riscv_env_get_cpu(env));
+
+target_ulong mode = env->priv;
+if (access_type != MMU_INST_FETCH) {
+if (get_field(env->mstatus, MSTATUS_MPRV)) {
+mode = get_field(env->mstatus, MSTATUS_MPP);
+}
+}
+if (env->priv_ver >= PRIV_VERSION_1_10_0) {
+if (get_field(env->satp, SATP_MODE) == VM_1_09_MBARE) {
+mode = PRV_M;
+}
+} else {
+if (get_field(env->mstatus, MSTATUS_VM) == VM_1_10_MBARE) {
+mode = PRV_M;
+}
+}
+
+/* check to make sure that mmu_idx and mode that we get matches */
+if (unlikely(mode != mmu_idx)) {
+fprintf(stderr, "MODE: mmu_idx mismatch\n");
+exit(1);
+}
+
+if (mode == PRV_M) {
+target_ulong msb_mask = /*0x7FFF; */
+(((target_ulong)2) << (TARGET_LONG_BITS - 1)) - 1;
+*physical = address & msb_mask;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+return TRANSLATE_SUCCESS;
+}
+
+target_ulong addr = address;
+target_ulong base;
+
+int levels, ptidxbits, ptesize, vm, sum;
+int mxr = get_field(env->mstatus, MSTATUS_MXR);
+
+if (env->priv_ver >= PRIV_VERSION_1_10_0) {
+base = get_field(env->satp, SATP_PPN) << PGSHIFT;
+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;
+case VM_1_10_SV39:
+  levels = 3; ptidxbits = 9; ptesize = 8; break;
+case VM_1_10_SV48:
+  levels = 4; ptidxbits = 9; ptesize = 8; break;
+case VM_1_10_SV57:
+  levels = 5; ptidxbits = 9; ptesize = 8; break;
+default:
+  printf("unsupported SATP_MODE value\n");
+  exit(1);
+}
+} else {
+base = env->sptbr << PGSHIFT;
+sum = !get_field(env->mstatus, MSTATUS_PUM);
+vm = get_field(env->mstatus, MSTATUS_VM);
+switch (vm) {
+case VM_1_09_SV32:
+  levels = 2; ptidxbits = 10; ptesize = 4; break;
+case VM_1_09_SV39:
+  levels = 3; ptidxbits = 9; ptesize = 8; 

[Qemu-devel] [PATCH v1 01/21] RISC-V Maintainers

2018-01-02 Thread Michael Clark
Add Michael Clark, Sagar Karandikar and Bastian Koppelmann as
RISC-V Maintainers.

Signed-off-by: Michael Clark 
---
 MAINTAINERS | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 73a..09a1314 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -209,6 +209,16 @@ F: hw/ppc/
 F: include/hw/ppc/
 F: disas/ppc.c
 
+RISC-V
+M: Michael Clark 
+M: Sagar Karandikar 
+M: Bastian Koppelmann 
+S: Maintained
+F: target/riscv/
+F: hw/riscv/
+F: include/hw/riscv/
+F: disas/riscv.c
+
 S390
 M: Richard Henderson 
 M: Alexander Graf 
-- 
2.7.0




[Qemu-devel] [PATCH v1 03/21] RISC-V CPU Core Definition

2018-01-02 Thread Michael Clark
Add CPU state header, CPU definitions and initialization routines

Signed-off-by: Michael Clark 
---
 target/riscv/cpu.c  | 338 +++
 target/riscv/cpu.h  | 363 ++
 target/riscv/cpu_bits.h | 411 
 3 files changed, 1112 insertions(+)
 create mode 100644 target/riscv/cpu.c
 create mode 100644 target/riscv/cpu.h
 create mode 100644 target/riscv/cpu_bits.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
new file mode 100644
index 000..ee4c4c2
--- /dev/null
+++ b/target/riscv/cpu.c
@@ -0,0 +1,338 @@
+/*
+ * QEMU RISC-V CPU
+ *
+ * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+
+/* RISC-V CPU definitions */
+
+typedef struct RISCVCPUInfo {
+const char *name;
+void (*initfn)(Object *obj);
+} RISCVCPUInfo;
+
+#ifdef CONFIG_USER_ONLY
+static void riscv_any_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+env->misa = RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU;
+env->misa_mask = env->misa;
+env->user_ver = USER_VERSION_2_02_0;
+env->priv_ver = PRIV_VERSION_1_10_0;
+}
+#else
+static void riscv_imafdcsu_priv1_9_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+env->misa = RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU;
+env->misa_mask = env->misa;
+env->user_ver = USER_VERSION_2_02_0;
+env->priv_ver = PRIV_VERSION_1_09_1;
+}
+
+static void riscv_imafdcsu_priv1_10_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+env->misa = RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU;
+env->misa_mask = env->misa;
+env->user_ver = USER_VERSION_2_02_0;
+env->priv_ver = PRIV_VERSION_1_10_0;
+}
+
+static void riscv_imacu_priv1_10_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+env->misa = RVXLEN | RVI | RVM | RVA | RVC | RVU;
+env->misa_mask = env->misa;
+env->user_ver = USER_VERSION_2_02_0;
+env->priv_ver = PRIV_VERSION_1_10_0;
+}
+
+static void riscv_imac_priv1_10_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+env->misa = RVXLEN | RVI | RVM | RVA | RVC;
+env->misa_mask = env->misa;
+env->user_ver = USER_VERSION_2_02_0;
+env->priv_ver = PRIV_VERSION_1_10_0;
+}
+#endif
+
+static const RISCVCPUInfo riscv_cpus[] = {
+#ifdef CONFIG_USER_ONLY
+{ TYPE_RISCV_CPU_ANY,riscv_any_cpu_init },
+#else
+{ TYPE_RISCV_CPU_IMAFDCSU_PRIV_1_09, riscv_imafdcsu_priv1_9_cpu_init },
+{ TYPE_RISCV_CPU_IMAFDCSU_PRIV_1_10, riscv_imafdcsu_priv1_10_cpu_init },
+{ TYPE_RISCV_CPU_IMACU_PRIV_1_10,riscv_imacu_priv1_10_cpu_init },
+{ TYPE_RISCV_CPU_IMAC_PRIV_1_10, riscv_imac_priv1_10_cpu_init },
+#endif
+{ NULL, NULL }
+};
+
+static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
+{
+ObjectClass *oc;
+char *typename;
+char **cpuname;
+
+cpuname = g_strsplit(cpu_model, ",", 1);
+typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
+oc = object_class_by_name(typename);
+g_strfreev(cpuname);
+g_free(typename);
+if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) ||
+object_class_is_abstract(oc)) {
+return NULL;
+}
+return oc;
+}
+
+static inline void set_feature(CPURISCVState *env, int feature)
+{
+env->features |= 1ULL << feature;
+}
+
+static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+env->pc = value;
+}
+
+static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+env->pc = tb->pc;
+}
+
+#ifdef CONFIG_USER_ONLY
+static bool riscv_cpu_has_work(CPUState *cs)
+{
+return 0;
+}
+#else
+static bool riscv_cpu_has_work(CPUState *cs)
+{
+return cs->interrupt_request & CPU_INTERRUPT_HARD;
+}
+#endif
+
+void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
+  target_ulong *data)
+{
+env->pc = data[0];
+}
+

[Qemu-devel] [PATCH v1 00/21] RISC-V QEMU Port Submission v1

2018-01-02 Thread Michael Clark
QEMU RISC-V Emulation Support (RV64GC, RV32GC)

*** Background ***

"RISC-V is an open, free ISA enabling a new era of processor innovation
through open standard collaboration. Born in academia and research,
RISC-V ISA delivers a new level of free, extensible software and
hardware freedom on architecture, paving the way for the next 50 years
of computing design and innovation."

The QEMU RISC-V port has been developed and maintained out-of-tree for
several years by Sagar Karandikar and Bastian Koppelmann. The RISC-V
Privileged specification has evolved substantially over this period but
has recently been solidifying. The RISC-V Base ISA has been frozon for
some time and the Privileged ISA, GCC toolchain and Linux ABI are now
quite stable. I have recently joined Sagar and Bastian as a RISC-V QEMU
Maintainer and hope to support upstreaming the port. 

There are multiple vendors taping out, preparing to ship, or shipping
silicon that implements the RISC-V Privileged ISA Version 1.10. There
are also several RISC-V Soft-IP cores implementing Privileged ISA
Version 1.10 that run on FPGA such as SiFive's Freedom U500 Platform
and the U54‑MC RISC-V Core IP, among many more implementations from a
variety of vendors. See https://riscv.org/ for more details.

RISC-V support was upstreamed in binutils 2.28 and GCC 7.1 in the first
half of 2016. RISC-V support is now available in LLVM top-of-tree and
the RISC-V Linux port was accepted into Linux 4.15-rc1 late last year
and will be available in the upcoming Linux 4.15 release. RISC-V GLIBC
patches are currently under review and it is hoped that RISC-V support
will be added in the GLIBC 2.27 release.  We believe it is timely to
submit the RISC-V QEMU port for upstream review with the goal of
incorporating RISC-V support into the upcoming QEMU 2.12 release.

The RISC-V QEMU port is still under active development, mostly with
respect to device emulation, the addition of Hypervisor support as
specified in the RISC-V Draft Privileged ISA Version 1.11, and Vector
support once the first draft is finalized later this year. We believe
now is the appropriate time for RISC-V QEMU development to be carried
out in the main QEMU repository as the code will benefit from more
rigorous review. The RISC-V QEMU port currently supports all the ISA
extensions that have been finalized and frozen in the Base ISA.

Blog post about recent additions to RISC-V QEMU: https://goo.gl/fJ4zgk

The RISC-V QEMU wiki: https://github.com/riscv/riscv-qemu/wiki

Instructions for building a busybox+dropbear root image, BBL (Berkeley
Boot Loader) and linux kernel image for use with the RISC-V QEMU
'virt' machine: https://github.com/michaeljclark/busybear-linux

The git tree for the v1 patch submission:

- https://github.com/riscv/riscv-qemu/tree/qemu-upstream-v1

*** Overview ***

The RISC-V QEMU port implements the following specifications:

- RISC-V Instruction Set Manual Volume I: User-Level ISA Version 2.2
- RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.9.1
- RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.10

The RISC-V QEMU port supports the following instruction set extensions:

- RV32GC with Supervisor-mode and User-mode (RV32IMAFDCSU)
- RV64GC with Supervisor-mode and User-mode (RV64IMAFDCSU)

The RISC-V QEMU port adds the following targets to QEMU:

- riscv32-softmmu
- riscv64-softmmu
- riscv32-linux-user
- riscv64-linux-user

The RISC-V QEMU port supports the following hardware:

- HTIF Console (Host Target Interface)
- SiFive CLINT (Core Local Interruptor) for Timer interrupts and IPIs
- SiFive PLIC (Platform Level Interrupt Controller)
- SiFive UART, PRCI, AON, PWM, QSPI support is partially implemented
- VirtIO MMIO (GPEX PCI support will be added in a future patch)
- Generic 16550A UART emulation using 'hw/char/serial.c'
- Experimental SMP support (PLIC and CLINT) on the 'virt' machine

The RISC-V QEMU full system emulator supports 5 machines:

- 'spike_v1.9';  CLINT, PLIC, HTIF console, config-string, Priv v1.9.1
- 'spike_v1.10'; CLINT, PLIC, HTIF console, device-tree, Priv v1.10
- 'virt'; CLINT, PLIC, 16550A UART, VirtIO, device-tree, Priv v1.10
- 'sifive_e300'; CLINT, PLIC, SiFive UART, HiFive1 compat, Priv v1.10
- 'sifive_u500'; CLINT, PLIC, SiFive UART, device-tree, Priv v1.10

This is a list of RISC-V QEMU Port Contributors:

- Alex Suykov
- Antony Pavlov
- Bastian Koppelmann
- Bruce Hoult
- Chih-Min Chao
- Daire McNamara
- David Abdurachmanov
- Ivan Griffin
- Kito Cheng
- Michael Clark
- Palmer Dabbelt
- Sagar Karandikar
- Stefan O'Rear

Notes:

- contributor email addresses available off-list on request.
- checkpatch has been run on all 21 patches.
- checkpatch exceptions are noted in 2 patches that have errors.
- tested linux on 'spike_v1.9', 'spike_v1.10' and 'virt' machines
- passes "make check" on full build for all targets

This patch series includes the following patches:

Michael Clark (21):
  RISC-V Maintainers
  RISC-V ELF Machine 

[Qemu-devel] [PATCH v1 02/21] RISC-V ELF Machine Definition

2018-01-02 Thread Michael Clark
Define RISC-V ELF machine EM_RISCV 243

Signed-off-by: Michael Clark 
---
 include/elf.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index e8a515c..8e457fc 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -112,6 +112,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_UNICORE32110 /* UniCore32 */
 
+#define EM_RISCV243 /* RISC-V */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
-- 
2.7.0




Re: [Qemu-devel] [RESEND PATCH 2/6] memory: introduce AddressSpaceOps and IOMMUObject

2018-01-02 Thread David Gibson
On Thu, Dec 21, 2017 at 04:40:19PM +0800, Liu, Yi L wrote:
> On Wed, Dec 20, 2017 at 10:18:16PM +1100, David Gibson wrote:
> > On Wed, Dec 20, 2017 at 02:47:30PM +0800, Liu, Yi L wrote:
> > > On Mon, Dec 18, 2017 at 10:35:31PM +1100, David Gibson wrote:
> > > > On Wed, Nov 15, 2017 at 03:16:32PM +0800, Peter Xu wrote:
> > > > > On Tue, Nov 14, 2017 at 10:52:54PM +0100, Auger Eric wrote:
> > > > > 
> > > > > 
> [...]
> > > > So, having read and thought a bunch more, I think I know where you
> > > > need to start hooking this in.  The thing is the current qemu PCI DMA
> > > > structure assumes that each device belongs to just a single PCI
> > > > address space - that's what pci_device_iommu_address_space() returns.
> > > > 
> > > > For virt-SVM that's just not true.  IIUC, a virt-SVM capable device
> > > > could simultaneously write to multiple process address spaces, since
> > > > the process IDs actually go over the bus.
> > > 
> > > Correct.
> > > 
> > > > So trying to hook notifiers at the AddressSpace OR MemoryRegion level
> > > > just doesn't make sense - if we've picked a single addresss space for
> > > > the device, we've already made a wrong step.
> > > 
> > > That's also why we want to have notifiers based on IOMMUObject(may be
> > > not a suitable name, let me use it as the patch named).
> > 
> > Right, I think "IOMMUObject" is a misleading name.
> > 
> > > > Instead what you need I think is something like:
> > > > pci_device_virtsvm_context().  virt-SVM capable devices would need to
> > > > call that *before* calling pci_device_iommu_address_space ().  Well
> > > > rather the virt-SVM capable DMA helpers would need to call that.
> > > > 
> > > > That would return a new VirtSVMContext (or something) object, which
> > > > would roughly correspond to a single PASID table.  That's where the
> > > > methods and notifiers for managing that would need to go.
> > > 
> > > Correct, pci_device_iommu_address_space() returns an AS and it is
> > > a PCI address space. And if pci_device_virtsvm_context() is also
> > > called in vfio_realize(), it may not return an AS since there may
> > > be no 1st level translation page table bound.
> > > 
> > > So as you said, return a new VirtSVMContext, this VirtSVMContext can
> > > hook some new notifiers. I think the IOMMUObject introduced in this patch
> > > can meet the requirement. But it may be re-named.
> > 
> > Ok.
> > 
> > > So here it addressed the concern you raised before which is hook 
> > > IOMMUObject
> > > via a PCI address space. Regards to VirtSVMContext, it may be a 
> > > replacement
> > > of IOMMUObject. As it is related to PASID, I'm considering to name it as
> > > IOMMUPasidContext or IOMMUPasidObject. So it would be an abstraction of 
> > > all
> > > the IOMMU PASID related operations.
> > 
> > I'm ok with calling it a "PASID context".
> > 
> > Thinking about this some more, here are some extra observations:
> > 
> >  * I think each device needs both a PASID context and an ordinary
> >address space.  The PASID context would be used for bus
> >transactions which include a process id, the address space for
> >those that don't.
> 
> Correct. Also virt-SVM still needs the PCI Address space. And the PCI
> Address space == Guest physical Address space.

Not necessarily.  That's true if you're only making the L1 translation
guest visible.  But I think we need to at least think about the case
where both L1 and L2 translations are guest visible, in which case the
PCI address space is not the same as the guest physical address space.

> For virt-SVM, requires
> pt mode to ensure the nested translation.

What is pt mode?

> >  * Theoretically, the PASID context could be modelled as an array/map
> >of AddressSpace objects for each process ID.  However, creating all
> 
> I also thought about creating AddressSpace objects for each process ID.
> But I don't think we need to do it. My reason as below:
> 
> In theory, it is correct to have AddressSpace object for each process
> virtual address space in Qemu, and this is what we are doing for PCI
> address space so far. However, this is necessary when we want to mirror
> the mapping to host. Each time there is mapping changed within the PCI
> address space, we need to mirror it to host.
> 
> While for virt-SVM, we don't need to mirror the changes within the guest
> process address space. The nested translation capability in HW brings us
> a convenience. In nested translation, HW can access a guest PASID table
> with a GPA(this is what Intel and AMD does, not sure about ARM, maybe or
> maybe not). For VT-d and AMD-IOMMU, even any change in guest PASID table,
> it is not necessary to mirror it to host. Based on the statements above,
> there is a candidate function to be included in PASIDContext. It could be
> bind_guest_pasid_table(). And be used to set the guest PASID Table to host
> translation structure when guest finds a device is has SVM
> capability.

That's true for passthrough devices, but not 

Re: [Qemu-devel] [PATCH qemu v3] RFC: ppc/spapr: Receive and store device tree blob from SLOF

2018-01-02 Thread David Gibson
On Tue, Jan 02, 2018 at 05:13:09PM +1100, Alexey Kardashevskiy wrote:
> On 11/12/17 17:20, Alexey Kardashevskiy wrote:
> > On 09/11/17 17:38, David Gibson wrote:
> >> On Tue, Nov 07, 2017 at 06:14:04PM +1100, Alexey Kardashevskiy wrote:
> >>> On 20/10/17 11:46, Alexey Kardashevskiy wrote:
>  On 19/10/17 17:24, David Gibson wrote:
> > On Tue, Oct 17, 2017 at 04:55:03PM +1100, Alexey Kardashevskiy wrote:
> >> On 16/10/17 20:36, David Gibson wrote:
> >>> On Mon, Oct 16, 2017 at 04:20:04PM +1100, Alexey Kardashevskiy
> >> wrote:
> > [snip]
> >>> ||
> >>>
> >>> Yeah.. this is all a bit complicated, I'm really thinking about a
> >>> fdt_fsck() function for libfdt.
> >>
> >>
> >> Oh. So what now? Do as below or wait for libdtc update?
> >
> > So I started hacking on this.  It's a bit fiddlier to get right than I
> > anticipated.  How about you make a placeholder function to "test" the
> > tree for now, with a comment that it will be updated once the libfdt
> > extensions are there.
> 
>  What would the placeholder do? Nothing or my proposed "FDT_CHK" thingy?
> 
>  Are we in a hurry with this one at all, or I can wait till libfdt gets 
>  this
>  fsck()?
> >>>
> >>>
> >>> Ping?
> >>>
> >>> This is not v2.11 material, is it?
> >>
> >> Not at this stage, no.
> >>
> >> I've started looking at writing the fdt_fsck() thing, but got
> >> sidetracked by a bunch of related fixes to safety of handling
> >> corrupted blobs in libfdt.
> > 
> > Please let me know when I can repost the "
> > ppc/spapr: Receive and store device tree blob from SLOF" again. Thanks.
> 
> 
> Still to early to repost?

No.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 00/42] SDHCI: housekeeping, add a qtest and fix few issues

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:48 AM, Philippe Mathieu-Daudé  wrote:
> Since v2:
> - more detailed 'capabilities', all boards converted to use these properties
> - since all qtests pass, removed the previous 'capareg' property
> - added Stefan/Alistair R-b
> - corrected 'access' LED behavior (Alistair's review)
> - more uses of the registerfields API
> - remove some dead code
> - cosmetix:
>   - added more comments
>   - renamed a pair of registers
>   - reordered few struct members
>
> Note, the bcm2835 seems to have 1KB minimum blocksize, however the current
> model is implemented with 512B. I didn't change the current value.
>
> Since v1:
> - addressed Alistair Francis review comments, added some R-b
> - only move register defines to "sd-internal.h"
> - fixed deposit64() arguments
> - dropped unuseful s->fifo_buffer = NULL
> - use a qemu_irq for the LED, restrict the logging to ON/OFF
> - fixed a trace format string error
> - included Andrey Smirnov ACMD12ERRSTS write patch
> - dropped few unuseful patches, and separate the Python polemical ones for 
> later
>
> From the "SDHCI housekeeping" series:
> - 1: we restrict part of "sd/sd.h" into local "sd-internal.h",
> - 2,3: we somehow beautiful the code, no logical changes,
> - 4-7: we refactor the common sysbus/pci qdev code,
> - 8-10: we add plenty of trace events which will result useful later,
> - 11: we finally expose a "dma-memory" property.
> From the "SDHCI: add a qtest and fix few issues" series:
> - 12,13: fix registers
> - 14,15: boards can specify which SDHCI Spec to use (v2 and v3 so far)
> - 15-20: HCI qtest
>
> Regards,
>
> Phil.
>
> $ git backport-diff
> [] : patches are identical
> [] : number of functional differences between upstream/downstream patch
> [down] : patch is downstream-only
> The flags [FC] indicate (F)unctional and (C)ontextual differences, 
> respectively
>
> 001/42:[0003] [FC] 'sdhci: clean up includes'
> 002/42:[down] 'sdhci: sort registers comments'
> 003/42:[down] 'sdhci: remove dead code'
> 004/42:[] [--] 'sdhci: refactor same sysbus/pci properties'
> 005/42:[] [--] 'sdhci: refactor common sysbus/pci class_init()'
> 006/42:[] [--] 'sdhci: refactor common sysbus/pci realize()'
> 007/42:[0001] [FC] 'sdhci: refactor common sysbus/pci unrealize()'
> 008/42:[] [--] 'sdhci: use qemu_log_mask(UNIMP) instead of fprintf()'
> 009/42:[] [--] 'sdhci: convert the DPRINT() calls into trace events'
> 010/42:[down] 'sdhci: add a GPIO for the 'access control' LED'
> 011/42:[] [--] 'sdhci: move MASK_TRNMOD with other SDHC_TRN* defines'
> 012/42:[down] 'sdhci: use FIELD_DP32() macro for the WRITE_PROTECT flag'
> 013/42:[down] 'sdhci: rename the SDHC_CAPAB register'
> 014/42:[0008] [FC] 'sdhci: fix CAPAB/MAXCURR registers, 64bit and read-only'
> 015/42:[] [-C] 'sdhci: Implement write method of ACMD12ERRSTS register'
> 016/42:[down] 'sdhci: use deposit64() on admasysaddr'
> 017/42:[] [-C] 'sdhci: add a "dma-memory" property'
> 018/42:[down] 'sdhci: add a spec_version property'
> 019/42:[down] 'sdhci: add basic Spec v1 capabilities'
> 020/42:[down] 'sdhci: add max-block-length capability (Spec v1)'
> 021/42:[down] 'sdhci: add clock capabilities (Spec v1)'
> 022/42:[down] 'sdhci: add DMA and 64-bit capabilities (Spec v2)'
> 023/42:[down] 'sdhci: default to Spec v2'
> 024/42:[down] 'sdhci: add a 'dma' shortcut property'
> 025/42:[down] 'sdhci: add BLOCK_SIZE_MASK for DMA'
> 026/42:[down] 'sdhci: Fix 64-bit ADMA2'
> 027/42:[down] 'hw/arm/exynos4210: implement SDHCI Spec v2'
> 028/42:[down] 'hw/arm/xilinx_zynq: implement SDHCI Spec v2'
> 029/42:[0022] [FC] 'sdhci: add qtest to check the SD Spec version'
> 030/42:[down] 'sdhci: check Spec v2 capabilities qtest'
> 031/42:[down] 'sdhci: add v3 capabilities'
> 032/42:[down] 'sdhci: rename the hostctl1 register'
> 033/42:[down] 'hw/arm/bcm2835_peripherals: implement SDHCI Spec v3'
> 034/42:[down] 'hw/arm/fsl-imx6: implement SDHCI Spec v3'
> 035/42:[down] 'hw/arm/xilinx_zynqmp: implement SDHCI Spec v3'
> 036/42:[down] 'sdhci: check Spec v3 capabilities qtest'
> 037/42:[down] 'sdhci: remove the deprecated 'capareg' property'
> 038/42:[0008] [FC] 'sdhci: add check_capab_readonly() qtest'
> 039/42:[0009] [FC] 'sdhci: add a check_capab_baseclock() qtest'
> 040/42:[0011] [FC] 'sdhci: add a check_capab_sdma() qtest'
> 041/42:[] [-C] 'sdhci: add a check_capab_v3() qtest'
> 042/42:[down] 'sdhci: add Spec v4.2 register definitions'

We are making progress here. Do you think it would be worth splitting
out the earlier patches that have been reviewed so far so they can be
merged? A 42 patch series it pretty daunting and most of the first 20
are pretty straightforward and have been reviewed.

Alistair

>
> Andrey Smirnov (1):
>   sdhci: Implement write method of ACMD12ERRSTS register
>
> Philippe Mathieu-Daudé (40):
>   sdhci: clean up includes
>   sdhci: sort registers comments
>   sdhci: remove dead code
>   sdhci: refactor same sysbus/pci properties 

Re: [Qemu-devel] [PATCH v3 13/42] sdhci: rename the SDHC_CAPAB register

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:49 AM, Philippe Mathieu-Daudé  wrote:
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/sd/sdhci-internal.h | 2 +-
>  hw/sd/sdhci.c  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
> index df240ea046..b7475a1b7b 100644
> --- a/hw/sd/sdhci-internal.h
> +++ b/hw/sd/sdhci-internal.h
> @@ -176,7 +176,7 @@ FIELD(SDHC_PRNSTS, WRITE_PROTECT,  19, 1);
>  #define SDHC_ACMD12ERRSTS  0x3C
>
>  /* HWInit Capabilities Register 0x05E80080 */
> -#define SDHC_CAPAREG   0x40
> +#define SDHC_CAPAB 0x40
>  #define SDHC_CAN_DO_DMA0x0040
>  #define SDHC_CAN_DO_ADMA2  0x0008
>  #define SDHC_CAN_DO_ADMA1  0x0010
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index b5ecbc9969..604ad525f6 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -903,7 +903,7 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, 
> unsigned size)
>  case SDHC_ACMD12ERRSTS:
>  ret = s->acmd12errsts;
>  break;
> -case SDHC_CAPAREG:
> +case SDHC_CAPAB:
>  ret = s->capareg;
>  break;
>  case SDHC_MAXCURR:
> --
> 2.15.1
>
>



Re: [Qemu-devel] [PATCH v3 14/42] sdhci: fix CAPAB/MAXCURR registers, both are 64bit and read-only

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:49 AM, Philippe Mathieu-Daudé  wrote:
> running qtests:
>
>   $ make check-qtest-arm
> GTESTER check-qtest-arm
>   SDHC rd_4b @0x44 not implemented
>   SDHC wr_4b @0x40 <- 0x89abcdef not implemented
>   SDHC wr_4b @0x44 <- 0x01234567 not implemented
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/hw/sd/sdhci.h |  4 ++--
>  hw/sd/sdhci.c | 23 +++
>  2 files changed, 21 insertions(+), 6 deletions(-)
>
> diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> index da943a6562..9436375b1e 100644
> --- a/include/hw/sd/sdhci.h
> +++ b/include/hw/sd/sdhci.h
> @@ -86,9 +86,9 @@ typedef struct SDHCIState {
>
>  /* Read-only registers */
>  /* 0x40 */
> -uint32_t capareg;  /* Capabilities Register */
> +uint64_t capareg;  /* Capabilities Register */
>  /* 0x48 */
> -uint32_t maxcurr;  /* Maximum Current Capabilities Register */
> +uint64_t maxcurr;  /* Maximum Current Capabilities Register */
>
>  uint8_t  *fifo_buffer; /* SD host i/o FIFO buffer */
>  uint32_t buf_maxsz;
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index 604ad525f6..ae84af46da 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -904,10 +904,16 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, 
> unsigned size)
>  ret = s->acmd12errsts;
>  break;
>  case SDHC_CAPAB:
> -ret = s->capareg;
> +ret = (uint32_t)s->capareg;
> +break;
> +case SDHC_CAPAB + 4:
> +ret = (uint32_t)(s->capareg >> 32);
>  break;
>  case SDHC_MAXCURR:
> -ret = s->maxcurr;
> +ret = (uint32_t)s->maxcurr;
> +break;
> +case SDHC_MAXCURR + 4:
> +ret = (uint32_t)(s->maxcurr >> 32);
>  break;
>  case SDHC_ADMAERR:
>  ret =  s->admaerr;
> @@ -1129,6 +1135,15 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, 
> unsigned size)
>  }
>  sdhci_update_irq(s);
>  break;
> +
> +case SDHC_CAPAB:
> +case SDHC_CAPAB + 4:
> +case SDHC_MAXCURR:
> +case SDHC_MAXCURR + 4:
> +qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx
> +  " <- 0x%08x read-only\n", size, offset, value >> 
> shift);
> +break;
> +
>  default:
>  qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 
> 0x%08x "
>"not implemented\n", size, offset, value >> shift);
> @@ -1260,9 +1275,9 @@ const VMStateDescription sdhci_vmstate = {
>  /* Capabilities registers provide information on supported features of this
>   * specific host controller implementation */
>  static Property sdhci_properties[] = {
> -DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
> +DEFINE_PROP_UINT64("capareg", SDHCIState, capareg,
>  SDHC_CAPAB_REG_DEFAULT),
> -DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
> +DEFINE_PROP_UINT64("maxcurr", SDHCIState, maxcurr, 0),
>  DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, 
> pending_insert_quirk,
>   false),
>  DEFINE_PROP_END_OF_LIST(),
> --
> 2.15.1
>
>



Re: [Qemu-devel] [PATCH v3 10/42] sdhci: add a GPIO for the 'access control' LED

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:49 AM, Philippe Mathieu-Daudé  wrote:
> It blinks to caution the user not to remove the card while the SD card is
> being accessed.
> So far it only emit a trace event.

s/emit/emits/g

>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  include/hw/sd/sdhci.h |  2 ++
>  hw/sd/sdhci.c | 14 ++
>  hw/sd/trace-events|  1 +
>  3 files changed, 17 insertions(+)
>
> diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> index a6fe064f51..da943a6562 100644
> --- a/include/hw/sd/sdhci.h
> +++ b/include/hw/sd/sdhci.h
> @@ -45,6 +45,8 @@ typedef struct SDHCIState {
>  QEMUTimer *insert_timer;   /* timer for 'changing' sd card. */
>  QEMUTimer *transfer_timer;
>  qemu_irq irq;
> +qemu_irq access_led;
> +int access_led_level;
>
>  /* Registers cleared on reset */
>  /* 0x00 */
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index acd5aa1e19..4679a6d5ed 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -203,6 +203,16 @@ static void sdhci_poweron_reset(DeviceState *dev)
>  }
>  }
>
> +static void sdhci_led_handler(void *opaque, int line, int level)
> +{
> +SDHCIState *s = (SDHCIState *)opaque;
> +
> +if (s->access_led_level != level) {
> +trace_sdhci_led(level);
> +s->access_led_level = level;
> +}
> +}
> +
>  static void sdhci_data_transfer(void *opaque);
>
>  static void sdhci_send_command(SDHCIState *s)
> @@ -1051,6 +1061,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, 
> unsigned size)
>  !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7) {
>  s->pwrcon &= ~SDHC_POWER_ON;
>  }
> +qemu_set_irq(s->access_led, s->hostctl & 1);
>  break;
>  case SDHC_CLKCON:
>  if (!(mask & 0xFF00)) {
> @@ -1163,6 +1174,7 @@ static void sdhci_initfn(SDHCIState *s)
>  qbus_create_inplace(>sdbus, sizeof(s->sdbus),
>  TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
>
> +s->access_led = qemu_allocate_irq(sdhci_led_handler, s, 0);
>  s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
> sdhci_raise_insertion_irq, s);
>  s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
> sdhci_data_transfer, s);
>  }
> @@ -1187,6 +1199,8 @@ static void sdhci_uninitfn(SDHCIState *s)
>  timer_free(s->insert_timer);
>  timer_del(s->transfer_timer);
>  timer_free(s->transfer_timer);
> +
> +qemu_free_irq(s->access_led);
>  }
>
>  static bool sdhci_pending_insert_vmstate_needed(void *opaque)
> diff --git a/hw/sd/trace-events b/hw/sd/trace-events
> index e4e26c6d73..f821db2046 100644
> --- a/hw/sd/trace-events
> +++ b/hw/sd/trace-events
> @@ -13,6 +13,7 @@ sdhci_adma_transfer_completed(void) "ADMA transfer 
> completed"
>  sdhci_access(const char *access, unsigned int size, uint64_t offset, const 
> char *dir, uint64_t val, uint64_t val2) "%s %ub: addr[0x%04" PRIx64 "] %s %" 
> PRIu64 "(0x%" PRIx64 ")"
>  sdhci_read_dataport(uint16_t data_count) "all %u bytes of data have been 
> read from input buffer"
>  sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes 
> of data"
> +sdhci_led(bool state) "LED: %u"
>
>  # hw/sd/milkymist-memcard.c
>  milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x 
> value 0x%08x"
> --
> 2.15.1
>
>



Re: [Qemu-devel] [PATCH v3 03/42] sdhci: remove dead code

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:48 AM, Philippe Mathieu-Daudé  wrote:
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/hw/sd/sdhci.h | 2 --
>  hw/sd/sdhci.c | 2 --
>  2 files changed, 4 deletions(-)
>
> diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> index 749cc279ed..a6fe064f51 100644
> --- a/include/hw/sd/sdhci.h
> +++ b/include/hw/sd/sdhci.h
> @@ -44,8 +44,6 @@ typedef struct SDHCIState {
>
>  QEMUTimer *insert_timer;   /* timer for 'changing' sd card. */
>  QEMUTimer *transfer_timer;
> -qemu_irq eject_cb;
> -qemu_irq ro_cb;
>  qemu_irq irq;
>
>  /* Registers cleared on reset */
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index b7d2a20985..365bc80009 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -1200,8 +1200,6 @@ static void sdhci_uninitfn(SDHCIState *s)
>  timer_free(s->insert_timer);
>  timer_del(s->transfer_timer);
>  timer_free(s->transfer_timer);
> -qemu_free_irq(s->eject_cb);
> -qemu_free_irq(s->ro_cb);
>
>  g_free(s->fifo_buffer);
>  s->fifo_buffer = NULL;
> --
> 2.15.1
>
>



Re: [Qemu-devel] [PATCH v3 02/42] sdhci: sort registers comments

2018-01-02 Thread Alistair Francis
On Fri, Dec 29, 2017 at 9:48 AM, Philippe Mathieu-Daudé  wrote:
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  include/hw/sd/sdhci.h | 21 +++--
>  1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> index 1335373d3c..749cc279ed 100644
> --- a/include/hw/sd/sdhci.h
> +++ b/include/hw/sd/sdhci.h
> @@ -49,14 +49,20 @@ typedef struct SDHCIState {
>  qemu_irq irq;
>
>  /* Registers cleared on reset */
> +/* 0x00 */
>  uint32_t sdmasysad;/* SDMA System Address register */
>  uint16_t blksize;  /* Host DMA Buff Boundary and Transfer BlkSize 
> Reg */
>  uint16_t blkcnt;   /* Blocks count for current transfer */
> +/* 0x08 */
>  uint32_t argument; /* Command Argument Register */
>  uint16_t trnmod;   /* Transfer Mode Setting Register */
>  uint16_t cmdreg;   /* Command Register */
> +/* 0x10 */
>  uint32_t rspreg[4];/* Response Registers 0-3 */
> +/* 0x20 */
> +/* Buffer Data Port Register - virtual access point to R and W buffers */
>  uint32_t prnsts;   /* Present State Register */
> +/* 0x28 */
>  uint8_t  hostctl;  /* Host Control Register */
>  uint8_t  pwrcon;   /* Power control Register */
>  uint8_t  blkgap;   /* Block Gap Control Register */
> @@ -64,6 +70,7 @@ typedef struct SDHCIState {
>  uint16_t clkcon;   /* Clock control Register */
>  uint8_t  timeoutcon;   /* Timeout Control Register */
>  uint8_t  admaerr;  /* ADMA Error Status Register */
> +/* 0x30 */
>  uint16_t norintsts;/* Normal Interrupt Status Register */
>  uint16_t errintsts;/* Error Interrupt Status Register */
>  uint16_t norintstsen;  /* Normal Interrupt Status Enable Register */
> @@ -71,23 +78,25 @@ typedef struct SDHCIState {
>  uint16_t norintsigen;  /* Normal Interrupt Signal Enable Register */
>  uint16_t errintsigen;  /* Error Interrupt Signal Enable Register */
>  uint16_t acmd12errsts; /* Auto CMD12 error status register */
> +/* 0x50 */
> +/* Force Event Auto CMD12 Error Interrupt Reg - write only */
> +/* Force Event Error Interrupt Register- write only */
> +/* 0x58 */
>  uint64_t admasysaddr;  /* ADMA System Address Register */
>
>  /* Read-only registers */
> +/* 0x40 */
>  uint32_t capareg;  /* Capabilities Register */
> +/* 0x48 */
>  uint32_t maxcurr;  /* Maximum Current Capabilities Register */
>
>  uint8_t  *fifo_buffer; /* SD host i/o FIFO buffer */
>  uint32_t buf_maxsz;
>  uint16_t data_count;   /* current element in FIFO buffer */
>  uint8_t  stopped_state;/* Current SDHC state */
> -bool pending_insert_quirk;/* Quirk for Raspberry Pi card insert int 
> */
>  bool pending_insert_state;
> -/* Buffer Data Port Register - virtual access point to R and W buffers */
> -/* Software Reset Register - always reads as 0 */
> -/* Force Event Auto CMD12 Error Interrupt Reg - write only */
> -/* Force Event Error Interrupt Register- write only */
> -/* RO Host Controller Version Register always reads as 0x2401 */
> +/* Configurable properties */
> +bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
>  } SDHCIState;
>
>  #define TYPE_PCI_SDHCI "sdhci-pci"
> --
> 2.15.1
>
>



[Qemu-devel] [PATCH v6 15/17] target/m68k: add andi/ori/eori to SR/CCR

2018-01-02 Thread Laurent Vivier
Signed-off-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
---
 target/m68k/translate.c | 53 ++---
 1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index d007943d93..205c3b8f35 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2201,6 +2201,7 @@ DISAS_INSN(arith_im)
 TCGv dest;
 TCGv addr;
 int opsize;
+bool with_SR = ((insn & 0x3f) == 0x3c);
 
 op = (insn >> 9) & 7;
 opsize = insn_opsize(insn);
@@ -2217,32 +2218,73 @@ DISAS_INSN(arith_im)
 default:
abort();
 }
-SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : );
+
+if (with_SR) {
+/* SR/CCR can only be used with andi/eori/ori */
+if (op == 2 || op == 3 || op == 6) {
+disas_undef(env, s, insn);
+return;
+}
+switch (opsize) {
+case OS_BYTE:
+src1 = gen_get_ccr(s);
+break;
+case OS_WORD:
+if (IS_USER(s)) {
+gen_exception(s, s->insn_pc, EXCP_PRIVILEGE);
+return;
+}
+src1 = gen_get_sr(s);
+break;
+case OS_LONG:
+disas_undef(env, s, insn);
+return;
+}
+} else {
+SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : );
+}
 dest = tcg_temp_new();
 switch (op) {
 case 0: /* ori */
 tcg_gen_or_i32(dest, src1, im);
-gen_logic_cc(s, dest, opsize);
+if (with_SR) {
+gen_set_sr(s, dest, opsize == OS_BYTE);
+} else {
+DEST_EA(env, insn, opsize, dest, );
+gen_logic_cc(s, dest, opsize);
+}
 break;
 case 1: /* andi */
 tcg_gen_and_i32(dest, src1, im);
-gen_logic_cc(s, dest, opsize);
+if (with_SR) {
+gen_set_sr(s, dest, opsize == OS_BYTE);
+} else {
+DEST_EA(env, insn, opsize, dest, );
+gen_logic_cc(s, dest, opsize);
+}
 break;
 case 2: /* subi */
 tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, src1, im);
 tcg_gen_sub_i32(dest, src1, im);
 gen_update_cc_add(dest, im, opsize);
 set_cc_op(s, CC_OP_SUBB + opsize);
+DEST_EA(env, insn, opsize, dest, );
 break;
 case 3: /* addi */
 tcg_gen_add_i32(dest, src1, im);
 gen_update_cc_add(dest, im, opsize);
 tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
 set_cc_op(s, CC_OP_ADDB + opsize);
+DEST_EA(env, insn, opsize, dest, );
 break;
 case 5: /* eori */
 tcg_gen_xor_i32(dest, src1, im);
-gen_logic_cc(s, dest, opsize);
+if (with_SR) {
+gen_set_sr(s, dest, opsize == OS_BYTE);
+} else {
+DEST_EA(env, insn, opsize, dest, );
+gen_logic_cc(s, dest, opsize);
+}
 break;
 case 6: /* cmpi */
 gen_update_cc_cmp(s, src1, im, opsize);
@@ -2251,9 +2293,6 @@ DISAS_INSN(arith_im)
 abort();
 }
 tcg_temp_free(im);
-if (op != 6) {
-DEST_EA(env, insn, opsize, dest, );
-}
 tcg_temp_free(dest);
 }
 
-- 
2.14.3




  1   2   3   >