Re: [Qemu-devel] [PATCH v2 00/16] Virtio devices split from virtio-pci

2018-11-27 Thread Juan Quintela
"Michael S. Tsirkin"  wrote:
> On Mon, Nov 26, 2018 at 08:59:53PM +0100, Juan Quintela wrote:
>> Hi
>> 
>> V2:
>> 
>> - Rebase on top of master
>> 
>> Please review.
>> 
>> Later, Juan.
>
> And just making sure the point is so that one
> can disable virtio-pci and still build virtio?
>
> And the point of that is mostly as a cleanup on
> generic principles, right? Or is there a project that
> actually wants to do it?

This allows "make check" to work with them disabled.  Without this
changes, introspection fails, because we have the "name" (kind of)
"virtio-pci-blk", but not the real virtio device, so it tries to use it
while it is not there.  See the equivalent change for virtio-ccw-*.

Thanks, Juan.

PD.  Without this change, you can build a qemu with virtio devices
 disabled (i.e. not compiled in), but it fails "make check".  With
 the changes, it also works for "make check".


>
>> 
>> [v1]
>> >From previous verision (in the middle of make check tests):
>> - split also the bits of virtio-pci.h (mst suggestion)
>> - add gpu, crypt and gpg bits
>> - more cleanups
>> - fix all the copyrights (the ones not changed have been there
>>   foverever)
>> - be consistent with naming, vhost-* or virtio-*
>> 
>> Please review, Juan.
>> 
>> Juan Quintela (16):
>>   virtio: split vhost vsock bits from virtio-pci
>>   virtio: split virtio input host bits from virtio-pci
>>   virtio: split virtio input bits from virtio-pci
>>   virtio: split virtio rng bits from virtio-pci
>>   virtio: split virtio balloon bits from virtio-pci
>>   virtio: split virtio 9p bits from virtio-pci
>>   virtio: split vhost user blk bits from virtio-pci
>>   virtio: split vhost user scsi bits from virtio-pci
>>   virtio: split vhost scsi bits from virtio-pci
>>   virtio: split virtio scsi bits from virtio-pci
>>   virtio: split virtio blk bits rom virtio-pci
>>   virtio: split virtio net bits rom virtio-pci
>>   virtio: split virtio serial bits rom virtio-pci
>>   virtio: split virtio gpu bits rom virtio-pci.h
>>   virtio: split virtio crypto bits rom virtio-pci.h
>>   virtio: virtio 9p really requires CONFIG_VIRTFS to work
>> 
>>  default-configs/virtio.mak|   3 +-
>>  hw/display/virtio-gpu-pci.c   |  14 +
>>  hw/display/virtio-vga.c   |   1 +
>>  hw/virtio/Makefile.objs   |  14 +-
>>  hw/virtio/vhost-scsi-pci.c|  95 
>>  hw/virtio/vhost-user-blk-pci.c| 101 
>>  hw/virtio/vhost-user-scsi-pci.c   | 101 
>>  hw/virtio/vhost-vsock-pci.c   |  82 
>>  hw/virtio/virtio-9p-pci.c |  86 
>>  hw/virtio/virtio-balloon-pci.c|  94 
>>  hw/virtio/virtio-blk-pci.c|  97 
>>  hw/virtio/virtio-crypto-pci.c |  14 +
>>  hw/virtio/virtio-input-host-pci.c |  45 ++
>>  hw/virtio/virtio-input-pci.c  | 154 ++
>>  hw/virtio/virtio-net-pci.c|  96 
>>  hw/virtio/virtio-pci.c| 783 --
>>  hw/virtio/virtio-pci.h| 234 -
>>  hw/virtio/virtio-rng-pci.c|  86 
>>  hw/virtio/virtio-scsi-pci.c   | 106 
>>  hw/virtio/virtio-serial-pci.c | 112 +
>>  tests/Makefile.include|  18 +-
>>  21 files changed, 1308 insertions(+), 1028 deletions(-)
>>  create mode 100644 hw/virtio/vhost-scsi-pci.c
>>  create mode 100644 hw/virtio/vhost-user-blk-pci.c
>>  create mode 100644 hw/virtio/vhost-user-scsi-pci.c
>>  create mode 100644 hw/virtio/vhost-vsock-pci.c
>>  create mode 100644 hw/virtio/virtio-9p-pci.c
>>  create mode 100644 hw/virtio/virtio-balloon-pci.c
>>  create mode 100644 hw/virtio/virtio-blk-pci.c
>>  create mode 100644 hw/virtio/virtio-input-host-pci.c
>>  create mode 100644 hw/virtio/virtio-input-pci.c
>>  create mode 100644 hw/virtio/virtio-net-pci.c
>>  create mode 100644 hw/virtio/virtio-rng-pci.c
>>  create mode 100644 hw/virtio/virtio-scsi-pci.c
>>  create mode 100644 hw/virtio/virtio-serial-pci.c
>> 
>> -- 
>> 2.19.1
>> 



Re: [Qemu-devel] [PATCH v2] bt: use size_t type for length parameters instead of int

2018-11-27 Thread P J P
+-- On Mon, 19 Nov 2018, P J P wrote --+
| From: Prasad J Pandit 
| 
| The length parameter values are not negative, thus use an unsigned
| type 'size_t' for them. Many routines pass 'len' values to memcpy(3)
| calls. If it was negative, it could lead to memory corruption issues.
| Add check to avoid it.
| 
| Reported-by: Arash TC 
| Signed-off-by: Prasad J Pandit 
| ---
|  bt-host.c  |  8 +++---
|  bt-vhci.c  |  7 +++---
|  hw/bt/core.c   |  2 +-
|  hw/bt/hci-csr.c| 32 
|  hw/bt/hci.c| 38 ++--
|  hw/bt/hid.c| 10 
|  hw/bt/l2cap.c  | 56 ++
|  hw/bt/sdp.c|  6 ++---
|  hw/usb/dev-bluetooth.c | 12 -
|  include/hw/bt.h|  8 +++---
|  include/sysemu/bt.h| 10 
|  11 files changed, 96 insertions(+), 93 deletions(-)
| 
| Update v2: modify assert calls
|   -> https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg01036.html
| 

Ping...!
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F



Re: [Qemu-devel] [PATCH for-3.1 0/2] Fix disas/nanomips

2018-11-27 Thread Aleksandar Markovic
Stefan Weil wrote:

> These two patches fix wrong format strings used in disas/nanomips.

Stefan,

I truly appreciate your interest in nanoMIPS dissasembler.

In my opinion, this series comes too late in 3.1 development cycle to be
accepted. The described severity of undesired behavior is just way too low
for rc3 phase.

Also, as a general remark, in this series, there is no example of wrong
output for big endian host, only some belief or opinion - referent test
example would be helpful, and much better justification for the series.
Some build errors are mentioned, but they are not a part for official
builds. Related to these errors, certain additional build options are said
to cause build warnings, but such build options were not identified.

All in all, my judgement is that we should deal with these issues after 3.1
release.

However, I am still grateful to you for bringing these issues up, and you
are welcome to participate in any way in future development of this and
other segments of QEMU for MIPS.

Yours,
Aleksandar
On Nov 27, 2018 1:19 PM, "Stefan Weil"  wrote:

> These two patches fix wrong format strings used in disas/nanomips.
>
> The first patch replaces proprietary data types by POSIX data types,
> because otherwise the PRI... macros cannot be used in the second patch.
>
> Those patches are only relevant for 3.1 if full nanomips support is
> considered
> important enought and if QEMU is used on big endian machines (I think
> the old code will work on little endian hosts even with wrong format
> strings).
>
> I use those patches for QEMU for Windows because that is compiled with
> more compiler warnings, so compilation would fail without the fix.
>
> Regards
> Stefan
>
>
>


Re: [Qemu-devel] [PATCH] spice: Use new SpiceImageCompression definition

2018-11-27 Thread no-reply
Hi,

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

Message-id: 20181126153036.22414-1-fzig...@redhat.com
Subject: [Qemu-devel] [PATCH] spice: Use new SpiceImageCompression definition
Type: series

=== 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
git config --local diff.algorithm histogram

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'
0db479d spice: Use new SpiceImageCompression definition

=== OUTPUT BEGIN ===
Checking PATCH 1/1: spice: Use new SpiceImageCompression definition...
ERROR: space prohibited after that open square bracket '['
#26: FILE: ui/spice-core.c:334:
+[ SPICE_IMAGE_COMPRESSION_OFF ]  = "off",

ERROR: space prohibited before that close square bracket ']'
#26: FILE: ui/spice-core.c:334:
+[ SPICE_IMAGE_COMPRESSION_OFF ]  = "off",

ERROR: space prohibited after that open square bracket '['
#27: FILE: ui/spice-core.c:335:
+[ SPICE_IMAGE_COMPRESSION_AUTO_GLZ ] = "auto_glz",

ERROR: space prohibited before that close square bracket ']'
#27: FILE: ui/spice-core.c:335:
+[ SPICE_IMAGE_COMPRESSION_AUTO_GLZ ] = "auto_glz",

ERROR: space prohibited after that open square bracket '['
#28: FILE: ui/spice-core.c:336:
+[ SPICE_IMAGE_COMPRESSION_AUTO_LZ ]  = "auto_lz",

ERROR: space prohibited before that close square bracket ']'
#28: FILE: ui/spice-core.c:336:
+[ SPICE_IMAGE_COMPRESSION_AUTO_LZ ]  = "auto_lz",

ERROR: space prohibited after that open square bracket '['
#29: FILE: ui/spice-core.c:337:
+[ SPICE_IMAGE_COMPRESSION_QUIC ] = "quic",

ERROR: space prohibited before that close square bracket ']'
#29: FILE: ui/spice-core.c:337:
+[ SPICE_IMAGE_COMPRESSION_QUIC ] = "quic",

ERROR: space prohibited after that open square bracket '['
#30: FILE: ui/spice-core.c:338:
+[ SPICE_IMAGE_COMPRESSION_GLZ ]  = "glz",

ERROR: space prohibited before that close square bracket ']'
#30: FILE: ui/spice-core.c:338:
+[ SPICE_IMAGE_COMPRESSION_GLZ ]  = "glz",

ERROR: space prohibited after that open square bracket '['
#31: FILE: ui/spice-core.c:339:
+[ SPICE_IMAGE_COMPRESSION_LZ ]   = "lz",

ERROR: space prohibited before that close square bracket ']'
#31: FILE: ui/spice-core.c:339:
+[ SPICE_IMAGE_COMPRESSION_LZ ]   = "lz",

total: 12 errors, 0 warnings, 34 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH v5 22/36] spapr/xive: add models for KVM support

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:15AM +0100, Cédric Le Goater wrote:
> This introduces a set of XIVE models specific to KVM which derive from
> the XIVE base models. The interfaces with KVM are a new capability and
> a new KVM device for the XIVE native exploitation interrupt mode.
> 
> They handle the initialization of the TIMA and the source ESB memory
> regions which have a different type under KVM. These are 'ram device'
> memory mappings, similarly to VFIO, exposed to the guest and the
> associated VMAs on the host are populated dynamically with the
> appropriate pages using a fault handler.
> 
> Signed-off-by: Cédric Le Goater 

The logic here looks fine, but I think it would be better to activate
it with explicit if (kvm) type logic rather than using a subclass.

> ---
>  default-configs/ppc64-softmmu.mak |   1 +
>  include/hw/ppc/spapr_xive.h   |  18 ++
>  include/hw/ppc/xive.h |   3 +
>  linux-headers/asm-powerpc/kvm.h   |  12 +
>  linux-headers/linux/kvm.h |   4 +
>  target/ppc/kvm_ppc.h  |   6 +
>  hw/intc/spapr_xive_kvm.c  | 430 ++
>  hw/ppc/spapr.c|   7 +-
>  hw/ppc/spapr_irq.c|  19 +-
>  target/ppc/kvm.c  |   7 +
>  hw/intc/Makefile.objs |   1 +
>  11 files changed, 503 insertions(+), 5 deletions(-)
>  create mode 100644 hw/intc/spapr_xive_kvm.c
> 
> diff --git a/default-configs/ppc64-softmmu.mak 
> b/default-configs/ppc64-softmmu.mak
> index 7f34ad0528ed..c1bf5cd951f5 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -18,6 +18,7 @@ CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
>  CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
>  CONFIG_XIVE=$(CONFIG_PSERIES)
>  CONFIG_XIVE_SPAPR=$(CONFIG_PSERIES)
> +CONFIG_XIVE_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
>  CONFIG_MEM_DEVICE=y
>  CONFIG_DIMM=y
>  CONFIG_SPAPR_RNG=y
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index aca2969a09ab..9c817bb7ae74 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -40,6 +40,10 @@ typedef struct sPAPRXive {
>  /* TIMA mapping address */
>  hwaddrtm_base;
>  MemoryRegion  tm_mmio;
> +
> +/* KVM support */
> +int   fd;
> +void  *tm_mmap;
>  } sPAPRXive;
>  
>  #define SPAPR_XIVE_BASE_CLASS(klass) \
> @@ -83,4 +87,18 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr);
>  void spapr_dt_xive(sPAPRXive *xive, int nr_servers, void *fdt,
> uint32_t phandle);
>  
> +/*
> + * XIVE KVM models
> + */
> +
> +#define TYPE_SPAPR_XIVE_KVM  "spapr-xive-kvm"
> +#define SPAPR_XIVE_KVM(obj)  OBJECT_CHECK(sPAPRXive, (obj), 
> TYPE_SPAPR_XIVE_KVM)
> +
> +#define TYPE_XIVE_SOURCE_KVM "xive-source-kvm"
> +#define XIVE_SOURCE_KVM(obj) \
> +OBJECT_CHECK(XiveSource, (obj), TYPE_XIVE_SOURCE_KVM)
> +
> +#define TYPE_XIVE_TCTX_KVM   "xive-tctx-kvm"
> +#define XIVE_TCTX_KVM(obj)   OBJECT_CHECK(XiveTCTX, (obj), 
> TYPE_XIVE_TCTX_KVM)
> +
>  #endif /* PPC_SPAPR_XIVE_H */
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 281ed370121c..7aaf5a182cb3 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -69,6 +69,9 @@ typedef struct XiveSource {
>  uint32_tesb_shift;
>  MemoryRegionesb_mmio;
>  
> +/* KVM support */
> +void*esb_mmap;
> +
>  XiveFabric  *xive;
>  } XiveSource;
>  
> diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
> index 8c876c166ef2..f34c971491dd 100644
> --- a/linux-headers/asm-powerpc/kvm.h
> +++ b/linux-headers/asm-powerpc/kvm.h

Updates to linux-headers need to be split out into a separate patch.
Eventually (i.e. by the time we merge) they should be just "update
headers to SHA XXX" not picking and choosing pieces.

> @@ -675,4 +675,16 @@ struct kvm_ppc_cpu_char {
>  #define  KVM_XICS_PRESENTED  (1ULL << 43)
>  #define  KVM_XICS_QUEUED (1ULL << 44)
>  
> +/* POWER9 XIVE Native Interrupt Controller */
> +#define KVM_DEV_XIVE_GRP_CTRL1
> +#define   KVM_DEV_XIVE_GET_ESB_FD1
> +#define   KVM_DEV_XIVE_GET_TIMA_FD   2
> +#define   KVM_DEV_XIVE_VC_BASE   3
> +#define KVM_DEV_XIVE_GRP_SOURCES 2   /* 64-bit source attributes */
> +
> +/* Layout of 64-bit XIVE source attribute values */
> +#define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0)
> +#define KVM_XIVE_LEVEL_ASSERTED  (1ULL << 1)
> +
> +
>  #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index f11a7eb49cfa..59fa8d8d7f39 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -965,6 +965,8 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_COALESCED_PIO 162
>  #define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
>  #define KVM_CAP_EXCEPTION_PAYLOAD 164
> +#define KVM_CAP_ARM_VM_IPA_SIZE 165
> +#define KVM_CAP_P

Re: [Qemu-devel] [PATCH v5 21/36] spapr: extend the sPAPR IRQ backend for XICS migration

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:14AM +0100, Cédric Le Goater wrote:
> Introduce a new sPAPR IRQ handler to handle resend after migration
> when the machine is using a KVM XICS interrupt controller model.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  include/hw/ppc/spapr_irq.h |  2 ++
>  hw/ppc/spapr.c | 13 +
>  hw/ppc/spapr_irq.c | 27 +++
>  3 files changed, 34 insertions(+), 8 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index b299dd794bff..4e36c0984e1a 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -45,6 +45,7 @@ typedef struct sPAPRIrq {
>  void *fdt, uint32_t phandle);
>  Object *(*cpu_intc_create)(sPAPRMachineState *spapr, Object *cpu,
> Error **errp);
> +int (*post_load)(sPAPRMachineState *spapr, int version_id);
>  } sPAPRIrq;
>  
>  extern sPAPRIrq spapr_irq_xics;
> @@ -55,6 +56,7 @@ void spapr_irq_init(sPAPRMachineState *spapr, int 
> nr_servers, Error **errp);
>  int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error 
> **errp);
>  void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
> +int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id);
>  
>  /*
>   * XICS legacy routines
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 8fbb743769db..f9cf2debff5a 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1738,14 +1738,6 @@ static int spapr_post_load(void *opaque, int 
> version_id)
>  return err;
>  }
>  
> -if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
> -CPUState *cs;
> -CPU_FOREACH(cs) {
> -PowerPCCPU *cpu = POWERPC_CPU(cs);
> -icp_resend(ICP(cpu->intc));
> -}
> -}
> -
>  /* In earlier versions, there was no separate qdev for the PAPR
>   * RTC, so the RTC offset was stored directly in sPAPREnvironment.
>   * So when migrating from those versions, poke the incoming offset
> @@ -1766,6 +1758,11 @@ static int spapr_post_load(void *opaque, int 
> version_id)
>  }
>  }
>  
> +err = spapr_irq_post_load(spapr, version_id);
> +if (err) {
> +return err;
> +}
> +
>  return err;
>  }
>  
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index f6e9e44d4cf9..33dd5da7d255 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -203,6 +203,18 @@ static Object 
> *spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
>  return icp_create(cpu, spapr->icp_type, XICS_FABRIC(spapr), errp);
>  }
>  
> +static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
> +{
> +if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
> +CPUState *cs;
> +CPU_FOREACH(cs) {
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +icp_resend(ICP(cpu->intc));
> +}
> +}
> +return 0;
> +}
> +
>  #define SPAPR_IRQ_XICS_NR_IRQS 0x1000
>  #define SPAPR_IRQ_XICS_NR_MSIS \
>  (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
> @@ -219,6 +231,7 @@ sPAPRIrq spapr_irq_xics = {
>  .print_info  = spapr_irq_print_info_xics,
>  .dt_populate = spapr_irq_dt_populate_xics,
>  .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
> +.post_load   = spapr_irq_post_load_xics,
>  };
>  
>   /*
> @@ -331,6 +344,11 @@ static Object 
> *spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
>  XIVE_ROUTER(spapr->xive), errp);
>  }
>  
> +static int spapr_irq_post_load_xive(sPAPRMachineState *spapr, int version_id)
> +{
> +return 0;
> +}
> +
>  /*
>   * XIVE uses the full IRQ number space. Set it to 8K to be compatible
>   * with XICS.
> @@ -351,6 +369,7 @@ sPAPRIrq spapr_irq_xive = {
>  .print_info  = spapr_irq_print_info_xive,
>  .dt_populate = spapr_irq_dt_populate_xive,
>  .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
> +.post_load   = spapr_irq_post_load_xive,
>  };
>  
>  /*
> @@ -389,6 +408,13 @@ qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq)
>  return smc->irq->qirq(spapr, irq);
>  }
>  
> +int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id)
> +{
> +sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +
> +return smc->irq->post_load(spapr, version_id);
> +}
> +
>  /*
>   * XICS legacy routines - to deprecate one day
>   */
> @@ -458,4 +484,5 @@ sPAPRIrq spapr_irq_xics_legacy = {
>  .print_info  = spapr_irq_print_info_xics,
>  .dt_populate = spapr_irq_dt_populate_xics,
>  .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
> +.post_load   = spapr_irq_post_load_xics,
>  };

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

Re: [Qemu-devel] [PATCH for-3.1] vfio-helpers: Fix qemu_vfio_open_pci() crash

2018-11-27 Thread Cong Li


- Original Message -
> From: "Markus Armbruster" 
> To: qemu-devel@nongnu.org
> Cc: c...@redhat.com, f...@euphon.net, stefa...@redhat.com, pbonz...@redhat.com
> Sent: Tuesday, November 27, 2018 4:41:43 PM
> Subject: [PATCH for-3.1] vfio-helpers: Fix qemu_vfio_open_pci() crash
> 
> qemu_vfio_open_common() initializes s->lock only after passing s to
> qemu_vfio_dma_map() via qemu_vfio_init_ramblock().
> qemu_vfio_dma_map() tries to lock the uninitialized lock and crashes.
> 
> Fix by initializing s->lock first.
> 
> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1645840
> Fixes: 418026ca43bc2626db092d7558258f9594366f28
> Cc: qemu-sta...@nongnu.org
> Signed-off-by: Markus Armbruster 
> ---
> Compile-tested only, as I lack suitable hardware.  Cong Li (cc'ed) is
> going to test it for real.  It looks obvious enough to me to put it
> into -rc3 without waiting for the test results.  We can also wait and
> put it into -rc4.

Smoke test of nvme:// pass with this patch.

Ack.

> 
>  util/vfio-helpers.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
> index 1d9272efa4..9cd42e 100644
> --- a/util/vfio-helpers.c
> +++ b/util/vfio-helpers.c
> @@ -411,13 +411,13 @@ static int qemu_vfio_init_ramblock(const char
> *block_name, void *host_addr,
>  
>  static void qemu_vfio_open_common(QEMUVFIOState *s)
>  {
> +qemu_mutex_init(&s->lock);
>  s->ram_notifier.ram_block_added = qemu_vfio_ram_block_added;
>  s->ram_notifier.ram_block_removed = qemu_vfio_ram_block_removed;
>  ram_block_notifier_add(&s->ram_notifier);
>  s->low_water_mark = QEMU_VFIO_IOVA_MIN;
>  s->high_water_mark = QEMU_VFIO_IOVA_MAX;
>  qemu_ram_foreach_block(qemu_vfio_init_ramblock, s);
> -qemu_mutex_init(&s->lock);
>  }
>  
>  /**
> --
> 2.17.2
> 
> 



[Qemu-devel] [PATCH 07/12] tcg: Dump register preference info with liveness

2018-11-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/tcg.h |  3 ---
 tcg/tcg.c | 44 +---
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index b2e274b7af..ac5d01c223 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1089,9 +1089,6 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, 
TCGOpcode opc, int narg);
 
 void tcg_optimize(TCGContext *s);
 
-/* only used for debugging purposes */
-void tcg_dump_ops(TCGContext *s);
-
 TCGv_i32 tcg_const_i32(int32_t val);
 TCGv_i64 tcg_const_i64(int64_t val);
 TCGv_i32 tcg_const_local_i32(int32_t val);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index adf6570c36..27d081e11a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1921,7 +1921,7 @@ static inline TCGReg tcg_regset_first(TCGRegSet d)
 }
 }
 
-void tcg_dump_ops(TCGContext *s)
+static void tcg_dump_ops(TCGContext *s, bool have_prefs)
 {
 char buf[128];
 TCGOp *op;
@@ -2056,12 +2056,15 @@ void tcg_dump_ops(TCGContext *s)
 col += qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", op->args[k]);
 }
 }
-if (op->life) {
-unsigned life = op->life;
 
-for (; col < 48; ++col) {
+if (have_prefs || op->life) {
+for (; col < 40; ++col) {
 putc(' ', qemu_logfile);
 }
+}
+
+if (op->life) {
+unsigned life = op->life;
 
 if (life & (SYNC_ARG * 3)) {
 qemu_log("  sync:");
@@ -2081,6 +2084,33 @@ void tcg_dump_ops(TCGContext *s)
 }
 }
 }
+
+if (have_prefs) {
+for (i = 0; i < nb_oargs; ++i) {
+TCGRegSet set = op->output_pref[i];
+
+if (i == 0) {
+qemu_log("  pref=");
+} else {
+qemu_log(",");
+}
+if (set == 0) {
+qemu_log("none");
+} else if (set == MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS)) {
+qemu_log("all");
+#ifdef CONFIG_DEBUG_TCG
+} else if (tcg_regset_single(set)) {
+TCGReg reg = tcg_regset_first(set);
+qemu_log("%s", tcg_target_reg_names[reg]);
+#endif
+} else if (TCG_TARGET_NB_REGS <= 32) {
+qemu_log("%#x", (uint32_t)set);
+} else {
+qemu_log("%#" PRIx64, (uint64_t)set);
+}
+}
+}
+
 qemu_log("\n");
 }
 }
@@ -3669,7 +3699,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, false);
 qemu_log("\n");
 qemu_log_unlock();
 }
@@ -3697,7 +3727,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP before indirect lowering:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, false);
 qemu_log("\n");
 qemu_log_unlock();
 }
@@ -3718,7 +3748,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
  && qemu_log_in_addr_range(tb->pc))) {
 qemu_log_lock();
 qemu_log("OP after optimization and liveness analysis:\n");
-tcg_dump_ops(s);
+tcg_dump_ops(s, true);
 qemu_log("\n");
 qemu_log_unlock();
 }
-- 
2.17.2




Re: [Qemu-devel] [Spice-devel] [PATCH] spice: Use new SpiceImageCompression definition

2018-11-27 Thread Gerd Hoffmann
On Tue, Nov 27, 2018 at 01:35:02PM +0100, Christophe Fergeau wrote:
> hey,
> 
> On Mon, Nov 26, 2018 at 03:30:36PM +, Frediano Ziglio wrote:
> > Definitions were updated by spice-server in patch de66161 included
> > in 0.12.6 released on 12th June 2015.
> 
> QEMU's configure only checks for spice-server 0.12.0:

> I don't know how far back QEMU wants to support spice-server.
> Apart from this, the patch looks good to me.

0.12.6 is more than three years old, so this or something newer should
be available in most distros meanwhile.  Raising the bar to that version
looks ok to me (separate patch please, and please also drop #ifdefs we
don't need any more then).

thanks,
  Gerd




[Qemu-devel] [PATCH 10/12] tcg: Split out more subroutines from liveness_pass_1

2018-11-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 35 +++
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 27814df882..21668831a1 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2417,6 +2417,26 @@ static void la_bb_end(TCGContext *s, int ng, int nt)
 }
 }
 
+/* liveness analysis: sync globals back to memory.  */
+static void la_global_sync(TCGContext *s, int ng)
+{
+int i;
+
+for (i = 0; i < ng; ++i) {
+s->temps[i].state |= TS_MEM;
+}
+}
+
+/* liveness analysis: sync globals back to memory and kill.  */
+static void la_global_kill(TCGContext *s, int ng)
+{
+int i;
+
+for (i = 0; i < ng; i++) {
+s->temps[i].state = TS_DEAD | TS_MEM;
+}
+}
+
 /* Liveness analysis : update the opc_arg_life array to tell if a
given input arguments is dead. Instructions updating dead
temporaries are removed. */
@@ -2472,15 +2492,9 @@ static void liveness_pass_1(TCGContext *s)
 
 if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
 TCG_CALL_NO_READ_GLOBALS))) {
-/* globals should go back to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state = TS_DEAD | TS_MEM;
-}
+la_global_kill(s, nb_globals);
 } else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+la_global_sync(s, nb_globals);
 }
 
 /* record arguments that die in this helper */
@@ -2623,10 +2637,7 @@ static void liveness_pass_1(TCGContext *s)
 if (def->flags & TCG_OPF_BB_END) {
 la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+la_global_sync(s, nb_globals);
 }
 
 /* record arguments that die in this opcode */
-- 
2.17.2




[Qemu-devel] [PATCH 09/12] tcg: Rename and adjust liveness_pass_1 helpers

2018-11-27 Thread Richard Henderson
No need for a "tcg_" prefix for a static function; we already
have another "la_" prefix for indicating liveness analysis.
Pass in nb_globals and nb_temps, as we will already have them
in registers for other loops within the parent function.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 82f9a66d31..27814df882 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2389,10 +2389,8 @@ static void reachable_code_pass(TCGContext *s)
 
 /* liveness analysis: end of function: all temps are dead, and globals
should be in memory. */
-static void tcg_la_func_end(TCGContext *s)
+static void la_func_end(TCGContext *s, int ng, int nt)
 {
-int ng = s->nb_globals;
-int nt = s->nb_temps;
 int i;
 
 for (i = 0; i < ng; ++i) {
@@ -2405,10 +2403,8 @@ static void tcg_la_func_end(TCGContext *s)
 
 /* liveness analysis: end of basic block: all temps are dead, globals
and local temps should be in memory. */
-static void tcg_la_bb_end(TCGContext *s)
+static void la_bb_end(TCGContext *s, int ng, int nt)
 {
-int ng = s->nb_globals;
-int nt = s->nb_temps;
 int i;
 
 for (i = 0; i < ng; ++i) {
@@ -2427,9 +2423,10 @@ static void tcg_la_bb_end(TCGContext *s)
 static void liveness_pass_1(TCGContext *s)
 {
 int nb_globals = s->nb_globals;
+int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
 
-tcg_la_func_end(s);
+la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, TCGOpHead, link, op_prev) {
 int i, nb_iargs, nb_oargs;
@@ -2624,7 +2621,7 @@ static void liveness_pass_1(TCGContext *s)
 
 /* if end of basic block, update */
 if (def->flags & TCG_OPF_BB_END) {
-tcg_la_bb_end(s);
+la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
 /* globals should be synced to memory */
 for (i = 0; i < nb_globals; i++) {
-- 
2.17.2




[Qemu-devel] [PATCH 08/12] tcg: Reindent parts of liveness_pass_1

2018-11-27 Thread Richard Henderson
There are two blocks of the form

if (foo) {
stuff1;
goto bar;
} else {
baz:
stuff2;
}

which have unnecessary and confusing indentation.
Remove the else and unindent stuff2.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 139 --
 1 file changed, 71 insertions(+), 68 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 27d081e11a..82f9a66d31 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2458,47 +2458,46 @@ static void liveness_pass_1(TCGContext *s)
 }
 }
 goto do_remove;
-} else {
-do_not_remove_call:
+}
+do_not_remove_call:
 
-/* output args are dead */
-for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
-if (arg_ts->state & TS_MEM) {
-arg_life |= SYNC_ARG << i;
-}
-arg_ts->state = TS_DEAD;
+/* output args are dead */
+for (i = 0; i < nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts->state & TS_DEAD) {
+arg_life |= DEAD_ARG << i;
 }
+if (arg_ts->state & TS_MEM) {
+arg_life |= SYNC_ARG << i;
+}
+arg_ts->state = TS_DEAD;
+}
 
-if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
-TCG_CALL_NO_READ_GLOBALS))) {
-/* globals should go back to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state = TS_DEAD | TS_MEM;
-}
-} else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
-/* globals should be synced to memory */
-for (i = 0; i < nb_globals; i++) {
-s->temps[i].state |= TS_MEM;
-}
+if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
+TCG_CALL_NO_READ_GLOBALS))) {
+/* globals should go back to memory */
+for (i = 0; i < nb_globals; i++) {
+s->temps[i].state = TS_DEAD | TS_MEM;
 }
+} else if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
+/* globals should be synced to memory */
+for (i = 0; i < nb_globals; i++) {
+s->temps[i].state |= TS_MEM;
+}
+}
 
-/* record arguments that die in this helper */
-for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts && arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
+/* record arguments that die in this helper */
+for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts && arg_ts->state & TS_DEAD) {
+arg_life |= DEAD_ARG << i;
 }
-/* input arguments are live for preceding opcodes */
-for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts) {
-arg_ts->state &= ~TS_DEAD;
-}
+}
+/* input arguments are live for preceding opcodes */
+for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
+arg_ts = arg_temp(op->args[i]);
+if (arg_ts) {
+arg_ts->state &= ~TS_DEAD;
 }
 }
 }
@@ -2602,43 +2601,47 @@ static void liveness_pass_1(TCGContext *s)
 goto do_not_remove;
 }
 }
-do_remove:
-tcg_op_remove(s, op);
-} else {
-do_not_remove:
-/* output args are dead */
-for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state & TS_DEAD) {
-arg_life |= DEAD_ARG << i;
-}
-if (arg_ts->state & TS_MEM) {
-arg_life |= SYNC_ARG << i;
-}
-

[Qemu-devel] [PATCH 12/12] tcg: Record register preferences during liveness

2018-11-27 Thread Richard Henderson
With these preferences, we can arrange for function call arguments to
be computed into the proper registers instead of requiring extra moves.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 197 +-
 1 file changed, 165 insertions(+), 32 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 673aaf52a1..734a453fc8 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2387,6 +2387,21 @@ static void reachable_code_pass(TCGContext *s)
 #define IS_DEAD_ARG(n)   (arg_life & (DEAD_ARG << (n)))
 #define NEED_SYNC_ARG(n) (arg_life & (SYNC_ARG << (n)))
 
+/* For liveness_pass_1, the register preferences for a given temp.  */
+static inline TCGRegSet *la_temp_pref(TCGTemp *ts)
+{
+return ts->state_ptr;
+}
+
+/* For liveness_pass_1, reset the preferences for a given temp to the
+ * maximal regset for its type.
+ */
+static inline void la_reset_pref(TCGTemp *ts)
+{
+*la_temp_pref(ts)
+= (ts->state == TS_DEAD ? 0 : tcg_target_available_regs[ts->type]);
+}
+
 /* liveness analysis: end of function: all temps are dead, and globals
should be in memory. */
 static void la_func_end(TCGContext *s, int ng, int nt)
@@ -2395,9 +2410,11 @@ static void la_func_end(TCGContext *s, int ng, int nt)
 
 for (i = 0; i < ng; ++i) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(&s->temps[i]);
 }
 for (i = ng; i < nt; ++i) {
 s->temps[i].state = TS_DEAD;
+la_reset_pref(&s->temps[i]);
 }
 }
 
@@ -2409,11 +2426,13 @@ static void la_bb_end(TCGContext *s, int ng, int nt)
 
 for (i = 0; i < ng; ++i) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(&s->temps[i]);
 }
 for (i = ng; i < nt; ++i) {
 s->temps[i].state = (s->temps[i].temp_local
  ? TS_DEAD | TS_MEM
  : TS_DEAD);
+la_reset_pref(&s->temps[i]);
 }
 }
 
@@ -2423,7 +2442,12 @@ static void la_global_sync(TCGContext *s, int ng)
 int i;
 
 for (i = 0; i < ng; ++i) {
-s->temps[i].state |= TS_MEM;
+int state = s->temps[i].state;
+s->temps[i].state = state | TS_MEM;
+if (state == TS_DEAD) {
+/* If the global was previously dead, reset prefs.  */
+la_reset_pref(&s->temps[i]);
+}
 }
 }
 
@@ -2434,6 +2458,29 @@ static void la_global_kill(TCGContext *s, int ng)
 
 for (i = 0; i < ng; i++) {
 s->temps[i].state = TS_DEAD | TS_MEM;
+la_reset_pref(&s->temps[i]);
+}
+}
+
+/* liveness analysis: note live globals crossing calls.  */
+static void la_cross_call(TCGContext *s, int nt)
+{
+TCGRegSet mask = ~tcg_target_call_clobber_regs;
+int i;
+
+for (i = 0; i < nt; i++) {
+TCGTemp *ts = &s->temps[i];
+if (!(ts->state & TS_DEAD)) {
+TCGRegSet *pset = la_temp_pref(ts);
+TCGRegSet set = *pset;
+
+set &= mask;
+/* If the combination is not possible, restart.  */
+if (set == 0) {
+set = tcg_target_available_regs[ts->type] & mask;
+}
+*pset = set;
+}
 }
 }
 
@@ -2445,16 +2492,23 @@ static void liveness_pass_1(TCGContext *s)
 int nb_globals = s->nb_globals;
 int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
+TCGRegSet *prefs;
+int i;
+
+prefs = tcg_malloc(sizeof(TCGRegSet) * nb_temps);
+for (i = 0; i < nb_temps; ++i) {
+s->temps[i].state_ptr = prefs + i;
+}
 
 /* ??? Should be redundant with the exit_tb that ends the TB.  */
 la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, TCGOpHead, link, op_prev) {
-int i, nb_iargs, nb_oargs;
+int nb_iargs, nb_oargs;
 TCGOpcode opc_new, opc_new2;
 bool have_opc_new2;
 TCGLifeData arg_life = 0;
-TCGTemp *arg_ts;
+TCGTemp *ts;
 TCGOpcode opc = op->opc;
 const TCGOpDef *def = &tcg_op_defs[opc];
 
@@ -2462,6 +2516,7 @@ static void liveness_pass_1(TCGContext *s)
 case INDEX_op_call:
 {
 int call_flags;
+int nb_call_regs;
 
 nb_oargs = TCGOP_CALLO(op);
 nb_iargs = TCGOP_CALLI(op);
@@ -2470,8 +2525,8 @@ static void liveness_pass_1(TCGContext *s)
 /* pure functions can be removed if their result is unused */
 if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
 for (i = 0; i < nb_oargs; i++) {
-arg_ts = arg_temp(op->args[i]);
-if (arg_ts->state != TS_DEAD) {
+ts = arg_temp(op->args[i]);
+if (ts->state != TS_DEAD) {
 goto do_not_remove_call;
 }
 }
@@ -2479,16 +2534,20 @@ static void liveness_pass_1(TCGContext *s)
 }
 do_not_remove_call:
 
-   

[Qemu-devel] [PATCH 02/12] tcg: Add preferred_reg argument to temp_load

2018-11-27 Thread Richard Henderson
Pass this through to tcg_reg_alloc.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index c596277fd0..7f29a2045a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2859,7 +2859,7 @@ static void temp_allocate_frame(TCGContext *s, TCGTemp 
*ts)
 s->current_frame_offset += sizeof(tcg_target_long);
 }
 
-static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet);
+static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, 
TCGRegSet);
 
 /* Mark a temporary as free or dead.  If 'free_or_dead' is negative,
mark it free; otherwise mark it dead.  */
@@ -2908,7 +2908,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts,
 break;
 }
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  allocated_regs);
+  allocated_regs, 0);
 /* fallthrough */
 
 case TEMP_VAL_REG:
@@ -3014,7 +3014,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet 
required_regs,
 /* Make sure the temporary is in a register.  If needed, allocate the register
from DESIRED while avoiding ALLOCATED.  */
 static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
-  TCGRegSet allocated_regs)
+  TCGRegSet allocated_regs, TCGRegSet preferred_regs)
 {
 TCGReg reg;
 
@@ -3023,13 +3023,13 @@ static void temp_load(TCGContext *s, TCGTemp *ts, 
TCGRegSet desired_regs,
 return;
 case TEMP_VAL_CONST:
 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
-0, ts->indirect_base);
+preferred_regs, ts->indirect_base);
 tcg_out_movi(s, ts->type, reg, ts->val);
 ts->mem_coherent = 0;
 break;
 case TEMP_VAL_MEM:
 reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
-0, ts->indirect_base);
+preferred_regs, ts->indirect_base);
 tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);
 ts->mem_coherent = 1;
 break;
@@ -3159,7 +3159,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */
 if (ts->val_type == TEMP_VAL_MEM) {
-temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs);
+temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs, 0);
 }
 
 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
@@ -3243,7 +3243,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 goto iarg_end;
 }
 
-temp_load(s, ts, arg_ct->u.regs, i_allocated_regs);
+temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, 0);
 
 if (arg_ct->ct & TCG_CT_IALIAS) {
 if (ts->fixed_reg) {
@@ -3424,7 +3424,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 if (arg != TCG_CALL_DUMMY_ARG) {
 ts = arg_temp(arg);
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  s->reserved_regs);
+  s->reserved_regs, 0);
 tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
 }
 #ifndef TCG_TARGET_STACK_GROWSUP
@@ -3449,7 +3449,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 TCGRegSet arg_set = 0;
 
 tcg_regset_set_reg(arg_set, reg);
-temp_load(s, ts, arg_set, allocated_regs);
+temp_load(s, ts, arg_set, allocated_regs, 0);
 }
 
 tcg_regset_set_reg(allocated_regs, reg);
-- 
2.17.2




[Qemu-devel] [PATCH 05/12] tcg: Add output_pref to TCGOp

2018-11-27 Thread Richard Henderson
Allocate storage for, but do not yet fill in, per-opcode
preferences for the output operands.  Pass it in to the
register allocation routines for output operands.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.h |  3 +++
 tcg/tcg.c | 18 +++---
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index c6caeeb42b..b2e274b7af 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -621,6 +621,9 @@ typedef struct TCGOp {
 
 /* Arguments for the opcode.  */
 TCGArg args[MAX_OPC_PARAM];
+
+/* Register preferences for the output(s).  */
+TCGRegSet output_pref[2];
 } TCGOp;
 
 #define TCGOP_CALLI(X)(X)->param1
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c83ca238aa..f86415ce29 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2613,6 +2613,8 @@ static void liveness_pass_1(TCGContext *s)
 break;
 }
 op->life = arg_life;
+op->output_pref[0] = 0;
+op->output_pref[1] = 0;
 }
 }
 
@@ -3127,17 +3129,18 @@ static void tcg_reg_alloc_movi(TCGContext *s, const 
TCGOp *op)
 TCGTemp *ots = arg_temp(op->args[0]);
 tcg_target_ulong val = op->args[1];
 
-tcg_reg_alloc_do_movi(s, ots, val, op->life, 0);
+tcg_reg_alloc_do_movi(s, ots, val, op->life, op->output_pref[0]);
 }
 
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
 {
 const TCGLifeData arg_life = op->life;
-TCGRegSet allocated_regs;
+TCGRegSet allocated_regs, preferred_regs;
 TCGTemp *ts, *ots;
 TCGType otype, itype;
 
 allocated_regs = s->reserved_regs;
+preferred_regs = op->output_pref[0];
 ots = arg_temp(op->args[0]);
 ts = arg_temp(op->args[1]);
 
@@ -3151,7 +3154,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 if (IS_DEAD_ARG(1)) {
 temp_dead(s, ts);
 }
-tcg_reg_alloc_do_movi(s, ots, val, arg_life, 0);
+tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
 return;
 }
 
@@ -3160,7 +3163,8 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */
 if (ts->val_type == TEMP_VAL_MEM) {
-temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs, 0);
+temp_load(s, ts, tcg_target_available_regs[itype],
+  allocated_regs, preferred_regs);
 }
 
 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
@@ -3190,7 +3194,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
input one. */
 tcg_regset_set_reg(allocated_regs, ts->reg);
 ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
- allocated_regs, 0,
+ allocated_regs, preferred_regs,
  ots->indirect_base);
 }
 tcg_out_mov(s, otype, ots->reg, ts->reg);
@@ -3324,7 +3328,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 } else if (arg_ct->ct & TCG_CT_NEWREG) {
 reg = tcg_reg_alloc(s, arg_ct->u.regs,
 i_allocated_regs | o_allocated_regs,
-0, ts->indirect_base);
+op->output_pref[k], ts->indirect_base);
 } else {
 /* if fixed register, we try to use it */
 reg = ts->reg;
@@ -,7 +3337,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 goto oarg_end;
 }
 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
-0, ts->indirect_base);
+op->output_pref[k], ts->indirect_base);
 }
 tcg_regset_set_reg(o_allocated_regs, reg);
 /* if a fixed register is used, then a move will be done 
afterwards */
-- 
2.17.2




[Qemu-devel] [PATCH 04/12] tcg: Add preferred_reg argument to tcg_reg_alloc_do_movi

2018-11-27 Thread Richard Henderson
Pass this through to temp_sync.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 509e5974bd..c83ca238aa 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3099,7 +3099,8 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet 
allocated_regs)
 }
 
 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
-  tcg_target_ulong val, TCGLifeData arg_life)
+  tcg_target_ulong val, TCGLifeData arg_life,
+  TCGRegSet preferred_regs)
 {
 if (ots->fixed_reg) {
 /* For fixed registers, we do not do any constant propagation.  */
@@ -3115,7 +3116,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp 
*ots,
 ots->val = val;
 ots->mem_coherent = 0;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
+temp_sync(s, ots, s->reserved_regs, preferred_regs, IS_DEAD_ARG(0));
 } else if (IS_DEAD_ARG(0)) {
 temp_dead(s, ots);
 }
@@ -3126,7 +3127,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp 
*op)
 TCGTemp *ots = arg_temp(op->args[0]);
 tcg_target_ulong val = op->args[1];
 
-tcg_reg_alloc_do_movi(s, ots, val, op->life);
+tcg_reg_alloc_do_movi(s, ots, val, op->life, 0);
 }
 
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
@@ -3150,7 +3151,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 if (IS_DEAD_ARG(1)) {
 temp_dead(s, ts);
 }
-tcg_reg_alloc_do_movi(s, ots, val, arg_life);
+tcg_reg_alloc_do_movi(s, ots, val, arg_life, 0);
 return;
 }
 
-- 
2.17.2




[Qemu-devel] [PATCH 06/12] tcg: Improve register allocation for matching constraints

2018-11-27 Thread Richard Henderson
Try harder to honor the output_pref.  When we're forced to allocate
a second register for the input, it does not need to use the input
constraint; that will be honored by the register we allocate for the
output and a move is already required.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 36 
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index f86415ce29..adf6570c36 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3235,6 +3235,8 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 
 /* satisfy input constraints */ 
 for (k = 0; k < nb_iargs; k++) {
+TCGRegSet i_preferred_regs, o_preferred_regs;
+
 i = def->sorted_args[nb_oargs + k];
 arg = op->args[i];
 arg_ct = &def->args_ct[i];
@@ -3245,17 +3247,18 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 /* constant is OK for instruction */
 const_args[i] = 1;
 new_args[i] = ts->val;
-goto iarg_end;
+continue;
 }
 
-temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, 0);
-
+i_preferred_regs = o_preferred_regs = 0;
 if (arg_ct->ct & TCG_CT_IALIAS) {
+o_preferred_regs = op->output_pref[arg_ct->alias_index];
 if (ts->fixed_reg) {
 /* if fixed register, we must allocate a new register
if the alias is not the same register */
-if (arg != op->args[arg_ct->alias_index])
+if (arg != op->args[arg_ct->alias_index]) {
 goto allocate_in_reg;
+}
 } else {
 /* if the input is aliased to an output and if it is
not dead after the instruction, we must allocate
@@ -3263,33 +3266,42 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 if (!IS_DEAD_ARG(i)) {
 goto allocate_in_reg;
 }
+
 /* check if the current register has already been allocated
for another input aliased to an output */
-int k2, i2;
-for (k2 = 0 ; k2 < k ; k2++) {
-i2 = def->sorted_args[nb_oargs + k2];
-if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
-(new_args[i2] == ts->reg)) {
-goto allocate_in_reg;
+if (ts->val_type == TEMP_VAL_REG) {
+int k2, i2;
+reg = ts->reg;
+for (k2 = 0 ; k2 < k ; k2++) {
+i2 = def->sorted_args[nb_oargs + k2];
+if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
+reg == new_args[i2]) {
+goto allocate_in_reg;
+}
 }
 }
+i_preferred_regs = o_preferred_regs;
 }
 }
+
+temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, i_preferred_regs);
 reg = ts->reg;
+
 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
 /* nothing to do : the constraint is satisfied */
 } else {
 allocate_in_reg:
 /* allocate a new register matching the constraint 
and move the temporary register into it */
+temp_load(s, ts, tcg_target_available_regs[ts->type],
+  i_allocated_regs, 0);
 reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs,
-0, ts->indirect_base);
+o_preferred_regs, ts->indirect_base);
 tcg_out_mov(s, ts->type, reg, ts->reg);
 }
 new_args[i] = reg;
 const_args[i] = 0;
 tcg_regset_set_reg(i_allocated_regs, reg);
-iarg_end: ;
 }
 
 /* mark dead temporaries and free the associated registers */
-- 
2.17.2




[Qemu-devel] [PATCH 03/12] tcg: Add preferred_reg argument to temp_sync

2018-11-27 Thread Richard Henderson
Pass this through to tcg_reg_alloc.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7f29a2045a..509e5974bd 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2887,8 +2887,8 @@ static inline void temp_dead(TCGContext *s, TCGTemp *ts)
registers needs to be allocated to store a constant.  If 'free_or_dead'
is non-zero, subsequently release the temporary; if it is positive, the
temp is dead; if it is negative, the temp is free.  */
-static void temp_sync(TCGContext *s, TCGTemp *ts,
-  TCGRegSet allocated_regs, int free_or_dead)
+static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
+  TCGRegSet preferred_regs, int free_or_dead)
 {
 if (ts->fixed_reg) {
 return;
@@ -2908,7 +2908,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts,
 break;
 }
 temp_load(s, ts, tcg_target_available_regs[ts->type],
-  allocated_regs, 0);
+  allocated_regs, preferred_regs);
 /* fallthrough */
 
 case TEMP_VAL_REG:
@@ -2935,7 +2935,7 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, 
TCGRegSet allocated_regs)
 {
 TCGTemp *ts = s->reg_to_temp[reg];
 if (ts != NULL) {
-temp_sync(s, ts, allocated_regs, -1);
+temp_sync(s, ts, allocated_regs, 0, -1);
 }
 }
 
@@ -3115,7 +3115,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp 
*ots,
 ots->val = val;
 ots->mem_coherent = 0;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, s->reserved_regs, IS_DEAD_ARG(0));
+temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
 } else if (IS_DEAD_ARG(0)) {
 temp_dead(s, ots);
 }
@@ -3198,7 +3198,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 ots->mem_coherent = 0;
 s->reg_to_temp[ots->reg] = ots;
 if (NEED_SYNC_ARG(0)) {
-temp_sync(s, ots, allocated_regs, 0);
+temp_sync(s, ots, allocated_regs, 0, 0);
 }
 }
 }
@@ -3368,7 +3368,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 tcg_out_mov(s, ts->type, ts->reg, reg);
 }
 if (NEED_SYNC_ARG(i)) {
-temp_sync(s, ts, o_allocated_regs, IS_DEAD_ARG(i));
+temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
 } else if (IS_DEAD_ARG(i)) {
 temp_dead(s, ts);
 }
@@ -3502,7 +3502,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 ts->mem_coherent = 0;
 s->reg_to_temp[reg] = ts;
 if (NEED_SYNC_ARG(i)) {
-temp_sync(s, ts, allocated_regs, IS_DEAD_ARG(i));
+temp_sync(s, ts, allocated_regs, 0, IS_DEAD_ARG(i));
 } else if (IS_DEAD_ARG(i)) {
 temp_dead(s, ts);
 }
-- 
2.17.2




[Qemu-devel] [PATCH 00/12] tcg: Improve register allocation for calls

2018-11-27 Thread Richard Henderson
The intent here is to remove several move insns putting the
function arguments into the proper place.  I'm hoping that
this will solve the skylake regression with spec2006, as
seen with the ool softmmu patch set.

Emilio, all of this is present on my tcg-next-for-4.0 branch.


r~


Richard Henderson (12):
  tcg: Add preferred_reg argument to tcg_reg_alloc
  tcg: Add preferred_reg argument to temp_load
  tcg: Add preferred_reg argument to temp_sync
  tcg: Add preferred_reg argument to tcg_reg_alloc_do_movi
  tcg: Add output_pref to TCGOp
  tcg: Improve register allocation for matching constraints
  tcg: Dump register preference info with liveness
  tcg: Reindent parts of liveness_pass_1
  tcg: Rename and adjust liveness_pass_1 helpers
  tcg: Split out more subroutines from liveness_pass_1
  tcg: Add TCG_OPF_BB_EXIT
  tcg: Record register preferences during liveness

 tcg/tcg-opc.h |   7 +-
 tcg/tcg.h |  20 +-
 tcg/tcg.c | 527 +-
 3 files changed, 405 insertions(+), 149 deletions(-)

-- 
2.17.2




[Qemu-devel] [PATCH 01/12] tcg: Add preferred_reg argument to tcg_reg_alloc

2018-11-27 Thread Richard Henderson
This new argument will aid register allocation by indicating how
the temporary will be used in future.  If the preference cannot
be satisfied, fall back to the constraints of the current insn.

Short circuit the preference when it cannot be satisfied or if
it does not further constrain the operation.

With an eye toward optimizing function call sequences, optimize
for the preferred_reg set containing a single register.

For the moment, all users pass 0 for preference.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 103 ++
 1 file changed, 81 insertions(+), 22 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 8734389ba9..c596277fd0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1907,6 +1907,20 @@ static const char * const alignment_name[(MO_AMASK >> 
MO_ASHIFT) + 1] = {
 [MO_ALIGN_64 >> MO_ASHIFT] = "al64+",
 };
 
+static inline bool tcg_regset_single(TCGRegSet d)
+{
+return (d & (d - 1)) == 0;
+}
+
+static inline TCGReg tcg_regset_first(TCGRegSet d)
+{
+if (TCG_TARGET_NB_REGS <= 32) {
+return ctz32(d);
+} else {
+return ctz64(d);
+}
+}
+
 void tcg_dump_ops(TCGContext *s)
 {
 char buf[128];
@@ -1922,6 +1936,7 @@ void tcg_dump_ops(TCGContext *s)
 def = &tcg_op_defs[c];
 
 if (c == INDEX_op_insn_start) {
+nb_oargs = 0;
 col += qemu_log("\n ");
 
 for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
@@ -2924,31 +2939,72 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, 
TCGRegSet allocated_regs)
 }
 }
 
-/* Allocate a register belonging to reg1 & ~reg2 */
-static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
-TCGRegSet allocated_regs, bool rev)
+/**
+ * tcg_reg_alloc:
+ * @required_regs: Set of registers in which we must allocate.
+ * @allocated_regs: Set of registers which must be avoided.
+ * @preferred_regs: Set of registers we should prefer.
+ * @rev: True if we search the registers in "indirect" order.
+ *
+ * The allocated register must be in @required_regs & ~@allocated_regs,
+ * but if we can put it in @preferred_regs we may save a move later.
+ */
+static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
+TCGRegSet allocated_regs,
+TCGRegSet preferred_regs, bool rev)
 {
-int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
+int i, j, f, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
+TCGRegSet reg_ct[2];
 const int *order;
-TCGReg reg;
-TCGRegSet reg_ct;
 
-reg_ct = desired_regs & ~allocated_regs;
+reg_ct[1] = required_regs & ~allocated_regs;
+tcg_debug_assert(reg_ct[1] != 0);
+reg_ct[0] = reg_ct[1] & preferred_regs;
+
+/* Skip the preferred_regs option if it cannot be satisfied,
+   or if the preference made no difference.  */
+f = reg_ct[0] == 0 || reg_ct[0] == reg_ct[1];
+
 order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
 
-/* first try free registers */
-for(i = 0; i < n; i++) {
-reg = order[i];
-if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
-return reg;
+/* Try free registers, preferences first.  */
+for (j = f; j < 2; j++) {
+TCGRegSet set = reg_ct[j];
+
+if (tcg_regset_single(set)) {
+/* One register in the set.  */
+TCGReg reg = tcg_regset_first(set);
+if (s->reg_to_temp[reg] == NULL) {
+return reg;
+}
+} else {
+for (i = 0; i < n; i++) {
+TCGReg reg = order[i];
+if (s->reg_to_temp[reg] == NULL &&
+tcg_regset_test_reg(set, reg)) {
+return reg;
+}
+}
+}
 }
 
-/* XXX: do better spill choice */
-for(i = 0; i < n; i++) {
-reg = order[i];
-if (tcg_regset_test_reg(reg_ct, reg)) {
+/* We must spill something.  */
+for (j = f; j < 2; j++) {
+TCGRegSet set = reg_ct[j];
+
+if (tcg_regset_single(set)) {
+/* One register in the set.  */
+TCGReg reg = tcg_regset_first(set);
 tcg_reg_free(s, reg, allocated_regs);
 return reg;
+} else {
+for (i = 0; i < n; i++) {
+TCGReg reg = order[i];
+if (tcg_regset_test_reg(set, reg)) {
+tcg_reg_free(s, reg, allocated_regs);
+return reg;
+}
+}
 }
 }
 
@@ -2966,12 +3022,14 @@ static void temp_load(TCGContext *s, TCGTemp *ts, 
TCGRegSet desired_regs,
 case TEMP_VAL_REG:
 return;
 case TEMP_VAL_CONST:
-reg = tcg_reg_alloc(s, desired_regs, allocated_regs, 
ts->indirect_base);
+reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
+0, ts->indirect_base);
 tcg_out_movi(s, ts->type, 

[Qemu-devel] [PATCH 11/12] tcg: Add TCG_OPF_BB_EXIT

2018-11-27 Thread Richard Henderson
Use this to notice the opcodes that exit the TB, which implies
that local temps are really dead and need not be synced.

Previously we so marked the true end of the TB, but that was
immediately overwritten by the la_bb_end invoked by any
TCG_OPF_BB_END opcode, like exit_tb.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-opc.h |  7 ---
 tcg/tcg.h | 14 --
 tcg/tcg.c |  5 -
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index e3a43aabb6..7a8a3edb5b 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -191,9 +191,10 @@ DEF(mulsh_i64, 1, 2, 0, IMPL64 | 
IMPL(TCG_TARGET_HAS_mulsh_i64))
 /* QEMU specific */
 DEF(insn_start, 0, 0, TLADDR_ARGS * TARGET_INSN_START_WORDS,
 TCG_OPF_NOT_PRESENT)
-DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
+DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_ptr, 0, 1, 0,
+TCG_OPF_BB_EXIT | TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
 
 DEF(qemu_ld_i32, 1, TLADDR_ARGS, 1,
 TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index ac5d01c223..abbf9c836a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1037,20 +1037,22 @@ typedef struct TCGArgConstraint {
 
 /* Bits for TCGOpDef->flags, 8 bits available.  */
 enum {
+/* Instruction exits the translation block.  */
+TCG_OPF_BB_EXIT  = 0x01,
 /* Instruction defines the end of a basic block.  */
-TCG_OPF_BB_END   = 0x01,
+TCG_OPF_BB_END   = 0x02,
 /* Instruction clobbers call registers and potentially update globals.  */
-TCG_OPF_CALL_CLOBBER = 0x02,
+TCG_OPF_CALL_CLOBBER = 0x04,
 /* Instruction has side effects: it cannot be removed if its outputs
are not used, and might trigger exceptions.  */
-TCG_OPF_SIDE_EFFECTS = 0x04,
+TCG_OPF_SIDE_EFFECTS = 0x08,
 /* Instruction operands are 64-bits (otherwise 32-bits).  */
-TCG_OPF_64BIT= 0x08,
+TCG_OPF_64BIT= 0x10,
 /* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemened by the host.  */
-TCG_OPF_NOT_PRESENT  = 0x10,
+TCG_OPF_NOT_PRESENT  = 0x20,
 /* Instruction operands are vectors.  */
-TCG_OPF_VECTOR   = 0x20,
+TCG_OPF_VECTOR   = 0x40,
 };
 
 typedef struct TCGOpDef {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 21668831a1..673aaf52a1 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2446,6 +2446,7 @@ static void liveness_pass_1(TCGContext *s)
 int nb_temps = s->nb_temps;
 TCGOp *op, *op_prev;
 
+/* ??? Should be redundant with the exit_tb that ends the TB.  */
 la_func_end(s, nb_globals, nb_temps);
 
 QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, TCGOpHead, link, op_prev) {
@@ -2634,7 +2635,9 @@ static void liveness_pass_1(TCGContext *s)
 }
 
 /* if end of basic block, update */
-if (def->flags & TCG_OPF_BB_END) {
+if (def->flags & TCG_OPF_BB_EXIT) {
+la_func_end(s, nb_globals, nb_temps);
+} else if (def->flags & TCG_OPF_BB_END) {
 la_bb_end(s, nb_globals, nb_temps);
 } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
 la_global_sync(s, nb_globals);
-- 
2.17.2




Re: [Qemu-devel] [PATCH v9 5/8] migration/ram.c: add a notifier chain for precopy

2018-11-27 Thread Peter Xu
On Tue, Nov 27, 2018 at 06:25:40PM +0800, Wei Wang wrote:
> On 11/27/2018 03:38 PM, Peter Xu wrote:
> > On Thu, Nov 15, 2018 at 06:08:01PM +0800, Wei Wang wrote:
> > > +typedef enum PrecopyNotifyReason {
> > > +PRECOPY_NOTIFY_ERR = 0,
> > > +PRECOPY_NOTIFY_START_ITERATION = 1,
> > > +PRECOPY_NOTIFY_BEFORE_SYNC_BITMAP = 2,
> > > +PRECOPY_NOTIFY_AFTER_SYNC_BITMAP = 3,
> > > +PRECOPY_NOTIFY_MAX = 4,
> > It would be nice to add some comments for each of the notify reason.
> > E.g., from the name PRECOPY_NOTIFY_START_ITERATION seems more like a
> > hook at the start of each iteration but according to [1] it should be
> > at the start of migration rather than each iteration (or when
> > migration restarts, though I'm not sure whether we really have this
> > yet).
> 
> OK. I think It would be better if the name itself could be straightforward.
> Probably we could change PRECOPY_NOTIFY_START_ITERATION to
> PRECOPY_NOTIFY_START_MIGRATION.

Sounds good.

> 
> 
> > > +} PrecopyNotifyReason;
> > > +
> > > +void precopy_infrastructure_init(void);
> > > +void precopy_add_notifier(Notifier *n);
> > > +void precopy_remove_notifier(Notifier *n);
> > > +
> > >   void ram_mig_init(void);
> > >   void qemu_guest_free_page_hint(void *addr, size_t len);
> > > diff --git a/migration/ram.c b/migration/ram.c
> > > index 229b791..65b1223 100644
> > > --- a/migration/ram.c
> > > +++ b/migration/ram.c
> > > @@ -292,6 +292,8 @@ struct RAMState {
> > >   bool ram_bulk_stage;
> > >   /* How many times we have dirty too many pages */
> > >   int dirty_rate_high_cnt;
> > > +/* ram save states used for notifiers */
> > > +int ram_save_state;
> > This can be removed?
> 
> Yes, thanks.
> 
> > 
> > >   /* these variables are used for bitmap sync */
> > >   /* last time we did a full bitmap_sync */
> > >   int64_t time_last_bitmap_sync;
> > > @@ -328,6 +330,28 @@ typedef struct RAMState RAMState;
> > >   static RAMState *ram_state;
> > > +static NotifierList precopy_notifier_list;
> > > +
> > > +void precopy_infrastructure_init(void)
> > > +{
> > > +notifier_list_init(&precopy_notifier_list);
> > > +}
> > > +
> > > +void precopy_add_notifier(Notifier *n)
> > > +{
> > > +notifier_list_add(&precopy_notifier_list, n);
> > > +}
> > > +
> > > +void precopy_remove_notifier(Notifier *n)
> > > +{
> > > +notifier_remove(n);
> > > +}
> > > +
> > > +static void precopy_notify(PrecopyNotifyReason reason)
> > > +{
> > > +notifier_list_notify(&precopy_notifier_list, &reason);
> > > +}
> > > +
> > >   uint64_t ram_bytes_remaining(void)
> > >   {
> > >   return ram_state ? (ram_state->migration_dirty_pages * 
> > > TARGET_PAGE_SIZE) :
> > > @@ -1642,6 +1666,8 @@ static void migration_bitmap_sync(RAMState *rs)
> > >   int64_t end_time;
> > >   uint64_t bytes_xfer_now;
> > > +precopy_notify(PRECOPY_NOTIFY_BEFORE_SYNC_BITMAP);
> > > +
> > >   ram_counters.dirty_sync_count++;
> > >   if (!rs->time_last_bitmap_sync) {
> > > @@ -1699,6 +1725,8 @@ static void migration_bitmap_sync(RAMState *rs)
> > >   if (migrate_use_events()) {
> > >   qapi_event_send_migration_pass(ram_counters.dirty_sync_count);
> > >   }
> > > +
> > > +precopy_notify(PRECOPY_NOTIFY_AFTER_SYNC_BITMAP);
> > >   }
> > >   /**
> > > @@ -2555,6 +2583,8 @@ static void ram_state_reset(RAMState *rs)
> > >   rs->last_page = 0;
> > >   rs->last_version = ram_list.version;
> > >   rs->ram_bulk_stage = true;
> > > +
> > > +precopy_notify(PRECOPY_NOTIFY_START_ITERATION);
> > [1]
> > 
> > >   }
> > >   #define MAX_WAIT 50 /* ms, half buffered_file limit */
> > > @@ -3324,6 +3354,7 @@ out:
> > >   ret = qemu_file_get_error(f);
> > >   if (ret < 0) {
> > > +precopy_notify(PRECOPY_NOTIFY_ERR);
> > Could you show me which function is this line in?
> > 
> > Line 3324 here is ram_save_complete(), but I cannot find this exact
> > place.
> 
> Sure, it's in ram_save_iterate():
> ...
> out:
> qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
> qemu_fflush(f);
> ram_counters.transferred += 8;
> 
> ret = qemu_file_get_error(f);
> if (ret < 0) {
> +precopy_notify(PRECOPY_NOTIFY_ERR);
> return ret;
> }
> 
> return done;
> }

Ok thanks.  Please just make sure you will capture all the error
cases, e.g., I also see path like this (a few lines below):

if (pages < 0) {
qemu_file_set_error(f, pages);
break;
}

It seems that you missed that one.

I would even suggest that you capture the error with higher level.
E.g., in migration_iteration_run() after qemu_savevm_state_iterate().
Or we can just check the return value of qemu_savevm_state_iterate(),
which we have had ignored so far.

[1]

> 
> 
> > 
> > Another thing to mention about the "reasons" (though I see it more
> > like "events"): have you thought about adding a PRECOPY_NOTIFY_END?
> > It might help in some cases:
> > 
> >- then you don't need to trickily

Re: [Qemu-devel] [PATCH v5 20/36] spapr: add classes for the XIVE models

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:13AM +0100, Cédric Le Goater wrote:
> The XIVE models for the QEMU and KVM accelerators will have a lot in
> common. Introduce an abstract class for the source, the thread context
> and the interrupt controller object to handle the differences in the
> object initialization. These classes will also be used to define state
> synchronization handlers for the monitor and migration usage.
> 
> This is very much like the XICS models.

Yeah.. so I know it's my code, but in hindsight I think making
separate subclasses for TCG and KVM was a mistake.  The distinction
between emulated and KVM version is supposed to be invisible to both
guest and (almost) to user, whereas a subclass usually indicates a
visibly different device.

> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr_xive.h |  15 +
>  include/hw/ppc/xive.h   |  30 ++
>  hw/intc/spapr_xive.c|  86 +++-
>  hw/intc/xive.c  | 109 +---
>  hw/ppc/spapr_irq.c  |   4 +-
>  5 files changed, 182 insertions(+), 62 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 5b3fab192d41..aca2969a09ab 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -13,6 +13,10 @@
>  #include "hw/sysbus.h"
>  #include "hw/ppc/xive.h"
>  
> +#define TYPE_SPAPR_XIVE_BASE "spapr-xive-base"
> +#define SPAPR_XIVE_BASE(obj) \
> +OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE_BASE)
> +
>  #define TYPE_SPAPR_XIVE "spapr-xive"
>  #define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE)
>  
> @@ -38,6 +42,17 @@ typedef struct sPAPRXive {
>  MemoryRegion  tm_mmio;
>  } sPAPRXive;
>  
> +#define SPAPR_XIVE_BASE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(sPAPRXiveClass, (klass), TYPE_SPAPR_XIVE_BASE)
> +#define SPAPR_XIVE_BASE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(sPAPRXiveClass, (obj), TYPE_SPAPR_XIVE_BASE)
> +
> +typedef struct sPAPRXiveClass {
> +XiveRouterClass parent_class;
> +
> +DeviceRealize   parent_realize;
> +} sPAPRXiveClass;
> +
>  bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi);
>  bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn);
>  void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index b74eb326dcd1..281ed370121c 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -38,6 +38,10 @@ typedef struct XiveFabricClass {
>   * XIVE Interrupt Source
>   */
>  
> +#define TYPE_XIVE_SOURCE_BASE "xive-source-base"
> +#define XIVE_SOURCE_BASE(obj) \
> +OBJECT_CHECK(XiveSource, (obj), TYPE_XIVE_SOURCE_BASE)
> +
>  #define TYPE_XIVE_SOURCE "xive-source"
>  #define XIVE_SOURCE(obj) OBJECT_CHECK(XiveSource, (obj), TYPE_XIVE_SOURCE)
>  
> @@ -68,6 +72,18 @@ typedef struct XiveSource {
>  XiveFabric  *xive;
>  } XiveSource;
>  
> +#define XIVE_SOURCE_BASE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(XiveSourceClass, (klass), TYPE_XIVE_SOURCE_BASE)
> +#define XIVE_SOURCE_BASE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(XiveSourceClass, (obj), TYPE_XIVE_SOURCE_BASE)
> +
> +typedef struct XiveSourceClass {
> +SysBusDeviceClass parent_class;
> +
> +DeviceRealize parent_realize;
> +DeviceReset   parent_reset;
> +} XiveSourceClass;
> +
>  /*
>   * ESB MMIO setting. Can be one page, for both source triggering and
>   * source management, or two different pages. See below for magic
> @@ -253,6 +269,9 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t 
> end_idx, Monitor *mon);
>   * XIVE Thread interrupt Management (TM) context
>   */
>  
> +#define TYPE_XIVE_TCTX_BASE "xive-tctx-base"
> +#define XIVE_TCTX_BASE(obj) OBJECT_CHECK(XiveTCTX, (obj), 
> TYPE_XIVE_TCTX_BASE)
> +
>  #define TYPE_XIVE_TCTX "xive-tctx"
>  #define XIVE_TCTX(obj) OBJECT_CHECK(XiveTCTX, (obj), TYPE_XIVE_TCTX)
>  
> @@ -278,6 +297,17 @@ typedef struct XiveTCTX {
>  XiveRouter  *xrtr;
>  } XiveTCTX;
>  
> +#define XIVE_TCTX_BASE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(XiveTCTXClass, (klass), TYPE_XIVE_TCTX_BASE)
> +#define XIVE_TCTX_BASE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(XiveTCTXClass, (obj), TYPE_XIVE_TCTX_BASE)
> +
> +typedef struct XiveTCTXClass {
> +DeviceClass   parent_class;
> +
> +DeviceRealize parent_realize;
> +} XiveTCTXClass;
> +
>  /*
>   * XIVE Thread Interrupt Management Aera (TIMA)
>   */
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 3bf77ace11a2..ec85f7e4f88d 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -53,9 +53,9 @@ static void spapr_xive_mmio_map(sPAPRXive *xive)
>  sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->tm_base);
>  }
>  
> -static void spapr_xive_reset(DeviceState *dev)
> +static void spapr_xive_base_reset(DeviceState *dev)
>  {
> -sPAPRXive *xive = SPAPR_XIVE(dev);
> +sPAPRXive *xive = SPAPR_XIVE_BASE(dev);
>  int i;
>

Re: [Qemu-devel] [PATCH v5 18/36] spapr: allocate the interrupt thread context under the CPU core

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:11AM +0100, Cédric Le Goater wrote:
> Each interrupt mode has its own specific interrupt presenter object,
> that we store under the CPU object, one for XICS and one for XIVE.
> 
> Extend the sPAPR IRQ backend with a new handler to support them both.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  include/hw/ppc/spapr.h |  1 +
>  include/hw/ppc/spapr_irq.h |  2 ++
>  include/hw/ppc/xive.h  |  2 ++
>  hw/intc/xive.c | 21 +
>  hw/ppc/spapr_cpu_core.c|  5 ++---
>  hw/ppc/spapr_irq.c | 17 +
>  6 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 8415faea7b82..f43ef69d61bc 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -177,6 +177,7 @@ struct sPAPRMachineState {
>  int32_t irq_map_nr;
>  unsigned long *irq_map;
>  sPAPRXive  *xive;
> +const char *xive_tctx_type;
>  
>  bool cmd_line_caps[SPAPR_CAP_NUM];
>  sPAPRCapabilities def, eff, mig;
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index cfdc1f86e713..c3b4c38145eb 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -42,6 +42,8 @@ typedef struct sPAPRIrq {
>  void (*print_info)(sPAPRMachineState *spapr, Monitor *mon);
>  void (*dt_populate)(sPAPRMachineState *spapr, uint32_t nr_servers,
>  void *fdt, uint32_t phandle);
> +Object *(*cpu_intc_create)(sPAPRMachineState *spapr, Object *cpu,
> +   Error **errp);
>  } sPAPRIrq;
>  
>  extern sPAPRIrq spapr_irq_xics;
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index e6931ddaa83f..b74eb326dcd1 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -284,6 +284,8 @@ typedef struct XiveTCTX {
>  extern const MemoryRegionOps xive_tm_ops;
>  
>  void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
> +Object *xive_tctx_create(Object *cpu, const char *type, XiveRouter *xrtr,
> + Error **errp);
>  
>  static inline uint32_t xive_tctx_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
>  {
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index fc6ef5895e6d..7d921023e2ee 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -579,6 +579,27 @@ static const TypeInfo xive_tctx_info = {
>  .class_init= xive_tctx_class_init,
>  };
>  
> +Object *xive_tctx_create(Object *cpu, const char *type, XiveRouter *xrtr,
> + Error **errp)
> +{
> +Error *local_err = NULL;
> +Object *obj;
> +
> +obj = object_new(type);
> +object_property_add_child(cpu, type, obj, &error_abort);
> +object_unref(obj);
> +object_property_add_const_link(obj, "cpu", cpu, &error_abort);
> +object_property_add_const_link(obj, "xive", OBJECT(xrtr), &error_abort);
> +object_property_set_bool(obj, true, "realized", &local_err);
> +if (local_err) {
> +object_unparent(obj);
> +error_propagate(errp, local_err);
> +return NULL;
> +}
> +
> +return obj;
> +}
> +
>  /*
>   * XIVE ESB helpers
>   */
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 2398ce62c0e7..1811cd48db90 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -11,7 +11,6 @@
>  #include "hw/ppc/spapr_cpu_core.h"
>  #include "target/ppc/cpu.h"
>  #include "hw/ppc/spapr.h"
> -#include "hw/ppc/xics.h" /* for icp_create() - to be removed */
>  #include "hw/boards.h"
>  #include "qapi/error.h"
>  #include "sysemu/cpus.h"
> @@ -215,6 +214,7 @@ static void spapr_cpu_core_unrealize(DeviceState *dev, 
> Error **errp)
>  static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr,
> sPAPRCPUCore *sc, Error **errp)
>  {
> +sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>  CPUPPCState *env = &cpu->env;
>  CPUState *cs = CPU(cpu);
>  Error *local_err = NULL;
> @@ -233,8 +233,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, 
> sPAPRMachineState *spapr,
>  qemu_register_reset(spapr_cpu_reset, cpu);
>  spapr_cpu_reset(cpu);
>  
> -cpu->intc = icp_create(OBJECT(cpu), spapr->icp_type, XICS_FABRIC(spapr),
> -   &local_err);
> +cpu->intc = smc->irq->cpu_intc_create(spapr, OBJECT(cpu), &local_err);
>  if (local_err) {
>  goto error_unregister;
>  }
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index d88a029d8c5c..253abc10e780 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -197,6 +197,12 @@ static void spapr_irq_dt_populate_xics(sPAPRMachineState 
> *spapr,
>  spapr_dt_xics(nr_servers, fdt, phandle);
>  }
>  
> +static Object *spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
> +  Object *cpu, Error **errp)
> +{
> +return icp_create(cpu, spapr->icp_ty

Re: [Qemu-devel] [PATCH v5 19/36] spapr: add a 'pseries-3.1-xive' machine type

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:12AM +0100, Cédric Le Goater wrote:
> The interrupt mode is statically defined to XIVE only for this machine.
> The guest OS is required to have support for the XIVE exploitation
> mode of the POWER9 interrupt controller.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr_irq.h |  1 +
>  hw/ppc/spapr.c | 36 +++-
>  hw/ppc/spapr_irq.c |  3 +++
>  3 files changed, 35 insertions(+), 5 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index c3b4c38145eb..b299dd794bff 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -33,6 +33,7 @@ void spapr_irq_msi_reset(sPAPRMachineState *spapr);
>  typedef struct sPAPRIrq {
>  uint32_tnr_irqs;
>  uint32_tnr_msis;
> +uint8_t ov5;

I'm a bit confused as to what exactly this represents..

>  void (*init)(sPAPRMachineState *spapr, int nr_irqs, int nr_servers,
>   Error **errp);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index ad1692cdcd0f..8fbb743769db 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1097,12 +1097,14 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, 
> void *fdt)
>  spapr_dt_rtas_tokens(fdt, rtas);
>  }
>  
> -/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU features
> - * that the guest may request and thus the valid values for bytes 24..26 of
> - * option vector 5: */
> -static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
> +/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU
> + * and the XIVE features that the guest may request and thus the valid
> + * values for bytes 23..26 of option vector 5: */
> +static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void 
> *fdt,
> +  int chosen)
>  {
>  PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
> +sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>  
>  char val[2 * 4] = {
>  23, 0x00, /* Xive mode, filled in below. */
> @@ -1123,7 +1125,11 @@ static void spapr_dt_ov5_platform_support(void *fdt, 
> int chosen)
>  } else {
>  val[3] = 0x00; /* Hash */
>  }
> +/* TODO: test KVM support */
> +val[1] = smc->irq->ov5;
>  } else {
> +val[1] = smc->irq->ov5;

..here it seems to be a specific value for this OV5 byte, indicating the
supported intc...

> +
>  /* V3 MMU supports both hash and radix in tcg (with dynamic 
> switching) */
>  val[3] = 0xC0;
>  }
> @@ -1191,7 +1197,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, 
> void *fdt)
>  _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path));
>  }
>  
> -spapr_dt_ov5_platform_support(fdt, chosen);
> +spapr_dt_ov5_platform_support(spapr, fdt, chosen);
>  
>  g_free(stdout_path);
>  g_free(bootlist);
> @@ -2622,6 +2628,11 @@ static void spapr_machine_init(MachineState *machine)
>  /* advertise support for ibm,dyamic-memory-v2 */
>  spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
>  
> +/* advertise XIVE */
> +if (smc->irq->ov5) {

..but here it seems to be a bool indicating XIVE support specifically.

> +spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
> +}
> +
>  /* init CPUs */
>  spapr_init_cpus(spapr);
>  
> @@ -3971,6 +3982,21 @@ static void 
> spapr_machine_3_1_class_options(MachineClass *mc)
>  
>  DEFINE_SPAPR_MACHINE(3_1, "3.1", true);
>  
> +static void spapr_machine_3_1_xive_instance_options(MachineState *machine)
> +{
> +spapr_machine_3_1_instance_options(machine);
> +}
> +
> +static void spapr_machine_3_1_xive_class_options(MachineClass *mc)
> +{
> +sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
> +
> +spapr_machine_3_1_class_options(mc);
> +smc->irq = &spapr_irq_xive;
> +}
> +
> +DEFINE_SPAPR_MACHINE(3_1_xive, "3.1-xive", false);
> +
>  /*
>   * pseries-3.0
>   */
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 253abc10e780..42e73851b174 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -210,6 +210,7 @@ static Object 
> *spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
>  sPAPRIrq spapr_irq_xics = {
>  .nr_irqs = SPAPR_IRQ_XICS_NR_IRQS,
>  .nr_msis = SPAPR_IRQ_XICS_NR_MSIS,
> +.ov5 = 0x0, /* XICS only */
>  
>  .init= spapr_irq_init_xics,
>  .claim   = spapr_irq_claim_xics,
> @@ -341,6 +342,7 @@ static Object 
> *spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
>  sPAPRIrq spapr_irq_xive = {
>  .nr_irqs = SPAPR_IRQ_XIVE_NR_IRQS,
>  .nr_msis = SPAPR_IRQ_XIVE_NR_MSIS,
> +.ov5 = 0x40, /* XIVE exploitation mode only */
>  
>  .init= spapr_irq_init_xive,
>  .claim   = spapr_irq_claim_xive,
> @@ -447,6 +449,7 @@ int spapr_irq_find(sPAPRMachineState *spapr, int num, 
> bool align, Error **er

Re: [Qemu-devel] [PATCH v5 17/36] spapr: add device tree support for the XIVE exploitation mode

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:10AM +0100, Cédric Le Goater wrote:
> The XIVE interface for the guest is described in the device tree under
> the "interrupt-controller" node. A couple of new properties are
> specific to XIVE :
> 
>  - "reg"
> 
>contains the base address and size of the thread interrupt
>managnement areas (TIMA), for the User level and for the Guest OS
>level. Only the Guest OS level is taken into account today.
> 
>  - "ibm,xive-eq-sizes"
> 
>the size of the event queues. One cell per size supported, contains
>log2 of size, in ascending order.
> 
>  - "ibm,xive-lisn-ranges"
> 
>the IRQ interrupt number ranges assigned to the guest for the IPIs.
> 
> and also under the root node :
> 
>  - "ibm,plat-res-int-priorities"
> 
>contains a list of priorities that the hypervisor has reserved for
>its own use. OPAL uses the priority 7 queue to automatically
>escalate interrupts for all other queues (DD2.X POWER9). So only
>priorities [0..6] are allowed for the guest.
> 
> Extend the sPAPR IRQ backend with a new handler to populate the DT
> with the appropriate "interrupt-controller" node.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr_irq.h  |  2 ++
>  include/hw/ppc/spapr_xive.h |  2 ++
>  hw/intc/spapr_xive_hcall.c  | 62 +
>  hw/ppc/spapr.c  |  3 +-
>  hw/ppc/spapr_irq.c  | 17 ++
>  5 files changed, 85 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index c854ae527808..cfdc1f86e713 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -40,6 +40,8 @@ typedef struct sPAPRIrq {
>  void (*free)(sPAPRMachineState *spapr, int irq, int num);
>  qemu_irq (*qirq)(sPAPRMachineState *spapr, int irq);
>  void (*print_info)(sPAPRMachineState *spapr, Monitor *mon);
> +void (*dt_populate)(sPAPRMachineState *spapr, uint32_t nr_servers,
> +void *fdt, uint32_t phandle);
>  } sPAPRIrq;
>  
>  extern sPAPRIrq spapr_irq_xics;
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 418511f3dc10..5b3fab192d41 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -65,5 +65,7 @@ bool spapr_xive_priority_is_valid(uint8_t priority);
>  typedef struct sPAPRMachineState sPAPRMachineState;
>  
>  void spapr_xive_hcall_init(sPAPRMachineState *spapr);
> +void spapr_dt_xive(sPAPRXive *xive, int nr_servers, void *fdt,
> +   uint32_t phandle);
>  
>  #endif /* PPC_SPAPR_XIVE_H */
> diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c
> index 52e4e23995f5..66c78aa88500 100644
> --- a/hw/intc/spapr_xive_hcall.c
> +++ b/hw/intc/spapr_xive_hcall.c
> @@ -890,3 +890,65 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr)
>  spapr_register_hypercall(H_INT_SYNC, h_int_sync);
>  spapr_register_hypercall(H_INT_RESET, h_int_reset);
>  }
> +
> +void spapr_dt_xive(sPAPRXive *xive, int nr_servers, void *fdt, uint32_t 
> phandle)
> +{
> +int node;
> +uint64_t timas[2 * 2];
> +/* Interrupt number ranges for the IPIs */
> +uint32_t lisn_ranges[] = {
> +cpu_to_be32(0),
> +cpu_to_be32(nr_servers),
> +};
> +uint32_t eq_sizes[] = {
> +cpu_to_be32(12), /* 4K */
> +cpu_to_be32(16), /* 64K */
> +cpu_to_be32(21), /* 2M */
> +cpu_to_be32(24), /* 16M */
> +};
> +/* The following array is in sync with the 'spapr_xive_priority_is_valid'
> + * routine above. The O/S is expected to choose priority 6.
> + */
> +uint32_t plat_res_int_priorities[] = {
> +cpu_to_be32(7),/* start */
> +cpu_to_be32(0xf8), /* count */
> +};
> +gchar *nodename;
> +
> +/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
> +timas[0] = cpu_to_be64(xive->tm_base + 3 * (1ull << TM_SHIFT));
> +timas[1] = cpu_to_be64(1ull << TM_SHIFT);
> +timas[2] = cpu_to_be64(xive->tm_base + 2 * (1ull << TM_SHIFT));

Don't you have symbolic constants for the ring numbers, instead of '2'
and '3' above?

> +timas[3] = cpu_to_be64(1ull << TM_SHIFT);
> +
> +nodename = g_strdup_printf("interrupt-controller@%" PRIx64,
> +   xive->tm_base + 3 * (1 << TM_SHIFT));
> +_FDT(node = fdt_add_subnode(fdt, 0, nodename));
> +g_free(nodename);
> +
> +_FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
> +_FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
> +
> +_FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
> +_FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
> + sizeof(eq_sizes)));
> +_FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
> + sizeof(lisn_ranges)));
> +
> +/* For Linux to link the LSIs to the main interrupt controller.

What's the "main interrupt co

Re: [Qemu-devel] [PATCH v5 16/36] spapr: add hcalls support for the XIVE exploitation interrupt mode

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:09AM +0100, Cédric Le Goater wrote:
> The different XIVE virtualization structures (sources and event queues)
> are configured with a set of Hypervisor calls :
> 
>  - H_INT_GET_SOURCE_INFO
> 
>used to obtain the address of the MMIO page of the Event State
>Buffer (ESB) entry associated with the source.
> 
>  - H_INT_SET_SOURCE_CONFIG
> 
>assigns a source to a "target".
> 
>  - H_INT_GET_SOURCE_CONFIG
> 
>determines which "target" and "priority" is assigned to a source
> 
>  - H_INT_GET_QUEUE_INFO
> 
>returns the address of the notification management page associated
>with the specified "target" and "priority".
> 
>  - H_INT_SET_QUEUE_CONFIG
> 
>sets or resets the event queue for a given "target" and "priority".
>It is also used to set the notification configuration associated
>with the queue, only unconditional notification is supported for
>the moment. Reset is performed with a queue size of 0 and queueing
>is disabled in that case.
> 
>  - H_INT_GET_QUEUE_CONFIG
> 
>returns the queue settings for a given "target" and "priority".
> 
>  - H_INT_RESET
> 
>resets all of the guest's internal interrupt structures to their
>initial state, losing all configuration set via the hcalls
>H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG.
> 
>  - H_INT_SYNC
> 
>issue a synchronisation on a source to make sure all notifications
>have reached their queue.
> 
> Calls that still need to be addressed :
> 
>H_INT_SET_OS_REPORTING_LINE
>H_INT_GET_OS_REPORTING_LINE
> 
> See the code for more documentation on each hcall.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr.h  |  15 +-
>  include/hw/ppc/spapr_xive.h |   6 +
>  hw/intc/spapr_xive_hcall.c  | 892 
>  hw/ppc/spapr_irq.c  |   2 +
>  hw/intc/Makefile.objs   |   2 +-
>  5 files changed, 915 insertions(+), 2 deletions(-)
>  create mode 100644 hw/intc/spapr_xive_hcall.c
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 1fbc2663e06c..8415faea7b82 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -452,7 +452,20 @@ struct sPAPRMachineState {
>  #define H_INVALIDATE_PID0x378
>  #define H_REGISTER_PROC_TBL 0x37C
>  #define H_SIGNAL_SYS_RESET  0x380
> -#define MAX_HCALL_OPCODEH_SIGNAL_SYS_RESET
> +
> +#define H_INT_GET_SOURCE_INFO   0x3A8
> +#define H_INT_SET_SOURCE_CONFIG 0x3AC
> +#define H_INT_GET_SOURCE_CONFIG 0x3B0
> +#define H_INT_GET_QUEUE_INFO0x3B4
> +#define H_INT_SET_QUEUE_CONFIG  0x3B8
> +#define H_INT_GET_QUEUE_CONFIG  0x3BC
> +#define H_INT_SET_OS_REPORTING_LINE 0x3C0
> +#define H_INT_GET_OS_REPORTING_LINE 0x3C4
> +#define H_INT_ESB   0x3C8
> +#define H_INT_SYNC  0x3CC
> +#define H_INT_RESET 0x3D0
> +
> +#define MAX_HCALL_OPCODEH_INT_RESET
>  
>  /* The hcalls above are standardized in PAPR and implemented by pHyp
>   * as well.
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 3f65b8f485fd..418511f3dc10 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -60,4 +60,10 @@ int spapr_xive_target_to_end(sPAPRXive *xive, uint32_t 
> target, uint8_t prio,
>  int spapr_xive_cpu_to_end(sPAPRXive *xive, PowerPCCPU *cpu, uint8_t prio,
>uint8_t *out_end_blk, uint32_t *out_end_idx);
>  
> +bool spapr_xive_priority_is_valid(uint8_t priority);

AFAICT this could be a local function.

> +
> +typedef struct sPAPRMachineState sPAPRMachineState;
> +
> +void spapr_xive_hcall_init(sPAPRMachineState *spapr);
> +
>  #endif /* PPC_SPAPR_XIVE_H */
> diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c
> new file mode 100644
> index ..52e4e23995f5
> --- /dev/null
> +++ b/hw/intc/spapr_xive_hcall.c
> @@ -0,0 +1,892 @@
> +/*
> + * QEMU PowerPC sPAPR XIVE interrupt controller model
> + *
> + * Copyright (c) 2017-2018, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "cpu.h"
> +#include "hw/ppc/fdt.h"
> +#include "hw/ppc/spapr.h"
> +#include "hw/ppc/spapr_xive.h"
> +#include "hw/ppc/xive_regs.h"
> +#include "monitor/monitor.h"

Fwiw, I don't think it's particularly necessary to split the hcall
handling out into a separate .c file.

> +/*
> + * OPAL uses the priority 7 EQ to automatically escalate interrupts
> + * for all other queues (DD2.X POWER9). So only priorities [0..6] are
> + * available for the guest.

Referencing OPAL behaviour doesn't really make sense in the context of
PAPR.  What I think you're getting at is that the PAPR spec only
allows a PAPR guest to use priorities 0..6 (or at least it will if the
XIVE updated spec ever gets published).  The fact that this allows the
host use 7 fo

[Qemu-devel] [PATCH V10 7/9] hw/misc/pvpanic: preparing for adding configure interface

2018-11-27 Thread Peng Hao
Prepare for pvpanic-mmio configure interface.

Signed-off-by: Peng Hao 
---
 hw/arm/sysbus-fdt.c |  2 ++
 hw/arm/virt.c   |  2 ++
 hw/misc/pvpanic.c   | 11 +--
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index ad698d4..34577f3 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -38,6 +38,7 @@
 #include "hw/vfio/vfio-amd-xgbe.h"
 #include "hw/display/ramfb.h"
 #include "hw/arm/fdt.h"
+#include "hw/misc/pvpanic.h"
 
 /*
  * internal struct that contains the information to create dynamic
@@ -459,6 +460,7 @@ static const BindingEntry bindings[] = {
 VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
 TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
+TYPE_BINDING(TYPE_PVPANIC_MMIO, no_fdt_node),
 TYPE_BINDING("", NULL), /* last element */
 };
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f2cb5de..1fd5941 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -59,6 +59,7 @@
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
+#include "hw/misc/pvpanic.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -1783,6 +1784,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
+machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PVPANIC_MMIO);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
 mc->block_default_type = IF_VIRTIO;
 mc->no_cdrom = 1;
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index c9382a8..b6b5c89 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -67,7 +67,7 @@ typedef struct PVPanicISAState {
 typedef struct PVPanicMMIOState {
 SysBusDevice parent_obj;
 /**/
-
+uint32_t base;
 /* public */
 MemoryRegion mr;
 } PVPanicMMIOState;
@@ -151,10 +151,17 @@ static void pvpanic_mmio_initfn(Object *obj)
 sysbus_init_mmio(sbd, &s->mr);
 }
 
+static Property pvpanic_mmio_properties[] = {
+DEFINE_PROP_UINT32("mmio", PVPanicMMIOState, base, 0x0907),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
-
+
+dc->user_creatable = true;
+dc->props = pvpanic_mmio_properties;
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 8/9] hw/misc/pvpanic: realize the configure interface

2018-11-27 Thread Peng Hao
Add configure interface for pvpanic-mmio. In qemu command line
use -device pvpanic-mmio to enable the device.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 5 -
 hw/arm/virt.c| 7 +++
 hw/misc/pvpanic.c| 1 +
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 2adba60..d29d229 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -45,6 +45,7 @@
 #include "hw/arm/virt.h"
 #include "sysemu/numa.h"
 #include "kvm_arm.h"
+#include "hw/misc/pvpanic.h"
 
 #define ARM_SPI_BASE 32
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -785,7 +786,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
-acpi_dsdt_add_pvpanic(scope, &memmap[VIRT_PVPANIC]);
+if (pvpanic_mmio()) {
+acpi_dsdt_add_pvpanic(scope, &memmap[VIRT_PVPANIC]);
+}
 acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1fd5941..9cddf36 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -198,8 +198,6 @@ static void create_pvpanic_device(const VirtMachineState 
*vms)
  hwaddr base = vms->memmap[VIRT_PVPANIC].base;
  hwaddr size = vms->memmap[VIRT_PVPANIC].size;
 
- sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
-
  nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
  qemu_fdt_add_subnode(vms->fdt, nodename);
  qemu_fdt_setprop_string(vms->fdt, nodename,
@@ -1330,6 +1328,9 @@ void virt_machine_done(Notifier *notifier, void *data)
 struct arm_boot_info *info = &vms->bootinfo;
 AddressSpace *as = arm_boot_address_space(cpu, info);
 
+if (pvpanic_mmio()) {
+create_pvpanic_device(vms);
+}
 /*
  * If the user provided a dtb, we assume the dynamic sysbus nodes
  * already are integrated there. This corresponds to a use case where
@@ -1551,8 +1552,6 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
-create_pvpanic_device(vms);
-
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index b6b5c89..6c4a79f 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -149,6 +149,7 @@ static void pvpanic_mmio_initfn(Object *obj)
 memory_region_init_io(&s->mr, OBJECT(s), &pvpanic_ops, s,
   TYPE_PVPANIC_MMIO, 2);
 sysbus_init_mmio(sbd, &s->mr);
+sysbus_mmio_map(sbd, 0, s->base);
 }
 
 static Property pvpanic_mmio_properties[] = {
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 0/9] add pvpanic mmio support

2018-11-27 Thread Peng Hao
The first patches are simple cleanups:
 - patch 1 move the pvpanic device with the 'ocmmon objects' so we compile
   it once for the x86/arm/aarch64 archs,
 - patch 2 simply renames ISA fields/definitions to generic ones.

 Then instead of add/use the MMIO pvpanic device in the virt machine in an
 unique patch, I split it in two distinct patches:
 - patch 3 uses Peng Hao's work, but add the MMIO interface to the existing
device (no logical change).
 - patch 4 is Peng Hao's work in the virt machine (no logical change).
 - patch 5 add pvpanic device in acpi table in virt machine
 v2 from Peng Hao is:
 https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg03433.html

v3 --> v4
 patch 1,2 no modification.
 patch 3, add TYPE_PANIC_MMIO for distinguishing different bus device,
  virt + isa_pvpanic will abnormally terminate virtual machine.
 patch 4, "pvpanic,mmio" --> "qemu,pvpanic-mmio".
 patch 5, newly added.

v4 --> v5
 patch 1,2 no modification.
 patch 3 delete PvpanicCommonState structure.
 patch 4 VIRT_PVPANIC_MMIO --> VIRT_PVPANIC
 correct VIRT_PVPANIC's overlap start address
 patch 5 no modification.

v5 --> v6
 add document.

v6 --> v7
 patch 5 modify device name from "PANC" to "PEVT".
 patch 6 modify document description.

v7 --> v8
 add configure interface for pvpanic-mmio

v8 --> v9
 revert "moving structure definition to header file"
 because of compile error in x86.

v9 --> v10
 Modify document.
 Repair missing header files.
 
the kernel part of the series:
 
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/log/?h=char-misc-testing
 misc/pvpanic: remove a redundant comma
 misc/pvpanic: convert to SPDX license tags
 misc/pvpanic: change header file sort style
 misc/pvpanic: remove unnecessary header file
 misc/pvpanic : break dependency on ACPI
 misc/pvpanic : grouping ACPI related stuff
 misc/pvpanic: add support to get pvpanic device info FDT
 dt-bindings: misc/pvpanic: add document for pvpanic-mmio
 misc/pvpanic: add MMIO support
 misc/pvpanic: simplify the code using acpi_dev_resource_io
 pvpanic: move pvpanic to misc as common driver  

Philippe Mathieu-Daudé (2):
  hw/misc/pvpanic: Build the pvpanic device in $(common-obj)
  hw/misc/pvpanic: Cosmetic renaming

Peng Hao (7):
  hw/misc/pvpanic: Add the MMIO interface
  hw/arm/virt: Use the pvpanic device
  hw/arm/virt: add pvpanic device in virt acpi table
  hw/misc/pvpanic: add configure query interface
  hw/misc/pvpanic: preparing for adding configure interface
  hw/misc/pvpanic: realize the configure interface
  pvpanic : update pvpanic document

 default-configs/arm-softmmu.mak |  1 +
 docs/specs/pvpanic.txt  | 15 ++-
 hw/arm/sysbus-fdt.c |  2 +
 hw/arm/virt-acpi-build.c| 17 
 hw/arm/virt.c   | 23 ++-
 hw/misc/Makefile.objs   |  2 +-
 hw/misc/pvpanic.c   | 87 +
 include/hw/arm/virt.h   |  1 +
 include/hw/misc/pvpanic.h   |  6 +++
 9 files changed, 134 insertions(+), 20 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH V10 6/9] hw/misc/pvpanic: add configure query interface

2018-11-27 Thread Peng Hao
Add configure query interface for pvpanic-mmio.

Signed-off-by: Peng Hao 
---
 include/hw/misc/pvpanic.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index f1a05b2..dc042cf 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -2,10 +2,12 @@
  * QEMU simulated pvpanic device.
  *
  * Copyright Fujitsu, Corp. 2013
+ * Copyright ZTE Ltd. 2018
  *
  * Authors:
  * Wen Congyang 
  * Hu Tao 
+ * Peng Hao 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -28,4 +30,9 @@ static inline uint16_t pvpanic_port(void)
 return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL);
 }
 
+static inline Object *pvpanic_mmio(void)
+{
+return object_resolve_path_type("", TYPE_PVPANIC_MMIO, NULL);
+}
+
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 4/9] hw/arm/virt: Use the pvpanic device

2018-11-27 Thread Peng Hao
Add pvpanic device in arm virt machine.

Signed-off-by: Peng Hao 
---
 default-configs/arm-softmmu.mak |  1 +
 hw/arm/virt.c   | 21 +
 include/hw/arm/virt.h   |  1 +
 3 files changed, 23 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 2420491..50345df 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -159,3 +159,4 @@ CONFIG_PCI_DESIGNWARE=y
 CONFIG_STRONGARM=y
 CONFIG_HIGHBANK=y
 CONFIG_MUSICPAL=y
+CONFIG_PVPANIC=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a2b8d8f..f2cb5de 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -143,6 +143,7 @@ static const MemMapEntry a15memmap[] = {
 [VIRT_GPIO] =   { 0x0903, 0x1000 },
 [VIRT_SECURE_UART] ={ 0x0904, 0x1000 },
 [VIRT_SMMU] =   { 0x0905, 0x0002 },
+[VIRT_PVPANIC] ={ 0x0907, 0x0002 },
 [VIRT_MMIO] =   { 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
 [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
@@ -190,6 +191,24 @@ static bool cpu_type_valid(const char *cpu)
 return false;
 }
 
+static void create_pvpanic_device(const VirtMachineState *vms)
+{
+ char *nodename;
+ hwaddr base = vms->memmap[VIRT_PVPANIC].base;
+ hwaddr size = vms->memmap[VIRT_PVPANIC].size;
+
+ sysbus_create_simple(TYPE_PVPANIC_MMIO, base, NULL);
+
+ nodename = g_strdup_printf("/pvpanic-mmio@%" PRIx64, base);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_string(vms->fdt, nodename,
+ "compatible", "qemu,pvpanic-mmio");
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
+  2, base, 2, size);
+
+ g_free(nodename);
+}
+
 static void create_fdt(VirtMachineState *vms)
 {
 void *fdt = create_device_tree(&vms->fdt_size);
@@ -1531,6 +1550,8 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
+create_pvpanic_device(vms);
+
 create_gic(vms, pic);
 
 fdt_add_pmu_nodes(vms);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 4cc57a7..937c124 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -66,6 +66,7 @@ enum {
 VIRT_GIC_REDIST,
 VIRT_GIC_REDIST2,
 VIRT_SMMU,
+VIRT_PVPANIC,
 VIRT_UART,
 VIRT_MMIO,
 VIRT_RTC,
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 9/9] pvpanic : update pvpanic document

2018-11-27 Thread Peng Hao
Add mmio support info in docs/specs/pvpanic.txt.

Signed-off-by: Peng Hao 
---
 docs/specs/pvpanic.txt | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
index c7bbacc..b1beea3 100644
--- a/docs/specs/pvpanic.txt
+++ b/docs/specs/pvpanic.txt
@@ -1,14 +1,17 @@
 PVPANIC DEVICE
 ==
 
-pvpanic device is a simulated ISA device, through which a guest panic
-event is sent to qemu, and a QMP event is generated. This allows
+pvpanic device is a simulated ISA/SYSBUS device, through which a guest
+panic event is sent to qemu, and a QMP event is generated. This allows
 management apps (e.g. libvirt) to be notified and respond to the event.
 
 The management app has the option of waiting for GUEST_PANICKED events,
 and/or polling for guest-panicked RunState, to learn when the pvpanic
 device has fired a panic event.
 
+The pvpanic device can be implemented as an ISA device (using IOPORT), 
+or, since qemu 4.0, as a SYSBUS device (using MMIO).
+
 ISA Interface
 -
 
@@ -19,6 +22,13 @@ Software should set only bits both itself and the device 
recognize.
 Currently, only bit 0 is recognized, setting it indicates a guest panic
 has happened.
 
+SYSBUS Interface
+
+
+The SYSBUS interface is similar to the ISA interface except that it uses
+MMIO. For example, the arm virt machine could put the pvpanic device at
+[0x907, 0x9070001] and currently only the first byte is used.
+
 ACPI Interface
 --
 
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 5/9] hw/arm/virt: add pvpanic device in virt acpi table

2018-11-27 Thread Peng Hao
Add pvpanic device in virt acpi table, so when kenrel command line
uses acpi=force, kernel can get info from acpi table.

Signed-off-by: Peng Hao 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5785fb6..2adba60 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -84,6 +84,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_pvpanic(Aml *scope, const MemMapEntry 
*pvpanic_memmap)
+{
+Aml *dev = aml_device("PEVT");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(pvpanic_memmap->base,
+   pvpanic_memmap->size, AML_READ_WRITE));
+
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
 {
 Aml *dev = aml_device("FWCF");
@@ -771,6 +785,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
+acpi_dsdt_add_pvpanic(scope, &memmap[VIRT_PVPANIC]);
 acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 3/9] hw/misc/pvpanic: Add the MMIO interface

2018-11-27 Thread Peng Hao
Add pvpanic new type "TYPE_PVPANIC_MMIO"

Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 50 +++
 include/hw/misc/pvpanic.h |  1 +
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 0f23a67..c9382a8 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -2,10 +2,12 @@
  * QEMU simulated pvpanic device.
  *
  * Copyright Fujitsu, Corp. 2013
+ * Copyright (c) 2018 ZTE Ltd.
  *
  * Authors:
  * Wen Congyang 
  * Hu Tao 
+ * Peng Hao 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -28,6 +30,9 @@
 #define PVPANIC_ISA_DEVICE(obj)\
 OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
 
+#define PVPANIC_MMIO_DEVICE(obj)\
+OBJECT_CHECK(PVPanicMMIOState, (obj), TYPE_PVPANIC_MMIO)
+
 static void handle_event(int event)
 {
 static bool logged;
@@ -56,21 +61,32 @@ typedef struct PVPanicISAState {
 MemoryRegion mr;
 } PVPanicISAState;
 
+/* PVPanicMMIOState for sysbus device and
+ * use mmio.
+ */
+typedef struct PVPanicMMIOState {
+SysBusDevice parent_obj;
+/**/
+
+/* public */
+MemoryRegion mr;
+} PVPanicMMIOState;
+
 /* return supported events on read */
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
 {
 return PVPANIC_PANICKED;
 }
 
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
  unsigned size)
 {
 handle_event(val);
 }
 
 static const MemoryRegionOps pvpanic_ops = {
-.read = pvpanic_ioport_read,
-.write = pvpanic_ioport_write,
+.read = pvpanic_read,
+.write = pvpanic_write,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -125,9 +141,35 @@ static TypeInfo pvpanic_isa_info = {
 .class_init= pvpanic_isa_class_init,
 };
 
+static void pvpanic_mmio_initfn(Object *obj)
+{
+PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(&s->mr, OBJECT(s), &pvpanic_ops, s,
+  TYPE_PVPANIC_MMIO, 2);
+sysbus_init_mmio(sbd, &s->mr);
+}
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static TypeInfo pvpanic_mmio_info = {
+.name  = TYPE_PVPANIC_MMIO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PVPanicMMIOState),
+.instance_init = pvpanic_mmio_initfn,
+.class_init= pvpanic_mmio_class_init,
+};
+
 static void pvpanic_register_types(void)
 {
 type_register_static(&pvpanic_isa_info);
+type_register_static(&pvpanic_mmio_info);
 }
 
 type_init(pvpanic_register_types)
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 1ee071a..f1a05b2 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -15,6 +15,7 @@
 #define HW_MISC_PVPANIC_H
 
 #define TYPE_PVPANIC "pvpanic"
+#define TYPE_PVPANIC_MMIO "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 2/9] hw/misc/pvpanic: Cosmetic renaming

2018-11-27 Thread Peng Hao
From: Philippe Mathieu-Daudé 

To ease the MMIO device addition in the next patch, rename:
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
- MemoryRegion io -> mr.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/pvpanic.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 9d8961b..0f23a67 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -25,8 +25,8 @@
 /* The pv event value */
 #define PVPANIC_PANICKED(1 << PVPANIC_F_PANICKED)
 
-#define ISA_PVPANIC_DEVICE(obj)\
-OBJECT_CHECK(PVPanicState, (obj), TYPE_PVPANIC)
+#define PVPANIC_ISA_DEVICE(obj)\
+OBJECT_CHECK(PVPanicISAState, (obj), TYPE_PVPANIC)
 
 static void handle_event(int event)
 {
@@ -45,12 +45,16 @@ static void handle_event(int event)
 
 #include "hw/isa/isa.h"
 
-typedef struct PVPanicState {
+/* PVPanicISAState for ISA device and
+ * use ioport.
+ */
+typedef struct PVPanicISAState {
 ISADevice parent_obj;
-
-MemoryRegion io;
+/*< private>*/
 uint16_t ioport;
-} PVPanicState;
+/**/
+MemoryRegion mr;
+} PVPanicISAState;
 
 /* return supported events on read */
 static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
@@ -75,15 +79,15 @@ static const MemoryRegionOps pvpanic_ops = {
 
 static void pvpanic_isa_initfn(Object *obj)
 {
-PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
 
-memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
+memory_region_init_io(&s->mr, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
 }
 
 static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
 {
 ISADevice *d = ISA_DEVICE(dev);
-PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
+PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
 FWCfgState *fw_cfg = fw_cfg_find();
 uint16_t *pvpanic_port;
 
@@ -96,11 +100,11 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error 
**errp)
 fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
 sizeof(*pvpanic_port));
 
-isa_register_ioport(d, &s->io, s->ioport);
+isa_register_ioport(d, &s->mr, s->ioport);
 }
 
 static Property pvpanic_isa_properties[] = {
-DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
+DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -116,7 +120,7 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void 
*data)
 static TypeInfo pvpanic_isa_info = {
 .name  = TYPE_PVPANIC,
 .parent= TYPE_ISA_DEVICE,
-.instance_size = sizeof(PVPanicState),
+.instance_size = sizeof(PVPanicISAState),
 .instance_init = pvpanic_isa_initfn,
 .class_init= pvpanic_isa_class_init,
 };
-- 
1.8.3.1




[Qemu-devel] [PATCH V10 1/9] hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

2018-11-27 Thread Peng Hao
From: Philippe Mathieu-Daudé 

The 'pvpanic' ISA device can be use by any machine with an ISA bus.

Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peng Hao 
---
 hw/misc/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 680350b..c387ce4 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
 common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
 common-obj-$(CONFIG_EDU) += edu.o
 common-obj-$(CONFIG_PCA9552) += pca9552.o
+common-obj-$(CONFIG_PVPANIC) += pvpanic.o
 
 common-obj-y += unimp.o
 common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
@@ -70,7 +71,6 @@ obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
 obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
 obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
 
-obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v5 12/36] spapr: initialize VSMT before initializing the IRQ backend

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:05AM +0100, Cédric Le Goater wrote:
> We will need to use xics_max_server_number() to create the sPAPRXive
> object modeling the interrupt controller of the machine which is
> created before the CPUs.
> 
> Signed-off-by: Cédric Le Goater 

My only concern here is that this moves the spapr_set_vsmt_mode()
before some of the sanity checks in spapr_init_cpus().  Are we certain
there are no edge cases that could cause badness?

> ---
>  hw/ppc/spapr.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7afd1a175bf2..50cb9f9f4a02 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2466,11 +2466,6 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
>  boot_cores_nr = possible_cpus->len;
>  }
>  
> -/* VSMT must be set in order to be able to compute VCPU ids, ie to
> - * call xics_max_server_number() or spapr_vcpu_id().
> - */
> -spapr_set_vsmt_mode(spapr, &error_fatal);
> -
>  if (smc->pre_2_10_has_unused_icps) {
>  int i;
>  
> @@ -2593,6 +2588,11 @@ static void spapr_machine_init(MachineState *machine)
>  /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
>  load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
>  
> +/* VSMT must be set in order to be able to compute VCPU ids, ie to
> + * call xics_max_server_number() or spapr_vcpu_id().
> + */
> +spapr_set_vsmt_mode(spapr, &error_fatal);
> +
>  /* Set up Interrupt Controller before we create the VCPUs */
>  smc->irq->init(spapr, &error_fatal);
>  

-- 
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 v5 13/36] spapr: introduce a spapr_irq_init() routine

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:06AM +0100, Cédric Le Goater wrote:
> Initialize the MSI bitmap from it as this will be necessary for the
> sPAPR IRQ backend for XIVE.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  include/hw/ppc/spapr_irq.h |  1 +
>  hw/ppc/spapr.c |  2 +-
>  hw/ppc/spapr_irq.c | 16 +++-
>  3 files changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index a467ce696ee4..bd7301e6d9c6 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,6 +43,7 @@ typedef struct sPAPRIrq {
>  extern sPAPRIrq spapr_irq_xics;
>  extern sPAPRIrq spapr_irq_xics_legacy;
>  
> +void spapr_irq_init(sPAPRMachineState *spapr, Error **errp);
>  int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error 
> **errp);
>  void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 50cb9f9f4a02..e470efe7993c 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2594,7 +2594,7 @@ static void spapr_machine_init(MachineState *machine)
>  spapr_set_vsmt_mode(spapr, &error_fatal);
>  
>  /* Set up Interrupt Controller before we create the VCPUs */
> -smc->irq->init(spapr, &error_fatal);
> +spapr_irq_init(spapr, &error_fatal);
>  
>  /* Set up containers for ibm,client-architecture-support negotiated 
> options
>   */
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index e77b94cc685e..f8b651de0ec9 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -97,11 +97,6 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, 
> Error **errp)
>  int nr_irqs = smc->irq->nr_irqs;
>  Error *local_err = NULL;
>  
> -/* Initialize the MSI IRQ allocator. */
> -if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> -spapr_irq_msi_init(spapr, smc->irq->nr_msis);
> -}
> -
>  if (kvm_enabled()) {
>  if (machine_kernel_irqchip_allowed(machine) &&
>  !xics_kvm_init(spapr, &local_err)) {
> @@ -213,6 +208,17 @@ sPAPRIrq spapr_irq_xics = {
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
> +{
> +sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +
> +/* Initialize the MSI IRQ allocator. */
> +if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> +spapr_irq_msi_init(spapr, smc->irq->nr_msis);
> +}
> +
> +smc->irq->init(spapr, errp);
> +}
>  
>  int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error 
> **errp)
>  {

-- 
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 v5 15/36] spapr: introdude a new machine IRQ backend for XIVE

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:08AM +0100, Cédric Le Goater wrote:
> The XIVE IRQ backend uses the same layout as the new XICS backend but
> covers the full range of the IRQ number space. The IRQ numbers for the
> CPU IPIs are allocated at the bottom of this space, below 4K, to
> preserve compatibility with XICS which does not use that range.
> 
> This should be enough given that the maximum number of CPUs is 1024
> for the sPAPR machine under QEMU. For the record, the biggest POWER8
> or POWER9 system has a maximum of 1536 HW threads (16 sockets, 192
> cores, SMT8).
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr.h |   2 +
>  include/hw/ppc/spapr_irq.h |   7 ++-
>  hw/ppc/spapr.c |   2 +-
>  hw/ppc/spapr_irq.c | 119 -
>  4 files changed, 124 insertions(+), 6 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 6279711fe8f7..1fbc2663e06c 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -16,6 +16,7 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry;
>  typedef struct sPAPREventSource sPAPREventSource;
>  typedef struct sPAPRPendingHPT sPAPRPendingHPT;
>  typedef struct ICSState ICSState;
> +typedef struct sPAPRXive sPAPRXive;
>  
>  #define HPTE64_V_HPTE_DIRTY 0x0040ULL
>  #define SPAPR_ENTRY_POINT   0x100
> @@ -175,6 +176,7 @@ struct sPAPRMachineState {
>  const char *icp_type;
>  int32_t irq_map_nr;
>  unsigned long *irq_map;
> +sPAPRXive  *xive;
>  
>  bool cmd_line_caps[SPAPR_CAP_NUM];
>  sPAPRCapabilities def, eff, mig;
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 0e9229bf219e..c854ae527808 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -13,6 +13,7 @@
>  /*
>   * IRQ range offsets per device type
>   */
> +#define SPAPR_IRQ_IPI0x0
>  #define SPAPR_IRQ_EPOW   0x1000  /* XICS_IRQ_BASE offset */
>  #define SPAPR_IRQ_HOTPLUG0x1001
>  #define SPAPR_IRQ_VIO0x1100  /* 256 VIO devices */
> @@ -33,7 +34,8 @@ typedef struct sPAPRIrq {
>  uint32_tnr_irqs;
>  uint32_tnr_msis;
>  
> -void (*init)(sPAPRMachineState *spapr, int nr_irqs, Error **errp);
> +void (*init)(sPAPRMachineState *spapr, int nr_irqs, int nr_servers,
> + Error **errp);
>  int (*claim)(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
>  void (*free)(sPAPRMachineState *spapr, int irq, int num);
>  qemu_irq (*qirq)(sPAPRMachineState *spapr, int irq);
> @@ -42,8 +44,9 @@ typedef struct sPAPRIrq {
>  
>  extern sPAPRIrq spapr_irq_xics;
>  extern sPAPRIrq spapr_irq_xics_legacy;
> +extern sPAPRIrq spapr_irq_xive;
>  
> -void spapr_irq_init(sPAPRMachineState *spapr, Error **errp);
> +void spapr_irq_init(sPAPRMachineState *spapr, int nr_servers, Error **errp);

I don't see why nr_servers needs to become a parameter, since it can
be derived from spapr within this routine.

>  int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error 
> **errp);
>  void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e470efe7993c..9f8c19e56e7a 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2594,7 +2594,7 @@ static void spapr_machine_init(MachineState *machine)
>  spapr_set_vsmt_mode(spapr, &error_fatal);
>  
>  /* Set up Interrupt Controller before we create the VCPUs */
> -spapr_irq_init(spapr, &error_fatal);
> +spapr_irq_init(spapr, xics_max_server_number(spapr), &error_fatal);

We should rename xics_max_server_number() since it's no longer xics
specific.

>  /* Set up containers for ibm,client-architecture-support negotiated 
> options
>   */
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index bac45023..2569ae1bc7f8 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -12,6 +12,7 @@
>  #include "qemu/error-report.h"
>  #include "qapi/error.h"
>  #include "hw/ppc/spapr.h"
> +#include "hw/ppc/spapr_xive.h"
>  #include "hw/ppc/xics.h"
>  #include "sysemu/kvm.h"
>  
> @@ -91,7 +92,7 @@ error:
>  }
>  
>  static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs,
> -Error **errp)
> +int nr_servers, Error **errp)
>  {
>  MachineState *machine = MACHINE(spapr);
>  Error *local_err = NULL;
> @@ -204,10 +205,122 @@ sPAPRIrq spapr_irq_xics = {
>  .print_info  = spapr_irq_print_info_xics,
>  };
>  
> + /*
> + * XIVE IRQ backend.
> + */
> +static sPAPRXive *spapr_xive_create(sPAPRMachineState *spapr,
> +const char *type_xive, int nr_irqs,
> +int nr_servers, Error **errp)
> +{
> +sPAPRXive *xive;
> +Error *local_err = NULL;
> +Object *obj;
> +uint32_t nr_ends = nr_servers << 

Re: [Qemu-devel] [PATCH 4/8] hw: arm: Carry RSDP specific data through AcpiRsdpData

2018-11-27 Thread Michael S. Tsirkin
On Tue, Nov 27, 2018 at 05:27:49PM +0100, Igor Mammedov wrote:
> On Tue, 27 Nov 2018 16:42:18 +0100
> Samuel Ortiz  wrote:
> 
> > Hi Igor,
> > 
> > On Tue, Nov 27, 2018 at 04:25:51PM +0100, Igor Mammedov wrote:
> > > On Mon, 26 Nov 2018 17:29:37 +0100
> > > Samuel Ortiz  wrote:
> > >   
> > > > That will allow us to generalize the ARM build_rsdp() routine to support
> > > > both legacy RSDP (The current i386 implementation) and extended RSDP
> > > > (The ARM implementation).
> > > > 
> > > > Signed-off-by: Samuel Ortiz 
> > > > ---
> > > >  include/hw/acpi/acpi-defs.h | 11 +++
> > > >  hw/arm/virt-acpi-build.c| 27 ++-
> > > >  2 files changed, 33 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> > > > index af8e023968..e7fd24c6c5 100644
> > > > --- a/include/hw/acpi/acpi-defs.h
> > > > +++ b/include/hw/acpi/acpi-defs.h
> > > > @@ -53,6 +53,17 @@ struct AcpiRsdpDescriptor {/* Root System 
> > > > Descriptor Pointer */
> > > >  } QEMU_PACKED;
> > > >  typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
> > > >  
> > > > +typedef struct AcpiRsdpData {
> > > > +uint8_t oem_id[6]; /* OEM identification */
> > > > +uint8_t revision;  /* Must be 0 for 1.0, 2 for 2.0 */
> > > > +
> > > > +unsigned *rsdt_tbl_offset;
> > > > +unsigned *xsdt_tbl_offset;
> > > > +} AcpiRsdpData;
> > > > +  
> > >   
> > > > +#define ACPI_RSDP_REV_1 0
> > > > +#define ACPI_RSDP_REV_2 2  
> > > it's one time used spec defined values so just use values directly
> > > in place with a comment, so reader won't have to jump around code
> > > when comparing to spec.  
> > It's also used in the ACPI tests fix patch.
> it's better to use in test it's own version (we just opencode them there)
> see fadt_fetch_facs_and_dsdt_ptrs()/sanitize_fadt_ptrs()
> same applies for length.
> that way if we break it in qemu's code test would catch the thing
> 
> > Also the 0 for revision 1 is a little confusing, I feel the above
> > definition is clearer.
> that's confusion is in the spec, so we just mimic it, no need to add more on 
> top

To be more precise, there is a huge number of constants in ACPI
such that adding defines for them all would be a huge burden,
and will not make it easy to check values against the
spec at all (case in point ACPI_RSDP_REV_2 is actually wrong,
2 is version 3 and up).

Thus the preferred style is to add a comment near the value
matching spec name verbatim, so one can copy it and
look it up in the spec. Sometimes one needs to reference
specific spec version.

0 /* Revision: ACPI version 1.0 */

and

1 /* Revision: ACPI 2.0 */

and

2 /* Revision: ACPI 3.0a */

For style consistency, if the value is used multiple times, we avoid
duplication by using an inline function and not a macro.

> > 
> > 
> > > > +
> > > >  /* Table structure from Linux kernel (the ACPI tables are under the
> > > > BSD license) */
> > > >  
> > > > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > > > index 0835900052..2dad465ecf 100644
> > > > --- a/hw/arm/virt-acpi-build.c
> > > > +++ b/hw/arm/virt-acpi-build.c
> > > > @@ -368,7 +368,7 @@ static void acpi_dsdt_add_power_button(Aml *scope)
> > > >  
> > > >  /* RSDP */
> > > >  static void
> > > > -build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned 
> > > > xsdt_tbl_offset)
> > > > +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, AcpiRsdpData 
> > > > *rsdp_data)
> > > >  {
> > > >  AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof 
> > > > *rsdp);
> > > >  unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address);
> > > > @@ -379,14 +379,14 @@ build_rsdp(GArray *rsdp_table, BIOSLinker 
> > > > *linker, unsigned xsdt_tbl_offset)
> > > >   true /* fseg memory */);
> > > >  
> > > >  memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
> > > > -memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
> > > > +memcpy(rsdp->oem_id, rsdp_data->oem_id, sizeof(rsdp->oem_id));
> > > >  rsdp->length = cpu_to_le32(sizeof(*rsdp));
> > > > -rsdp->revision = 0x02;
> > > > +rsdp->revision = rsdp_data->revision;
> > > >  
> > > >  /* Address to be filled by Guest linker */
> > > >  bios_linker_loader_add_pointer(linker,
> > > >  ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size,
> > > > -ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset);
> > > > +ACPI_BUILD_TABLE_FILE, *rsdp_data->xsdt_tbl_offset);
> > > >  
> > > >  /* Checksum to be filled by Guest linker */
> > > >  bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
> > > > @@ -399,6 +399,20 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, 
> > > > unsigned xsdt_tbl_offset)
> > > >  (char *)&rsdp->extended_checksum - rsdp_table->data);
> > > >  }
> > > >  
> > > > +static void
> > > > +init_rsdp_data(AcpiRsdpData *data, const char *oem_id, uint8_t 
> > > > r

Re: [Qemu-devel] [PATCH v2 00/16] Virtio devices split from virtio-pci

2018-11-27 Thread Michael S. Tsirkin
On Mon, Nov 26, 2018 at 08:59:53PM +0100, Juan Quintela wrote:
> Hi
> 
> V2:
> 
> - Rebase on top of master
> 
> Please review.
> 
> Later, Juan.

And just making sure the point is so that one
can disable virtio-pci and still build virtio?

And the point of that is mostly as a cleanup on
generic principles, right? Or is there a project that
actually wants to do it?

> 
> [v1]
> >From previous verision (in the middle of make check tests):
> - split also the bits of virtio-pci.h (mst suggestion)
> - add gpu, crypt and gpg bits
> - more cleanups
> - fix all the copyrights (the ones not changed have been there
>   foverever)
> - be consistent with naming, vhost-* or virtio-*
> 
> Please review, Juan.
> 
> Juan Quintela (16):
>   virtio: split vhost vsock bits from virtio-pci
>   virtio: split virtio input host bits from virtio-pci
>   virtio: split virtio input bits from virtio-pci
>   virtio: split virtio rng bits from virtio-pci
>   virtio: split virtio balloon bits from virtio-pci
>   virtio: split virtio 9p bits from virtio-pci
>   virtio: split vhost user blk bits from virtio-pci
>   virtio: split vhost user scsi bits from virtio-pci
>   virtio: split vhost scsi bits from virtio-pci
>   virtio: split virtio scsi bits from virtio-pci
>   virtio: split virtio blk bits rom virtio-pci
>   virtio: split virtio net bits rom virtio-pci
>   virtio: split virtio serial bits rom virtio-pci
>   virtio: split virtio gpu bits rom virtio-pci.h
>   virtio: split virtio crypto bits rom virtio-pci.h
>   virtio: virtio 9p really requires CONFIG_VIRTFS to work
> 
>  default-configs/virtio.mak|   3 +-
>  hw/display/virtio-gpu-pci.c   |  14 +
>  hw/display/virtio-vga.c   |   1 +
>  hw/virtio/Makefile.objs   |  14 +-
>  hw/virtio/vhost-scsi-pci.c|  95 
>  hw/virtio/vhost-user-blk-pci.c| 101 
>  hw/virtio/vhost-user-scsi-pci.c   | 101 
>  hw/virtio/vhost-vsock-pci.c   |  82 
>  hw/virtio/virtio-9p-pci.c |  86 
>  hw/virtio/virtio-balloon-pci.c|  94 
>  hw/virtio/virtio-blk-pci.c|  97 
>  hw/virtio/virtio-crypto-pci.c |  14 +
>  hw/virtio/virtio-input-host-pci.c |  45 ++
>  hw/virtio/virtio-input-pci.c  | 154 ++
>  hw/virtio/virtio-net-pci.c|  96 
>  hw/virtio/virtio-pci.c| 783 --
>  hw/virtio/virtio-pci.h| 234 -
>  hw/virtio/virtio-rng-pci.c|  86 
>  hw/virtio/virtio-scsi-pci.c   | 106 
>  hw/virtio/virtio-serial-pci.c | 112 +
>  tests/Makefile.include|  18 +-
>  21 files changed, 1308 insertions(+), 1028 deletions(-)
>  create mode 100644 hw/virtio/vhost-scsi-pci.c
>  create mode 100644 hw/virtio/vhost-user-blk-pci.c
>  create mode 100644 hw/virtio/vhost-user-scsi-pci.c
>  create mode 100644 hw/virtio/vhost-vsock-pci.c
>  create mode 100644 hw/virtio/virtio-9p-pci.c
>  create mode 100644 hw/virtio/virtio-balloon-pci.c
>  create mode 100644 hw/virtio/virtio-blk-pci.c
>  create mode 100644 hw/virtio/virtio-input-host-pci.c
>  create mode 100644 hw/virtio/virtio-input-pci.c
>  create mode 100644 hw/virtio/virtio-net-pci.c
>  create mode 100644 hw/virtio/virtio-rng-pci.c
>  create mode 100644 hw/virtio/virtio-scsi-pci.c
>  create mode 100644 hw/virtio/virtio-serial-pci.c
> 
> -- 
> 2.19.1
> 



Re: [Qemu-devel] [PATCH v5 09/36] ppc/xive: notify the CPU when the interrupt priority is more privileged

2018-11-27 Thread Eric Blake

On 11/27/18 8:41 PM, David Gibson wrote:

On Wed, Nov 28, 2018 at 01:32:21PM +1100, Benjamin Herrenschmidt wrote:

On Wed, 2018-11-28 at 11:13 +1100, David Gibson wrote:

Don't you need a cast to avoid (nsr << 8) being a shift-wider-than-size?


Shouldn't be a problem as long as it fits in an int, no ?


I dunno, I can never remember the rules about when C extends and when
it doesn't.  I'm not sure anybody does, which is kind of the point.


As soon as you perform arithmetic on a type narrower than int, it is 
first promoted to at least int (possibly wider, depending on the type of 
the other operand to the binary operator).  And, since C guarantees that 
int is larger than 8 bits, 'uint8_t << 8' and 'int8_t << 8' are both 
well-defined, without needing a cast of nsr.


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



Re: [Qemu-devel] [PATCH V9 0/9] add pvpanic mmio support

2018-11-27 Thread no-reply
Hi,

This series failed docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Message-id: 1543262162-6351-1-git-send-email-peng.h...@zte.com.cn
Subject: [Qemu-devel] [PATCH V9 0/9] add pvpanic mmio support
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-quick@centos7 SHOW_ENV=1 J=8
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
3159b16 pvpanic : update pvpanic document
043c070 hw/misc/pvpanic: realize the configure interface
86ea086 hw/misc/pvpanic: preparing for adding configure interface
af8de03 hw/misc/pvpanic: add configure query interface
63deb69 hw/arm/virt: add pvpanic device in virt acpi table
272983e hw/arm/virt: Use the pvpanic device
a0bdaee hw/misc/pvpanic: Add the MMIO interface
fe0cdc7e hw/misc/pvpanic: Cosmetic renaming
65de96a hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

=== OUTPUT BEGIN ===
  BUILD   centos7
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-q3noxx78/src'
  GEN 
/var/tmp/patchew-tester-tmp-q3noxx78/src/docker-src.2018-11-27-21.45.24.27232/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-q3noxx78/src/docker-src.2018-11-27-21.45.24.27232/qemu.tar.vroot'...
done.
Checking out files:  46% (3031/6463)   
Checking out files:  47% (3038/6463)   
Checking out files:  48% (3103/6463)   
Checking out files:  49% (3167/6463)   
Checking out files:  50% (3232/6463)   
Checking out files:  51% (3297/6463)   
Checking out files:  52% (3361/6463)   
Checking out files:  53% (3426/6463)   
Checking out files:  54% (3491/6463)   
Checking out files:  55% (3555/6463)   
Checking out files:  56% (3620/6463)   
Checking out files:  57% (3684/6463)   
Checking out files:  58% (3749/6463)   
Checking out files:  59% (3814/6463)   
Checking out files:  60% (3878/6463)   
Checking out files:  61% (3943/6463)   
Checking out files:  62% (4008/6463)   
Checking out files:  63% (4072/6463)   
Checking out files:  64% (4137/6463)   
Checking out files:  65% (4201/6463)   
Checking out files:  66% (4266/6463)   
Checking out files:  67% (4331/6463)   
Checking out files:  68% (4395/6463)   
Checking out files:  69% (4460/6463)   
Checking out files:  70% (4525/6463)   
Checking out files:  71% (4589/6463)   
Checking out files:  72% (4654/6463)   
Checking out files:  73% (4718/6463)   
Checking out files:  74% (4783/6463)   
Checking out files:  75% (4848/6463)   
Checking out files:  76% (4912/6463)   
Checking out files:  77% (4977/6463)   
Checking out files:  78% (5042/6463)   
Checking out files:  79% (5106/6463)   
Checking out files:  80% (5171/6463)   
Checking out files:  81% (5236/6463)   
Checking out files:  82% (5300/6463)   
Checking out files:  83% (5365/6463)   
Checking out files:  84% (5429/6463)   
Checking out files:  85% (5494/6463)   
Checking out files:  86% (5559/6463)   
Checking out files:  87% (5623/6463)   
Checking out files:  88% (5688/6463)   
Checking out files:  89% (5753/6463)   
Checking out files:  90% (5817/6463)   
Checking out files:  91% (5882/6463)   
Checking out files:  92% (5946/6463)   
Checking out files:  93% (6011/6463)   
Checking out files:  94% (6076/6463)   
Checking out files:  95% (6140/6463)   
Checking out files:  96% (6205/6463)   
Checking out files:  97% (6270/6463)   
Checking out files:  98% (6334/6463)   
Checking out files:  99% (6399/6463)   
Checking out files: 100% (6463/6463)   
Checking out files: 100% (6463/6463), done.
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-quick in qemu:centos7 
Packages installed:
SDL-devel-1.2.15-14.el7.x86_64
bison-3.0.4-1.el7.x86_64
bzip2-1.0.6-13.el7.x86_64
bzip2-devel-1.0.6-13.el7.x86_64
ccache-3.3.4-1.el7.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el7.x86_64
flex-2.5.37-3.el7.x86_64
gcc-4.8.5-28.el7_5.1.x86_64
gettext-0.19.8.1-2.el7.x86_64
git-1.8.3.1-14.el7_5.x86_64
glib2-devel-2.54.2-2.el7.x86_64
libaio-devel-0.3.109-13.el7.x86_64
libepoxy-devel-1.3.1-2.el7_5.x86_64
libfdt-devel-1.4.6-1.el7.x86_64
lzo-devel-2.06-8.el7.x86_64
make-3.82-23.el7.x86_64
mesa-libEGL-devel-17.2.3-8.20171019.el7.x86_64
mesa-libgbm-devel-17.2.3-8.20171019.el7.x86_64
nettle-devel-2.7.1-8.el7.x86_64
package g++ is not installed
package librdmacm-devel is not installed
pixman-devel-0.34.0-1.el7.x86_64
spice-glib-devel-0.34-3.el7_5.2.x86_64
spice-server-devel-0.14.0-2.el7_5.5.x86_64
tar-1.26-34.el7.x86_64
vte-devel-0.28.2-10.el7.x86_64
xen-devel-4.8.4.43.ge52ec4b787-1.el7.x86_64
zlib-devel-1.2.7-17.el7.x86_64

Environment 

Re: [Qemu-devel] [PATCH V9 0/9] add pvpanic mmio support

2018-11-27 Thread no-reply
Hi,

This series failed docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Message-id: 1543262162-6351-1-git-send-email-peng.h...@zte.com.cn
Subject: [Qemu-devel] [PATCH V9 0/9] add pvpanic mmio support
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=8
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
3159b16 pvpanic : update pvpanic document
043c070 hw/misc/pvpanic: realize the configure interface
86ea086 hw/misc/pvpanic: preparing for adding configure interface
af8de03 hw/misc/pvpanic: add configure query interface
63deb69 hw/arm/virt: add pvpanic device in virt acpi table
272983e hw/arm/virt: Use the pvpanic device
a0bdaee hw/misc/pvpanic: Add the MMIO interface
fe0cdc7e hw/misc/pvpanic: Cosmetic renaming
65de96a hw/misc/pvpanic: Build the pvpanic device in $(common-obj)

=== OUTPUT BEGIN ===
  BUILD   fedora
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-txwecgp8/src'
  GEN 
/var/tmp/patchew-tester-tmp-txwecgp8/src/docker-src.2018-11-27-21.43.06.22116/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-txwecgp8/src/docker-src.2018-11-27-21.43.06.22116/qemu.tar.vroot'...
done.
Checking out files:  46% (3012/6463)   
Checking out files:  47% (3038/6463)   
Checking out files:  48% (3103/6463)   
Checking out files:  49% (3167/6463)   
Checking out files:  50% (3232/6463)   
Checking out files:  51% (3297/6463)   
Checking out files:  52% (3361/6463)   
Checking out files:  53% (3426/6463)   
Checking out files:  54% (3491/6463)   
Checking out files:  55% (3555/6463)   
Checking out files:  56% (3620/6463)   
Checking out files:  57% (3684/6463)   
Checking out files:  58% (3749/6463)   
Checking out files:  59% (3814/6463)   
Checking out files:  60% (3878/6463)   
Checking out files:  61% (3943/6463)   
Checking out files:  62% (4008/6463)   
Checking out files:  63% (4072/6463)   
Checking out files:  64% (4137/6463)   
Checking out files:  65% (4201/6463)   
Checking out files:  66% (4266/6463)   
Checking out files:  67% (4331/6463)   
Checking out files:  68% (4395/6463)   
Checking out files:  69% (4460/6463)   
Checking out files:  70% (4525/6463)   
Checking out files:  71% (4589/6463)   
Checking out files:  72% (4654/6463)   
Checking out files:  73% (4718/6463)   
Checking out files:  74% (4783/6463)   
Checking out files:  75% (4848/6463)   
Checking out files:  76% (4912/6463)   
Checking out files:  77% (4977/6463)   
Checking out files:  78% (5042/6463)   
Checking out files:  79% (5106/6463)   
Checking out files:  80% (5171/6463)   
Checking out files:  81% (5236/6463)   
Checking out files:  82% (5300/6463)   
Checking out files:  83% (5365/6463)   
Checking out files:  84% (5429/6463)   
Checking out files:  85% (5494/6463)   
Checking out files:  86% (5559/6463)   
Checking out files:  87% (5623/6463)   
Checking out files:  88% (5688/6463)   
Checking out files:  89% (5753/6463)   
Checking out files:  90% (5817/6463)   
Checking out files:  91% (5882/6463)   
Checking out files:  92% (5946/6463)   
Checking out files:  93% (6011/6463)   
Checking out files:  94% (6076/6463)   
Checking out files:  95% (6140/6463)   
Checking out files:  96% (6205/6463)   
Checking out files:  97% (6270/6463)   
Checking out files:  98% (6334/6463)   
Checking out files:  99% (6399/6463)   
Checking out files: 100% (6463/6463)   
Checking out files: 100% (6463/6463), done.
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-mingw in qemu:fedora 
Packages installed:
SDL2-devel-2.0.9-1.fc28.x86_64
bc-1.07.1-5.fc28.x86_64
bison-3.0.4-9.fc28.x86_64
bluez-libs-devel-5.50-1.fc28.x86_64
brlapi-devel-0.6.7-19.fc28.x86_64
bzip2-1.0.6-26.fc28.x86_64
bzip2-devel-1.0.6-26.fc28.x86_64
ccache-3.4.2-2.fc28.x86_64
clang-6.0.1-2.fc28.x86_64
device-mapper-multipath-devel-0.7.4-3.git07e7bd5.fc28.x86_64
findutils-4.6.0-19.fc28.x86_64
flex-2.6.1-7.fc28.x86_64
gcc-8.2.1-5.fc28.x86_64
gcc-c++-8.2.1-5.fc28.x86_64
gettext-0.19.8.1-14.fc28.x86_64
git-2.17.2-1.fc28.x86_64
glib2-devel-2.56.3-2.fc28.x86_64
glusterfs-api-devel-4.1.5-1.fc28.x86_64
gnutls-devel-3.6.4-1.fc28.x86_64
gtk3-devel-3.22.30-1.fc28.x86_64
hostname-3.20-3.fc28.x86_64
libaio-devel-0.3.110-11.fc28.x86_64
libasan-8.2.1-5.fc28.x86_64
libattr-devel-2.4.48-3.fc28.x86_64
libcap-devel-2.25-9.fc28.x86_64
libcap-ng-devel-0.7.9-4.fc28.x86_64
libcurl-devel-7.59.0-8.fc28.x86_64
libfdt-devel-1.4.7-1.fc28.x86_64
libpng-devel-1.6.34-6.fc28.x86_64
librbd-devel-12.2

Re: [Qemu-devel] [PATCH v5 09/36] ppc/xive: notify the CPU when the interrupt priority is more privileged

2018-11-27 Thread David Gibson
On Wed, Nov 28, 2018 at 01:32:21PM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2018-11-28 at 11:13 +1100, David Gibson wrote:
> > Don't you need a cast to avoid (nsr << 8) being a shift-wider-than-size?
> 
> Shouldn't be a problem as long as it fits in an int, no ?

I dunno, I can never remember the rules about when C extends and when
it doesn't.  I'm not sure anybody does, which is kind of the point.

-- 
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 v5 11/36] spapr/xive: use the VCPU id as a NVT identifier

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:04AM +0100, Cédric Le Goater wrote:
> The IVPE scans the O/S CAM line of the XIVE thread interrupt contexts
> to find a matching Notification Virtual Target (NVT) among the NVTs
> dispatched on the HW processor threads.
> 
> On a real system, the thread interrupt contexts are updated by the
> hypervisor when a Virtual Processor is scheduled to run on a HW
> thread. Under QEMU, the model emulates the same behavior by hardwiring
> the NVT identifier in the thread context registers at reset.
> 
> The NVT identifier used by the sPAPRXive model is the VCPU id. The END
> identifier is also derived from the VCPU id. A set of helpers doing
> the conversion between identifiers are provided for the hcalls
> configuring the sources and the ENDs.
> 
> The model does not need a NVT table but The XiveRouter NVT operations
> are provided to perform some extra checks in the routing algorithm.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/spapr_xive.h |  17 +
>  include/hw/ppc/xive.h   |   3 +
>  hw/intc/spapr_xive.c| 136 
>  hw/intc/xive.c  |   9 +++
>  4 files changed, 165 insertions(+)
> 
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 06727bd86aa9..3f65b8f485fd 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -43,4 +43,21 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t 
> lisn);
>  void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
>  qemu_irq spapr_xive_qirq(sPAPRXive *xive, uint32_t lisn);
>  
> +/*
> + * sPAPR NVT and END indexing helpers
> + */
> +uint32_t spapr_xive_nvt_to_target(sPAPRXive *xive, uint8_t nvt_blk,
> +  uint32_t nvt_idx);
> +int spapr_xive_target_to_nvt(sPAPRXive *xive, uint32_t target,
> +uint8_t *out_nvt_blk, uint32_t *out_nvt_idx);
> +int spapr_xive_cpu_to_nvt(sPAPRXive *xive, PowerPCCPU *cpu,
> +  uint8_t *out_nvt_blk, uint32_t *out_nvt_idx);
> +
> +int spapr_xive_end_to_target(sPAPRXive *xive, uint8_t end_blk, uint32_t 
> end_idx,
> + uint32_t *out_server, uint8_t *out_prio);
> +int spapr_xive_target_to_end(sPAPRXive *xive, uint32_t target, uint8_t prio,
> + uint8_t *out_end_blk, uint32_t *out_end_idx);
> +int spapr_xive_cpu_to_end(sPAPRXive *xive, PowerPCCPU *cpu, uint8_t prio,
> +  uint8_t *out_end_blk, uint32_t *out_end_idx);
> +
>  #endif /* PPC_SPAPR_XIVE_H */
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index e715a6c6923d..e6931ddaa83f 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -187,6 +187,8 @@ typedef struct XiveRouter {
>  #define XIVE_ROUTER_GET_CLASS(obj)  \
>  OBJECT_GET_CLASS(XiveRouterClass, (obj), TYPE_XIVE_ROUTER)
>  
> +typedef struct XiveTCTX XiveTCTX;
> +
>  typedef struct XiveRouterClass {
>  SysBusDeviceClass parent;
>  
> @@ -201,6 +203,7 @@ typedef struct XiveRouterClass {
> XiveNVT *nvt);
>  int (*set_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> XiveNVT *nvt);
> +void (*reset_tctx)(XiveRouter *xrtr, XiveTCTX *tctx);
>  } XiveRouterClass;
>  
>  void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 5d038146c08e..3bf77ace11a2 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -199,6 +199,139 @@ static int spapr_xive_set_end(XiveRouter *xrtr,
>  return 0;
>  }
>  
> +static int spapr_xive_get_nvt(XiveRouter *xrtr,
> +  uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT 
> *nvt)
> +{
> +sPAPRXive *xive = SPAPR_XIVE(xrtr);
> +uint32_t vcpu_id = spapr_xive_nvt_to_target(xive, nvt_blk, nvt_idx);
> +PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);
> +
> +if (!cpu) {
> +return -1;
> +}
> +
> +/*
> + * sPAPR does not maintain a NVT table. Return that the NVT is
> + * valid if we have found a matching CPU
> + */
> +nvt->w0 = NVT_W0_VALID;
> +return 0;
> +}
> +
> +static int spapr_xive_set_nvt(XiveRouter *xrtr,
> +  uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT 
> *nvt)
> +{
> +/* no NVT table */
> +return 0;
> +}
> +
> +/*
> + * When a Virtual Processor is scheduled to run on a HW thread, the
> + * hypervisor pushes its identifier in the OS CAM line. Under QEMU, we
> + * need to emulate the same behavior.
> + */
> +static void spapr_xive_reset_tctx(XiveRouter *xrtr, XiveTCTX *tctx)
> +{
> +uint8_t  nvt_blk;
> +uint32_t nvt_idx;
> +uint32_t nvt_cam;
> +
> +spapr_xive_cpu_to_nvt(SPAPR_XIVE(xrtr), POWERPC_CPU(tctx->cs),
> +  &nvt_blk, &nvt_idx);
> +
> +nvt_cam = cpu_to_be32(TM_QW1W2_VO | xive_tctx_cam_line(nvt_blk, 
> nvt_idx));
> +mem

Re: [Qemu-devel] [PATCH v5 08/36] ppc/xive: introduce a simplified XIVE presenter

2018-11-27 Thread Benjamin Herrenschmidt
On Wed, 2018-11-28 at 10:49 +1100, David Gibson wrote:
> On Fri, Nov 16, 2018 at 11:57:01AM +0100, Cédric Le Goater wrote:
> > The last sub-engine of the XIVE architecture is the Interrupt
> > Virtualization Presentation Engine (IVPE). On HW, they share elements,
> > the Power Bus interface (CQ), the routing table descriptors, and they
> > can be combined in the same HW logic. We do the same in QEMU and
> > combine both engines in the XiveRouter for simplicity.
> 
> Ok, I'm not entirely convinced combining the IVPE and IVRE into a
> single object is a good idea, but we can probably discuss that once
> I've read further.

Keep in mind that the communication between the two is a bit more hairy
than simple notifications, though. Especially once we start
implementing escalation interrupts or worse, groups...

> > When the IVRE has completed its job of matching an event source with a
> > Notification Virtual Target (NVT) to notify, it forwards the event
> > notification to the IVPE sub-engine. The IVPE scans the thread
> > interrupt contexts of the Notification Virtual Targets (NVT)
> > dispatched on the HW processor threads and if a match is found, it
> > signals the thread. If not, the IVPE escalates the notification to
> > some other targets and records the notification in a backlog queue.
> > 
> > The IVPE maintains the thread interrupt context state for each of its
> > NVTs not dispatched on HW processor threads in the Notification
> > Virtual Target table (NVTT).
> > 
> > The model currently only supports single NVT notifications.
> > 
> > Signed-off-by: Cédric Le Goater 
> > ---
> >  include/hw/ppc/xive.h  |  13 +++
> >  include/hw/ppc/xive_regs.h |  22 
> >  hw/intc/xive.c | 223 +
> >  3 files changed, 258 insertions(+)
> > 
> > diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> > index 5987f26ddb98..e715a6c6923d 100644
> > --- a/include/hw/ppc/xive.h
> > +++ b/include/hw/ppc/xive.h
> > @@ -197,6 +197,10 @@ typedef struct XiveRouterClass {
> > XiveEND *end);
> >  int (*set_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
> > XiveEND *end);
> > +int (*get_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> > +   XiveNVT *nvt);
> > +int (*set_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> > +   XiveNVT *nvt);
> 
> As with the ENDs, I don't think get/set is a good interface for a
> bigger-than-word-size object.
> 
> >  } XiveRouterClass;
> >  
> >  void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);
> > @@ -207,6 +211,10 @@ int xive_router_get_end(XiveRouter *xrtr, uint8_t 
> > end_blk, uint32_t end_idx,
> >  XiveEND *end);
> >  int xive_router_set_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t 
> > end_idx,
> >  XiveEND *end);
> > +int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t 
> > nvt_idx,
> > +XiveNVT *nvt);
> > +int xive_router_set_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t 
> > nvt_idx,
> > +XiveNVT *nvt);
> >  
> >  /*
> >   * XIVE END ESBs
> > @@ -274,4 +282,9 @@ extern const MemoryRegionOps xive_tm_ops;
> >  
> >  void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
> >  
> > +static inline uint32_t xive_tctx_cam_line(uint8_t nvt_blk, uint32_t 
> > nvt_idx)
> > +{
> > +return (nvt_blk << 19) | nvt_idx;
> 
> I'm guessing this formula is the standard way of combining the NVT
> block and index into a single word?  If so, I think we should
> standardize on passing a single word "nvt_id" around and only
> splitting it when we need to use the block separately.  Same goes for
> the end_id, assuming there's a standard way of putting that into a
> single word.  That will address the point I raised earlier about lisn
> being passed around as a single word, but these later stage ids being
> split.
> 
> We'll probably want some inlines or macros to build an
> nvt/end/lisn/whatever id from block and index as well.
> 
> > +}
> > +
> >  #endif /* PPC_XIVE_H */
> > diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
> > index 2e3d6cb507da..05cb992d2815 100644
> > --- a/include/hw/ppc/xive_regs.h
> > +++ b/include/hw/ppc/xive_regs.h
> > @@ -158,4 +158,26 @@ typedef struct XiveEND {
> >  #define END_W7_F1_LOG_SERVER_ID  PPC_BITMASK32(1, 31)
> >  } XiveEND;
> >  
> > +/* Notification Virtual Target (NVT) */
> > +typedef struct XiveNVT {
> > +uint32_tw0;
> > +#define NVT_W0_VALID PPC_BIT32(0)
> > +uint32_tw1;
> > +uint32_tw2;
> > +uint32_tw3;
> > +uint32_tw4;
> > +uint32_tw5;
> > +uint32_tw6;
> > +uint32_tw7;
> > +uint32_tw8;
> > +#define NVT_W8_GRP_VALID PPC_BIT32(0)
> > +uint32_tw9;
> > +

Re: [Qemu-devel] [PATCH v5 09/36] ppc/xive: notify the CPU when the interrupt priority is more privileged

2018-11-27 Thread Benjamin Herrenschmidt
On Wed, 2018-11-28 at 11:13 +1100, David Gibson wrote:
> Don't you need a cast to avoid (nsr << 8) being a shift-wider-than-size?

Shouldn't be a problem as long as it fits in an int, no ?

Cheers,
Ben.




Re: [Qemu-devel] [RFC 38/48] translator: implement 2-pass translation

2018-11-27 Thread Emilio G. Cota
On Tue, Nov 27, 2018 at 14:06:57 -0500, Emilio G. Cota wrote:
> On Tue, Nov 27, 2018 at 14:48:11 +, Alex Bennée wrote:
> > With a little tweaking to the TCG we could then insert
> > our instrumentation at the end of the pass with all the knowledge we
> > want to export to the plugin.
> 
> After .translate_insn has returned for the last instruction, how
> do we insert the instrumentation that the plugin wants--say, a TB
> callback at the beginning of the TB, memory callbacks for the
> 2nd instruction, and an insn callback before the 3rd instruction
> executes?
> 
> I don't see how we could achieve that with "a little tweaking"
> instead of a 2nd pass, but I'd love to be wrong =)

(snip)
> > I don't quite follow. When we've done all our translation into TCG ops
> > haven't we by definition defined the TB?
> 
> Yes, that's precisely my point.
> 
> The part that's missing is that once the TB is defined, we want to
> insert instrumentation. Unfortunately, the "TCG ops" we get after
> the 1st pass (no instrumentation), are very different from the list
> of "TCG ops" that we get after the 2nd pass (after having injected
> instrumentation). Could we get the same output of the 2nd pass,
> just by using the output of the 1st and the list of injection points?
> It's probably possible, but it seems very hard to do. (Think for
> instance of memory callbacks, and further the complication of when
> they use helpers).
> 
> The only reasonable way to do this I think would be to leave behind
> "placeholder" TCG ops, that then we could scan to add further TCG ops.
> But you'll agree with me that the 2nd pass is simpler :P

It might not be that much simpler after all!

I am exploring the approach you suggested, that is IIUC to do a
single pass and then walk the list of Ops, adding (and
reordering) Ops based on what the plugins have requested.

Contrary to what I wrote earlier today (quoted above), this
approach seems quite promising, and certainly less ugly
than doing the 2 passes.

I just wrote some code to go over the list and add TB callbacks,
which go right before the first insn_start Op. The code is hack-ish
in that we first generate the TCG ops we need, which get added to
the end of the ops list, and then we go over those and move them
to where we want them to be (before insn_start, in this case).
But it works and it's less of a hack than doing the whole 2nd pass.

Insn callbacks will be trivial to implement this way; memory
callbacks should be harder because there are several qemu_ld/st
opcodes, but it should be doable; last, memory instrumentation
of helpers might actually be easier than with the 2 passes, because here
we just have to look for a Call TCG op to know whether a guest
instruction uses helpers, and if it does we can wrap the call
with the helpers to generate the setting/resetting of
CPUState.plugin_mem_cbs.

I'll try to do what's in the previous paragraph tomorrow -- I'm
appending what I did so far.

Thanks,

Emilio
---
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index ee9e179e14..232f645cd4 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -18,6 +18,7 @@
 #include "exec/gen-icount.h"
 #include "exec/log.h"
 #include "exec/translator.h"
+#include "exec/plugin-gen.h"
 
 /* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if
@@ -142,6 +143,11 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 gen_tb_end(db->tb, db->num_insns - bp_insn);
 
 if (plugin_enabled) {
+/* collect the plugins' instrumentation */
+qemu_plugin_tb_trans_cb(cpu, &tcg_ctx->plugin_tb);
+/* inject instrumentation */
+qemu_plugin_gen_inject();
+/* done */
 tcg_ctx->plugin_insn = NULL;
 }
 
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 75f182be37..cb5dbadc3c 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "qemu/queue.h"
 #include "cpu.h"
 #include "tcg/tcg.h"
 #include "tcg/tcg-op.h"
@@ -169,8 +170,61 @@ static void gen_vcpu_udata_cb(struct qemu_plugin_dyn_cb 
*cb)
 tcg_temp_free_i32(cpu_index);
 }
 
-void qemu_plugin_gen_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr)
+/* check that @a comes before @b */
+static inline void ops_check(const TCGOp *a, const TCGOp *b)
 {
+const TCGOp *op;
+bool seen_a = false;
+bool seen_b = false;
+
+tcg_debug_assert(a != b);
+QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
+if (op == a) {
+tcg_debug_assert(!seen_b);
+seen_a = true;
+} else if (op == b) {
+tcg_debug_assert(seen_a);
+seen_b = true;
+break;
+}
+}
+}
+
+/*
+ * Move ops from @from to @dest.
+ * @from must come after @dest in the list.
+ */
+static void ops_move(TCGOp *dest, TCGOp *from)
+{
+TCGOp *curr;
+
+#ifdef CONFIG_DEBUG_TCG
+ops_check(dest, from);
+#endi

Re: [Qemu-devel] [SeaBIOS] SeaBIOS booting time optimization

2018-11-27 Thread Kevin O'Connor
On Wed, Nov 21, 2018 at 12:43:34AM -0500, Stefan Berger wrote:
> On 11/20/18 11:51 AM, Stefano Garzarella wrote:
> > On Tue, Nov 20, 2018 at 5:13 PM Steve Douthit  
> > wrote:
> > > On 11/20/18 10:55 AM, Kevin O'Connor wrote:
> > > > FYI, this was raised a few months ago - see:
> > > > 
> > > > https://mail.coreboot.org/pipermail/seabios/2018-March/012186.html
> > > > 
> > > > IIRC, it should be possible to verify the TPM device is present before
> > > > trying to wait for it.
> > > We could skip probing entirely if there's no TCPA or TPM2 ACPI tables.
> > > There'd need to be some option to force probing in the case of
> > > missing/broken ACPI configurations.
> > I've just tried the
> > 0001-tpm-Check-for-TPM-related-ACPI-tables-before-attempt.patch
> > (https://mail.coreboot.org/pipermail/seabios/2018-March/012188.html)
> > and it solves my issue with the TPM.
> 
> I have tried it with the attached patch of that mail. We have to apply it,
> also for QEMU. It is this patch here:

Okay, thanks.  I applied Steve's patch.

-Kevin



Re: [Qemu-devel] [PATCH] riscv/cpu: use device_class_set_parent_realize

2018-11-27 Thread maozy

Hi, Palmer

On 11/28/18 8:34 AM, Palmer Dabbelt wrote:

On Mon, 26 Nov 2018 01:06:33 PST (-0800), Bastian Koppelmann wrote:

On 11/26/18 4:20 AM, Mao Zhongyi wrote:

Signed-off-by: Mao Zhongyi 
---
  target/riscv/cpu.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)



Reviewed-by: Bastian Koppelmann 


Shouldn't we also use device_class_set_parent_reset right below this?  


device_class_set_parent_reset only used for DeviceClass *dc->reset, here
is CPUClass *cc->reset.

Thanks,
Mao


Either
way, I'll queue this one for 3.2.

Thanks!







Re: [Qemu-devel] [RFC 23/48] translator: add plugin_insn argument to translate_insn

2018-11-27 Thread Emilio G. Cota
On Tue, Nov 27, 2018 at 19:54:02 -0500, Emilio G. Cota wrote:
> To avoid altering the signature of .translate_insn, I've modified
> arm_ldl_code directly, as follows:
> 
>  uint32_t insn = cpu_ldl_code(env, addr);
> +
>  if (bswap_code(sctlr_b)) {
> -return bswap32(insn);
> +insn = bswap32(insn);
> +}
> +if (tcg_ctx->plugin_insn) {
> +qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn, sizeof(insn));
>  }
>  return insn;
>  }

Turns out it got even more complicated with thumb, since instructions
can be 16 or 32 bits.

I ended up with the appended (qemu_plugin_insn_append() returns
when the first argument is NULL).

Emilio

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 88195ab949..e6caaff976 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -38,6 +38,7 @@
 #include "trace-tcg.h"
 #include "translate-a64.h"
 #include "qemu/atomic128.h"
+#include "qemu/plugin.h"
 
 static TCGv_i64 cpu_X[32];
 static TCGv_i64 cpu_pc;
@@ -13321,6 +13322,7 @@ static void disas_a64_insn(CPUARMState *env, 
DisasContext *s)
 uint32_t insn;
 
 insn = arm_ldl_code(env, s->pc, s->sctlr_b);
+qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn, sizeof(insn));
 s->insn = insn;
 s->pc += 4;
 
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 7c4675ffd8..7523257b85 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -36,6 +36,7 @@
 
 #include "trace-tcg.h"
 #include "exec/log.h"
+#include "qemu/plugin.h"
 
 
 #define ENABLE_ARCH_4Tarm_dc_feature(s, ARM_FEATURE_V4T)
@@ -13234,6 +13235,7 @@ static void arm_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 }
 
 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
+qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn, sizeof(insn));
 dc->insn = insn;
 dc->pc += 4;
 disas_arm_insn(dc, insn);
@@ -13304,11 +13306,16 @@ static void thumb_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
 is_16bit = thumb_insn_is_16bit(dc, insn);
 dc->pc += 2;
-if (!is_16bit) {
+if (is_16bit) {
+uint16_t insn16 = insn;
+
+qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn16, sizeof(insn16));
+} else {
 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
 
 insn = insn << 16 | insn2;
 dc->pc += 2;
+qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn, sizeof(insn));
 }
 dc->insn = insn;
 



[Qemu-devel] (no subject)

2018-11-27 Thread John Arbuckle
>From af4497f2b161bb4165acb8eee5cae3f2a7ea2227 Mon Sep 17 00:00:00 2001
From: John Arbuckle 
Date: Tue, 27 Nov 2018 20:01:20 -0500
Subject: [PATCH] ui/cocoa.m: fix crash due to cocoa_refresh() on Mac OS 10.14

Mac OS 10.14 only wants UI code to be called from the main thread. The
cocoa_refresh() function is called on another thread and this causes a
crash to take place. To fix this problem the cocoa_refresh() code is
called from the main thread only. 

Signed-off-by: John Arbuckle 
---
 ui/cocoa.m | 59 ++-
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index ecf12bfc2e..17c168d08f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -972,6 +972,8 @@ - (void)openDocumentation:(NSString *)filename;
 - (IBAction) do_about_menu_item: (id) sender;
 - (void)make_about_window;
 - (void)adjustSpeed:(id)sender;
+- (void) cocoa_refresh;
+- (void) cocoa_refresh_internal: (id) dummy;
 @end
 
 @implementation QemuCocoaAppController
@@ -1406,6 +1408,37 @@ - (void)adjustSpeed:(id)sender
 COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(), 
'%');
 }
 
+- (void) cocoa_refresh
+{
+[self performSelectorOnMainThread: @selector(cocoa_refresh_internal:) 
withObject: nil waitUntilDone: YES];
+}
+
+- (void) cocoa_refresh_internal: (id) dummy
+{
+COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
+graphic_hw_update(NULL);
+
+if (qemu_input_is_absolute()) {
+if (![cocoaView isAbsoluteEnabled]) {
+if ([cocoaView isMouseGrabbed]) {
+[cocoaView ungrabMouse];
+}
+}
+[cocoaView setAbsoluteEnabled:YES];
+}
+
+NSDate *distantPast;
+NSEvent *event;
+distantPast = [NSDate distantPast];
+do {
+event = [NSApp nextEventMatchingMask:NSEventMaskAny 
untilDate:distantPast
+  inMode: NSDefaultRunLoopMode 
dequeue:YES];
+if (event != nil) {
+[cocoaView handleEvent:event];
+}
+} while(event != nil);
+}
+
 @end
 
 
@@ -1579,31 +1612,7 @@ static void cocoa_switch(DisplayChangeListener *dcl,
 
 static void cocoa_refresh(DisplayChangeListener *dcl)
 {
-NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
-COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
-graphic_hw_update(NULL);
-
-if (qemu_input_is_absolute()) {
-if (![cocoaView isAbsoluteEnabled]) {
-if ([cocoaView isMouseGrabbed]) {
-[cocoaView ungrabMouse];
-}
-}
-[cocoaView setAbsoluteEnabled:YES];
-}
-
-NSDate *distantPast;
-NSEvent *event;
-distantPast = [NSDate distantPast];
-do {
-event = [NSApp nextEventMatchingMask:NSEventMaskAny 
untilDate:distantPast
-inMode: NSDefaultRunLoopMode dequeue:YES];
-if (event != nil) {
-[cocoaView handleEvent:event];
-}
-} while(event != nil);
-[pool release];
+[[NSApp delegate] cocoa_refresh];
 }
 
 static void cocoa_cleanup(void)
-- 
2.14.3 (Apple Git-98)




Re: [Qemu-devel] [PATCH v5 10/36] spapr/xive: introduce a XIVE interrupt controller

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:03AM +0100, Cédric Le Goater wrote:
> sPAPRXive models the XIVE interrupt controller of the sPAPR machine.
> It inherits from the XiveRouter and provisions storage for the routing
> tables :
> 
>   - Event Assignment Structure (EAS)
>   - Event Notification Descriptor (END)
> 
> The sPAPRXive model incorporates an internal XiveSource for the IPIs
> and for the interrupts of the virtual devices of the guest. This model
> is consistent with XIVE architecture which also incorporates an
> internal IVSE for IPIs and accelerator interrupts in the IVRE
> sub-engine.
> 
> The sPAPRXive model exports two memory regions, one for the ESB
> trigger and management pages used to control the sources and one for
> the TIMA pages. They are mapped by default at the addresses found on
> chip 0 of a baremetal system. This is also consistent with the XIVE
> architecture which defines a Virtualization Controller BAR for the
> internal IVSE ESB pages and a Thread Managment BAR for the TIMA.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  default-configs/ppc64-softmmu.mak |   1 +
>  include/hw/ppc/spapr_xive.h   |  46 +
>  hw/intc/spapr_xive.c  | 323 ++
>  hw/intc/Makefile.objs |   1 +
>  4 files changed, 371 insertions(+)
>  create mode 100644 include/hw/ppc/spapr_xive.h
>  create mode 100644 hw/intc/spapr_xive.c
> 
> diff --git a/default-configs/ppc64-softmmu.mak 
> b/default-configs/ppc64-softmmu.mak
> index 2d1e7c5c4668..7f34ad0528ed 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -17,6 +17,7 @@ CONFIG_XICS=$(CONFIG_PSERIES)
>  CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
>  CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
>  CONFIG_XIVE=$(CONFIG_PSERIES)
> +CONFIG_XIVE_SPAPR=$(CONFIG_PSERIES)
>  CONFIG_MEM_DEVICE=y
>  CONFIG_DIMM=y
>  CONFIG_SPAPR_RNG=y
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> new file mode 100644
> index ..06727bd86aa9
> --- /dev/null
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -0,0 +1,46 @@
> +/*
> + * QEMU PowerPC sPAPR XIVE interrupt controller model
> + *
> + * Copyright (c) 2017-2018, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#ifndef PPC_SPAPR_XIVE_H
> +#define PPC_SPAPR_XIVE_H
> +
> +#include "hw/sysbus.h"
> +#include "hw/ppc/xive.h"
> +
> +#define TYPE_SPAPR_XIVE "spapr-xive"
> +#define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE)
> +
> +typedef struct sPAPRXive {
> +XiveRouterparent;
> +
> +/* Internal interrupt source for IPIs and virtual devices */
> +XiveSourcesource;
> +hwaddrvc_base;
> +
> +/* END ESB MMIOs */
> +XiveENDSource end_source;
> +hwaddrend_base;
> +
> +/* Routing table */
> +XiveEAS   *eat;
> +uint32_t  nr_irqs;
> +XiveEND   *endt;
> +uint32_t  nr_ends;
> +
> +/* TIMA mapping address */
> +hwaddrtm_base;
> +MemoryRegion  tm_mmio;
> +} sPAPRXive;
> +
> +bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi);
> +bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn);
> +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
> +qemu_irq spapr_xive_qirq(sPAPRXive *xive, uint32_t lisn);
> +
> +#endif /* PPC_SPAPR_XIVE_H */
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> new file mode 100644
> index ..5d038146c08e
> --- /dev/null
> +++ b/hw/intc/spapr_xive.c
> @@ -0,0 +1,323 @@
> +/*
> + * QEMU PowerPC sPAPR XIVE interrupt controller model
> + *
> + * Copyright (c) 2017-2018, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "target/ppc/cpu.h"
> +#include "sysemu/cpus.h"
> +#include "monitor/monitor.h"
> +#include "hw/ppc/spapr.h"
> +#include "hw/ppc/spapr_xive.h"
> +#include "hw/ppc/xive.h"
> +#include "hw/ppc/xive_regs.h"
> +
> +/*
> + * XIVE Virtualization Controller BAR and Thread Managment BAR that we
> + * use for the ESB pages and the TIMA pages
> + */
> +#define SPAPR_XIVE_VC_BASE   0x00060100ull
> +#define SPAPR_XIVE_TM_BASE   0x000603020318ull
> +
> +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon)
> +{
> +int i;
> +uint32_t offset = 0;
> +
> +monitor_printf(mon, "XIVE Source %08x .. %08x\n", offset,
> +   offset + xive->source.nr_irqs - 1);
> +xive_source_pic_print_info(&xive->source, offset, mon);
> +
> +monitor_printf(mon, "XIVE EAT %08x .. %08x\n", 0, xive->nr_irqs - 1);
> +for (i = 0; i < xive->nr_irqs; i++) {
> +xive_eas_pic_print_info(&xive->eat[i], i, mon);
> +}
> +
> +monitor_printf(mon, "XIVE ENDT %08x .. %08x\n", 0, xive->nr_ends - 1);

Re: [Qemu-devel] [RFC 23/48] translator: add plugin_insn argument to translate_insn

2018-11-27 Thread Emilio G. Cota
On Mon, Nov 26, 2018 at 20:38:25 -0500, Emilio G. Cota wrote:
> On Mon, Nov 26, 2018 at 11:30:25 -0800, Richard Henderson wrote:
> > On 11/26/18 11:07 AM, Emilio G. Cota wrote:
> > > The main reason why I added the qemu_plugin_insn_append calls
> > > was to avoid reading the instructions twice from guest memory,
> > > because I was worried that doing so might somehow alter the
> > > guest's execution, e.g. what if we read a cross-page instruction,
> > > and both pages mapped to the same TLB entry? We'd end up having
> > > more TLB misses because instrumentation was enabled.
> > 
> > A better solution for this, I think is to change direct calls from
> > 
> >   cpu_ldl_code(env, pc);
> > to
> >   translator_ldl_code(dc_base, env, pc);
> > 
> > instead of passing around a new argument separate from DisasContextBase?
> 
> I think this + diff'ing pc_next should work to figure out the
> contents and size of each instruction.

I just tried doing things this way.

For some targets like i386, the translator_ld* helpers work
great; the instruction contents are copied, and through
the helpers we get the sizes of the instructions as well.

For ARM though (and maybe others, I haven't gone
through all of them yet), arm_ldl_code does the following:

/* Load an instruction and return it in the standard little-endian order */
static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
bool sctlr_b)
{
uint32_t insn = cpu_ldl_code(env, addr);
if (bswap_code(sctlr_b)) {
return bswap32(insn);
}
return insn;
}

To avoid altering the signature of .translate_insn, I've modified
arm_ldl_code directly, as follows:

 uint32_t insn = cpu_ldl_code(env, addr);
+
 if (bswap_code(sctlr_b)) {
-return bswap32(insn);
+insn = bswap32(insn);
+}
+if (tcg_ctx->plugin_insn) {
+qemu_plugin_insn_append(tcg_ctx->plugin_insn, &insn, sizeof(insn));
 }
 return insn;
 }

(NB. tcg_ctx->plugin_insn is updated by translator_loop
on every iteration.)

Let me know if you think I should do this differently.

Thanks,

Emilio



[Qemu-devel] What will happen if guest write to a memory address which not exists in any kvm memory slot?

2018-11-27 Thread Changlimin
For a multiple cpu guest, during cpu 0 delete a memory sot then add it,
if cpu 1 write the memory address which belong to the deleted memory slot and 
not exist in PTE,
kvm_mmu_page_fault fail, then return the QEMU with the reason KVM_EXIT_MMIO,
QEMU will also fail, What will happen in Guest?

This is the trace of kvm_set_memory_region, slot 0 is often deleted then added,
Maybe there is a memory write in guest after delete and before add.

# trace-bpfcc -I 
/usr/src/linux-headers-4.18.0-10-generic/include/uapi/linux/kvm.h \
'p::kvm_set_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region 
*mem), \
"slot %d addr %x size %x", mem->slot,mem->guest_phys_addr,mem->memory_size'

PID TID COMMFUNC -
80198019qemu-system-x86 kvm_set_memory_region slot 0 addr 0 size 
4000
80198019qemu-system-x86 kvm_set_memory_region slot 1 addr fffe size 0
80198019qemu-system-x86 kvm_set_memory_region slot 1 addr fffe size 
2
80198019qemu-system-x86 kvm_set_memory_region slot 0 addr 0 size 0
80198019qemu-system-x86 kvm_set_memory_region slot 0 addr 0 size c
80198019qemu-system-x86 kvm_set_memory_region slot 2 addr c size 0
80198019qemu-system-x86 kvm_set_memory_region slot 2 addr c size 
2
80198019qemu-system-x86 kvm_set_memory_region slot 3 addr e size 0
80198019qemu-system-x86 kvm_set_memory_region slot 3 addr e size 
2
80198019qemu-system-x86 kvm_set_memory_region slot 4 addr 10 size 
3ff0
80198019qemu-system-x86 kvm_set_memory_region slot 0 addr 0 size 0
80198019qemu-system-x86 kvm_set_memory_region slot 0 addr 0 size a


Re: [Qemu-devel] [PATCH] scsi: Address spurious clang warning

2018-11-27 Thread Peter Maydell
On Tue, 27 Nov 2018 at 18:49, John Snow  wrote:
>
> Some versions of Clang prior to 6.0 (and some builds of clang after,
> such as 6.0.1-2.fc28) fail to recognize { 0 } as a valid initializer
> for a struct with subobjects when -Wmissing-braces is enabled.
>
> https://bugs.llvm.org/show_bug.cgi?id=21689 and
> https://reviews.llvm.org/rL314499 suggests this should be fixed in 6.0,
> but it might not be the case for older versions or downstream versions.
>
> For now, follow the precedent of ebf2a499 and replace the standard { 0 }
> with the accepted { } to silence this warning and allow the build to
> work under clang 6.0.1-2.fc28, and builds prior to 6.0.
>
> Signed-off-by: John Snow 

Applied to master as a build fix for rc3, thanks.

-- PMM



Re: [Qemu-devel] [PATCH] riscv/cpu: use device_class_set_parent_realize

2018-11-27 Thread Palmer Dabbelt

On Mon, 26 Nov 2018 01:06:33 PST (-0800), Bastian Koppelmann wrote:

On 11/26/18 4:20 AM, Mao Zhongyi wrote:

Signed-off-by: Mao Zhongyi 
---
  target/riscv/cpu.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)



Reviewed-by: Bastian Koppelmann 


Shouldn't we also use device_class_set_parent_reset right below this?  Either
way, I'll queue this one for 3.2.

Thanks!



Re: [Qemu-devel] [PATCH v5 08/36] ppc/xive: introduce a simplified XIVE presenter

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:01AM +0100, Cédric Le Goater wrote:
> The last sub-engine of the XIVE architecture is the Interrupt
> Virtualization Presentation Engine (IVPE). On HW, they share elements,
> the Power Bus interface (CQ), the routing table descriptors, and they
> can be combined in the same HW logic. We do the same in QEMU and
> combine both engines in the XiveRouter for simplicity.

Ok, I'm not entirely convinced combining the IVPE and IVRE into a
single object is a good idea, but we can probably discuss that once
I've read further.

> When the IVRE has completed its job of matching an event source with a
> Notification Virtual Target (NVT) to notify, it forwards the event
> notification to the IVPE sub-engine. The IVPE scans the thread
> interrupt contexts of the Notification Virtual Targets (NVT)
> dispatched on the HW processor threads and if a match is found, it
> signals the thread. If not, the IVPE escalates the notification to
> some other targets and records the notification in a backlog queue.
> 
> The IVPE maintains the thread interrupt context state for each of its
> NVTs not dispatched on HW processor threads in the Notification
> Virtual Target table (NVTT).
> 
> The model currently only supports single NVT notifications.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ppc/xive.h  |  13 +++
>  include/hw/ppc/xive_regs.h |  22 
>  hw/intc/xive.c | 223 +
>  3 files changed, 258 insertions(+)
> 
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 5987f26ddb98..e715a6c6923d 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -197,6 +197,10 @@ typedef struct XiveRouterClass {
> XiveEND *end);
>  int (*set_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
> XiveEND *end);
> +int (*get_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> +   XiveNVT *nvt);
> +int (*set_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> +   XiveNVT *nvt);

As with the ENDs, I don't think get/set is a good interface for a
bigger-than-word-size object.

>  } XiveRouterClass;
>  
>  void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);
> @@ -207,6 +211,10 @@ int xive_router_get_end(XiveRouter *xrtr, uint8_t 
> end_blk, uint32_t end_idx,
>  XiveEND *end);
>  int xive_router_set_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
>  XiveEND *end);
> +int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> +XiveNVT *nvt);
> +int xive_router_set_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
> +XiveNVT *nvt);
>  
>  /*
>   * XIVE END ESBs
> @@ -274,4 +282,9 @@ extern const MemoryRegionOps xive_tm_ops;
>  
>  void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
>  
> +static inline uint32_t xive_tctx_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
> +{
> +return (nvt_blk << 19) | nvt_idx;

I'm guessing this formula is the standard way of combining the NVT
block and index into a single word?  If so, I think we should
standardize on passing a single word "nvt_id" around and only
splitting it when we need to use the block separately.  Same goes for
the end_id, assuming there's a standard way of putting that into a
single word.  That will address the point I raised earlier about lisn
being passed around as a single word, but these later stage ids being
split.

We'll probably want some inlines or macros to build an
nvt/end/lisn/whatever id from block and index as well.

> +}
> +
>  #endif /* PPC_XIVE_H */
> diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
> index 2e3d6cb507da..05cb992d2815 100644
> --- a/include/hw/ppc/xive_regs.h
> +++ b/include/hw/ppc/xive_regs.h
> @@ -158,4 +158,26 @@ typedef struct XiveEND {
>  #define END_W7_F1_LOG_SERVER_ID  PPC_BITMASK32(1, 31)
>  } XiveEND;
>  
> +/* Notification Virtual Target (NVT) */
> +typedef struct XiveNVT {
> +uint32_tw0;
> +#define NVT_W0_VALID PPC_BIT32(0)
> +uint32_tw1;
> +uint32_tw2;
> +uint32_tw3;
> +uint32_tw4;
> +uint32_tw5;
> +uint32_tw6;
> +uint32_tw7;
> +uint32_tw8;
> +#define NVT_W8_GRP_VALID PPC_BIT32(0)
> +uint32_tw9;
> +uint32_twa;
> +uint32_twb;
> +uint32_twc;
> +uint32_twd;
> +uint32_twe;
> +uint32_twf;
> +} XiveNVT;
> +
>  #endif /* PPC_XIVE_REGS_H */
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 4c6cb5d52975..5ba3b06e6e25 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -373,6 +373,32 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor 
> *mon)
>  }
>  }
>  
> +/* The H

[Qemu-devel] [PATCH v1 1/1] riscv: Ensure the kernel start address is correctly cast

2018-11-27 Thread Alistair Francis
Cast the kernel start address to the target bit length.

This ensures that we calculate the initrd offset to a valid address for
the architecture.

Signed-off-by: Alistair Francis 
Suggested-by: Alexander Graf 
Reported-by: Alexander Graf 
---
 hw/riscv/sifive_e.c | 2 +-
 hw/riscv/sifive_u.c | 2 +-
 hw/riscv/spike.c| 2 +-
 hw/riscv/virt.c | 3 ++-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index cb513cc3bb..3427b840cb 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -74,7 +74,7 @@ static const struct MemmapEntry {
 [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
 };
 
-static uint64_t load_kernel(const char *kernel_filename)
+static target_ulong load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ef07df2442..5d03a76a28 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -65,7 +65,7 @@ static const struct MemmapEntry {
 
 #define GEM_REVISION0x10070109
 
-static uint64_t load_kernel(const char *kernel_filename)
+static target_ulong load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 268df04c3c..79cb4c1282 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -53,7 +53,7 @@ static const struct MemmapEntry {
 [SPIKE_DRAM] = { 0x8000,0x0 },
 };
 
-static uint64_t load_kernel(const char *kernel_filename)
+static target_ulong load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2b38f89070..f4cbf6aa21 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -57,7 +57,7 @@ static const struct MemmapEntry {
 [VIRT_DRAM] = { 0x8000,0x0 },
 };
 
-static uint64_t load_kernel(const char *kernel_filename)
+static target_ulong load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
@@ -85,6 +85,7 @@ static hwaddr load_initrd(const char *filename, uint64_t 
mem_size,
  * halfway into RAM, and for boards with 256MB of RAM or more we put
  * the initrd at 128MB.
  */
+/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
 *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
 
 size = load_ramdisk(filename, *start, mem_size - *start);
-- 
2.19.1




Re: [Qemu-devel] [PATCH v5 09/36] ppc/xive: notify the CPU when the interrupt priority is more privileged

2018-11-27 Thread David Gibson
On Fri, Nov 16, 2018 at 11:57:02AM +0100, Cédric Le Goater wrote:
> After the event data was pushed in the O/S Event Queue, the IVPE
> raises the bit corresponding to the priority of the pending interrupt
> in the register IBP (Interrupt Pending Buffer) to indicate there is an
> event pending in one of the 8 priority queues. The Pending Interrupt
> Priority Register (PIPR) is also updated using the IPB. This register
> represent the priority of the most favored pending notification.
> 
> The PIPR is then compared to the the Current Processor Priority
> Register (CPPR). If it is more favored (numerically less than), the
> CPU interrupt line is raised and the EO bit of the Notification Source
> Register (NSR) is updated to notify the presence of an exception for
> the O/S. The check needs to be done whenever the PIPR or the CPPR are
> changed.
> 
> The O/S acknowledges the interrupt with a special load in the Thread
> Interrupt Management Area. If the EO bit of the NSR is set, the CPPR
> takes the value of PIPR. The bit number in the IBP corresponding to
> the priority of the pending interrupt is reseted and so is the EO bit
> of the NSR.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/intc/xive.c | 94 +-
>  1 file changed, 93 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 5ba3b06e6e25..c49932d2b799 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -21,9 +21,73 @@
>   * XIVE Thread Interrupt Management context
>   */
>  
> +/* Convert a priority number to an Interrupt Pending Buffer (IPB)
> + * register, which indicates a pending interrupt at the priority
> + * corresponding to the bit number
> + */
> +static uint8_t priority_to_ipb(uint8_t priority)
> +{
> +return priority > XIVE_PRIORITY_MAX ?
> +0 : 1 << (XIVE_PRIORITY_MAX - priority);
> +}
> +
> +/* Convert an Interrupt Pending Buffer (IPB) register to a Pending
> + * Interrupt Priority Register (PIPR), which contains the priority of
> + * the most favored pending notification.
> + */
> +static uint8_t ipb_to_pipr(uint8_t ibp)
> +{
> +return ibp ? clz32((uint32_t)ibp << 24) : 0xff;
> +}
> +
> +static void ipb_update(uint8_t *regs, uint8_t priority)
> +{
> +regs[TM_IPB] |= priority_to_ipb(priority);
> +regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
> +}
> +
> +static uint8_t exception_mask(uint8_t ring)
> +{
> +switch (ring) {
> +case TM_QW1_OS:
> +return TM_QW1_NSR_EO;
> +default:
> +g_assert_not_reached();
> +}
> +}
> +
>  static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
>  {
> -return 0;
> +uint8_t *regs = &tctx->regs[ring];
> +uint8_t nsr = regs[TM_NSR];
> +uint8_t mask = exception_mask(ring);
> +
> +qemu_irq_lower(tctx->output);
> +
> +if (regs[TM_NSR] & mask) {
> +uint8_t cppr = regs[TM_PIPR];
> +
> +regs[TM_CPPR] = cppr;
> +
> +/* Reset the pending buffer bit */
> +regs[TM_IPB] &= ~priority_to_ipb(cppr);
> +regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
> +
> +/* Drop Exception bit */
> +regs[TM_NSR] &= ~mask;
> +}
> +
> +return (nsr << 8) | regs[TM_CPPR];

Don't you need a cast to avoid (nsr << 8) being a shift-wider-than-size?

> +}
> +
> +static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
> +{
> +uint8_t *regs = &tctx->regs[ring];
> +
> +if (regs[TM_PIPR] < regs[TM_CPPR]) {
> +regs[TM_NSR] |= exception_mask(ring);
> +qemu_irq_raise(tctx->output);
> +}
>  }
>  
>  static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
> @@ -33,6 +97,9 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t 
> ring, uint8_t cppr)
>  }
>  
>  tctx->regs[ring + TM_CPPR] = cppr;
> +
> +/* CPPR has changed, check if we need to raise a pending exception */
> +xive_tctx_notify(tctx, ring);
>  }
>  
>  /*
> @@ -198,6 +265,17 @@ static void xive_tm_set_os_cppr(XiveTCTX *tctx, hwaddr 
> offset,
>  xive_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff);
>  }
>  
> +/*
> + * Adjust the IPB to allow a CPU to process event queues of other
> + * priorities during one physical interrupt cycle.
> + */
> +static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset,
> +   uint64_t value, unsigned size)
> +{
> +ipb_update(&tctx->regs[TM_QW1_OS], value & 0xff);
> +xive_tctx_notify(tctx, TM_QW1_OS);
> +}
> +
>  /*
>   * Define a mapping of "special" operations depending on the TIMA page
>   * offset and the size of the operation.
> @@ -220,6 +298,7 @@ static const XiveTmOp xive_tm_operations[] = {
>  
>  /* MMIOs above 2K : special operations with side effects */
>  { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg },
> +{ XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, 
> NULL },
>  };
>  
>  static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool 
> write)

Re: [Qemu-devel] [PATCH v5 04/36] ppc/xive: introduce the XiveRouter model

2018-11-27 Thread David Gibson
On Tue, Nov 27, 2018 at 08:30:15AM +0100, Cédric Le Goater wrote:
> On 11/27/18 1:11 AM, David Gibson wrote:
> > On Mon, Nov 26, 2018 at 10:39:44AM +0100, Cédric Le Goater wrote:
> >> On 11/26/18 6:44 AM, David Gibson wrote:
> >>> On Fri, Nov 23, 2018 at 11:28:24AM +0100, Cédric Le Goater wrote:
>  On 11/23/18 2:10 AM, David Gibson wrote:
> > On Thu, Nov 22, 2018 at 05:50:07PM +1100, Benjamin Herrenschmidt wrote:
> >> On Thu, 2018-11-22 at 15:44 +1100, David Gibson wrote:
> >>>
> >>> Sorry, didn't think of this in my first reply.
> >>>
> >>> 1) Does the hardware ever actually write back to the EAS?  I know it
> >>> does for the END, but it's not clear why it would need to for the
> >>> EAS.  If not, we don't need the setter.
> >>
> >> Nope, though the PAPR model will via hcalls
> >
> > Right, bit AIUI the set_eas hook is about abstracting PAPR vs bare
> > metal details.  Since the hcall knows it's PAPR it can just update the
> > backing information for the EAS directly, and no need for an
> > abstracted hook.
> 
>  Indeed, the first versions of the XIVE patchset did not use such hooks, 
>  but when discussed we said we wanted abstract methods for the router 
>  to validate the overall XIVE model, which is useful for PowerNV. 
> 
>  We can change again and have the hcalls get/set directly in the EAT
>  and ENDT. It would certainly simplify the sPAPR model.
> >>>
> >>> I think that's the better approach.
> >>
> >> ok. let's keep that in mind for  : 
> >>
> >>  [PATCH v5 11/36] spapr/xive: use the VCPU id as a NVT identifier
> >>  [PATCH v5 16/36] spapr: add hcalls support for the XIVE exploitation
> >>
> >> which are using the XiveRouter methods to access the controller EAT 
> >> and ENDT. I thought that was good practice to validate the model but 
> >> we can use direct sPAPR table accessors or none at all.
> > 
> > Ok.  Consistency is good as a general rule, but I don't think it makes
> > sense to force the EAT and the ENDT into the same model.  
> 
> What do you mean by model ? the QEMU machine IC model ?

Oh, sorry, nothing that formal.  By "model" I just meant the same
pattern of accessor hooks.  They certainly do belong in the same qemu
object.

> > The EAT is
> > pure configuration, whereas the the ENDT has both configuration and
> > status.  Or to look at it another way, the EAT is purely software
> > controlled, whereas the ENDT is at least partially hardware
> > controlled.
> 
> yes but the EAT and the ENDT are XIVE internal tables of the same XIVE 
> sub-engine, the IVRE, Interrupt Virtualization Routing Engine, formely 
> known as VC, for Virtualization Controller. the EAS is just an entry 
> point to the ENDT. I don't see why we would use different models for 
> them.
> 
> > (I realize that gets a bit fuzzy when considering PAPR, but I think
> > from the point of view of the XIVE model it makes sense to treat the
> > PAPR hypervisor logic as "software", even though it's "hardware" from the
> > guest point of view).
> 
> That I agree but the resulting code is too ugly in the hcalls. Tell me 
> when you reach patch 11, which links the machine IC model sPAPRXive to 
> the generic XiveRouter and also check patch 16 introducing the hcalls, 
> which update the XIVE internal tables.
> 
> Thanks,
> 
> C. 
> 
>  
> >>
> >>
> >> I think these prereq patches could be merged now :
> >>
> >>  [PATCH v5 12/36] spapr: initialize VSMT before initializing the IRQ
> >>  [PATCH v5 13/36] spapr: introduce a spapr_irq_init() routine
> >>  [PATCH v5 14/36] spapr: modify the irq backend 'init' method
> >>
> >> This one also :
> >>
> >>  [PATCH v5 21/36] spapr: extend the sPAPR IRQ backend for XICS
> >>
> >> Thanks,
> >>
> >> C. 
> >>
> > 
> 

-- 
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 for-4.0 0/9] ppc: get rid of g_malloc(sizeof(T) * n)

2018-11-27 Thread David Gibson
On Tue, Nov 27, 2018 at 02:04:53PM +0100, Greg Kurz wrote:
> As explained in HACKING, the g_malloc(sizeof(T) * n) construct is unsafe
> because it can't detect multiplication overflowing size_t and doesn't
> allow type checking.
> 
> It appears to be used in a bunch of places though:
> 
> $ git grep -E 'malloc.*sizeof' | grep ' \* '  | wc -l
> 101
> 
> This series fixes the ppc target and ppc machine code. The changes are
> mostly trivial. Only the mac99 and e500 machines required some more work
> that should be reviewed carefully, as it was only compile-tested.

Series applied, thanks.


-- 
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] [Bug 1805445] Re: QEMU arm virt machine was stopped by STMFD command while debug process

2018-11-27 Thread Peter Maydell
No, that is not something that QEMU supports. There is no such thing as
a "generic arm board". All arm boards are different hardware, and we
model only a few boards. We don't provide "put together your own model
from building blocks" functionality, I'm afraid, and it's unlikely we
ever will in future.

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

Title:
  QEMU arm virt machine was stopped by STMFD command while debug process

Status in QEMU:
  New

Bug description:
  Hello, i have a big problem with QEMU arm virtual machine. So...
  I run QEMU machine with bare-metal ThreadX fullflash from Texet TM-333 phone  
(Spreadtrum platform)
  [CODE]qemu-system-arm -S -gdb tcp::1234,ipv4 -drive 
file=C:\cygwin64\home\flash.bin,if=mtd,format=raw -M palmetto-bmc -cpu arm926 
-m 64M[/CODE]
  I use palmetto-bmc platform because it have ARM926EJ-S core and support SPI 
Flash.
  Then, i attach to gdb qemu process from IDA and run code step-by-step.

  
  When the IDA run 00032534 STR R11, [R10] command

  
  instead of store R11 on R10 adress, it jump 000328DC STMFD SP!, {R0-R12,LR} 
instruction...

  and virt machine not execute new instruction...
  [IMG]https://pp.userapi.com/c850624/v850624111/528f3/N7FTpgloWVU.jpg[/IMG]

  and why i did not change flash from n25q256a to n25q032a11 in aspeed.c
  without rebuild qemu?

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



Re: [Qemu-devel] [PULL v3 00/14] Misc patches for QEMU 3.1.0-rc3

2018-11-27 Thread Peter Maydell
On Tue, 27 Nov 2018 at 19:00, Paolo Bonzini  wrote:
>
> The following changes since commit 4822f1ee9efa8df56e29db0a68323b484bdb0335:
>
>   Merge remote-tracking branch 
> 'remotes/kraxel/tags/fixes-31-20181127-pull-request' into staging (2018-11-27 
> 11:21:38 +)
>
> are available in the git repository at:
>
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 3fe2199833c47652a7e5dbf8b347d873820104b8:
>
>   hostmem: no need to check for host_memory_backend_mr_inited() in alloc() 
> (2018-11-27 19:36:22 +0100)
>
> 
> * lsi HBA reselection fix (George)
> * Small cleanups (Li Qiang)
> * bugfixes for vhost-user-bridge and hostmem (Marc-André)
> * single-thread TCG fix (me)
> * VMX migration blocker (me)
> * target/i386 fix for LOCK (Richard)
> * MAINTAINERS update (Philippe, Thomas)
>
> ---


This still has the problem with backends/hostmem-file.c that
means it doesn't build on the BSDs...

backends/hostmem-file.c: In function 'file_backend_memory_alloc':
backends/hostmem-file.c:61:5: error: 'path' undeclared (first use in
this function)
 path = object_get_canonical_path(OBJECT(backend));
 ^
backends/hostmem-file.c:61:5: note: each undeclared identifier is
reported only once for each function it appears in

(mismatch in #ifdef choice between declaration and use of variable)

thanks
-- PMM



Re: [Qemu-devel] [RFC 41/48] configure: add --enable-plugins

2018-11-27 Thread Emilio G. Cota
On Tue, Nov 27, 2018 at 15:43:52 +0300, Roman Bolshakov wrote:
> ld64 on macOS has similar -exported_symbols_list option. Here's the reference:
> 
>  -exported_symbols_list filename
>   The specified filename contains a list of global symbol names
>   that will remain as global symbols in the output file.  All other
>   global symbols will be treated as if they were marked as
>   __private_extern__ (aka visibility=hidden) and will not be global in
>   the output file. The symbol names listed in filename must be one per
>   line.  Leading and trailing white space are not part of the symbol
>   name.  Lines starting with # are ignored, as are lines with only white
>   space.  Some wildcards (similar to shell file matching) are supported.
>   The * matches zero or more characters.  The ?  matches one character.
>   [abc] matches one character which must be an 'a', 'b', or 'c'.
>   [a-z] matches any single lower case letter from 'a' to 'z'.
> 
> 
> I can try your branch if you add support of the linker flag or send required
> changes via GitHub.

Can you please try this branch? I added a commit with the appended.
  https://github.com/cota/qemu/tree/plugin-v2

You can inspect the symbols in the final binary with
`readelf --dyn-syms' or `nm -D'.

Thanks,

Emilio

---
diff --git a/configure b/configure
index fe9707d951..3dc9c9697b 100755
--- a/configure
+++ b/configure
@@ -5176,15 +5176,31 @@ int main(void)
 }
 EOF
 
+ld_dynamic_list="no"
 if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
   ld_dynamic_list="yes"
-else
-  if test "$plugins" = "yes" ; then
-error_exit \
-"Plugin support requires specifying a set of symbols that " \
-"are exported to plugins. Unfortunately your linker doesn't " \
-"support the flag (--dynamic-list) used for this purpose."
-  fi
+fi
+
+#
+# See if -exported_symbols_list is supported by the linker
+
+cat > $TMPTXT <> $config_host_mak
 LIBS="-ldl $LIBS"
-LDFLAGS="-Wl,--dynamic-list=\$(SRC_PATH)/qemu-plugins.symbols $LDFLAGS"
+if test "$ld_dynamic_list" = "yes" ; then
+   LDFLAGS="-Wl,--dynamic-list=\$(SRC_PATH)/qemu-plugins.symbols $LDFLAGS"
+elif test "$ld_exported_symbols_list" = "yes" ; then
+   ld64_symbols=qemu-plugins-ld64.symbols
+   echo "# Automatically generated by configure - do not modify" > 
$ld64_symbols
+   cat "$source_path/qemu-plugins.symbols" | grep qemu_ | sed 's/;//g' >> 
$ld64_symbols
+   LDFLAGS="-Wl,-exported_symbols_list,\$(BUILD_DIR)/$ld64_symbols 
$LDFLAGS"
+else
+   error_exit \
+   "If \$plugins=yes, either \$ld_dynamic_list or " \
+   "\$ld_exported_symbols_list should have been set to 'yes'."
+fi
 fi
 
 if test "$tcg_interpreter" = "yes"; then



Re: [Qemu-devel] [PATCH] qemu-img info lists bitmap directory entries

2018-11-27 Thread Eric Blake

On 11/27/18 6:41 AM, Andrey Shinkevich wrote:

The 'Format specific information' of qemu-img info command will show
the name, flags and granularity for every QCOW2 bitmap.

Signed-off-by: Andrey Shinkevich 
---
Dear colleagues,

With this patch, qemu-img info will display a name, flags and granularity
information for every bitmap in the directory section of a QCOW2 image.
That information appears in the 'Format specific information' section as
it's shown in the following example:

image: /vz/vmprivate/VM1/harddisk.hdd
file format: qcow2
virtual size: 64G (68719476736 bytes)
disk size: 3.0M
cluster_size: 1048576
Format specific information:
 compat: 1.1
 lazy refcounts: true
 refcount bits: 16
 dirty bitmaps:
 [0]:
 flags:
 [0]: in-use
 [1]: auto
 name: {257b5ea5-38c5-410e-a457-71c76f763c60}
 granularity: 65536
 [1]:
 flags:
 [0]: in-use
 [1]: auto
 name: back-up
 granularity: 65536
 corrupt: false


This example is worth including in the commit message proper (by putting 
it above the Signed-off-by and --- lines).


In addition to Vladimir's review (he's correct about using 4.0),


+++ b/block/qcow2-bitmap.c
@@ -1008,6 +1008,56 @@ fail:
  return false;
  }
  
+static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags)

+{
+Qcow2BitmapInfoFlagsList *list = NULL;
+Qcow2BitmapInfoFlagsList **plist = &list;
+
+if (flags & BME_FLAG_IN_USE) {
+Qcow2BitmapInfoFlagsList *entry = g_new0(Qcow2BitmapInfoFlagsList, 1);
+entry->value = QCOW2_BITMAP_INFO_FLAGS_IN_USE;
+*plist = entry;
+plist = &entry->next;
+}
+if (flags & BME_FLAG_AUTO) {
+Qcow2BitmapInfoFlagsList *entry = g_new0(Qcow2BitmapInfoFlagsList, 1);
+entry->value = QCOW2_BITMAP_INFO_FLAGS_AUTO;
+*plist = entry;
+}
+return list;
+}


This implementation means that qemu won't report bits that are set but 
which qemu doesn't recognize.  Is that a problem?  I wouldn't 
over-engineer it unless we have a use case, but maybe one way would be 
to have an optional integer field alongside the array of known flags, 
where the integer is present only if there are unrecognized flags 
present.  But by the time we encounter an image with more than the two 
flags we currently recognize, we may have also patched this code to 
recognize a new flag.



@@ -4279,6 +4287,8 @@ static ImageInfoSpecific 
*qcow2_get_specific_info(BlockDriverState *bs)
QCOW2_INCOMPAT_CORRUPT,
  .has_corrupt= true,
  .refcount_bits  = s->refcount_bits,
+.has_bitmaps= bitmaps ? true : false,


This looks awkward; I'd write it ' = !!bitmaps'.



+++ b/qapi/block-core.json
@@ -77,7 +77,8 @@
'*lazy-refcounts': 'bool',
'*corrupt': 'bool',
'refcount-bits': 'int',
-  '*encrypt': 'ImageInfoSpecificQCow2Encryption'
+  '*encrypt': 'ImageInfoSpecificQCow2Encryption',
+  '*bitmaps': ['Qcow2BitmapInfo']


Missing documentation on the new member, including a '(since 4.0)' tag.

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



Re: [Qemu-devel] [PATCH v1 1/1] riscv: virt: Cast the initrd start address to target bit length

2018-11-27 Thread Alexander Graf



On 27.11.18 23:28, Alistair Francis wrote:
> On Tue, Nov 27, 2018 at 2:24 PM Alistair Francis  wrote:
>>
>> On Tue, Nov 27, 2018 at 2:12 PM Alexander Graf  wrote:
>>>
>>>
>>>
>>> On 27.11.18 23:05, Alistair Francis wrote:
 On Mon, Nov 26, 2018 at 11:02 AM Palmer Dabbelt  wrote:
>
> On Wed, 21 Nov 2018 18:09:27 PST (-0800), alistai...@gmail.com wrote:
>> On Wed, Nov 21, 2018 at 5:58 PM Palmer Dabbelt  wrote:
>>>
>>> On Wed, 21 Nov 2018 14:34:44 PST (-0800), Alistair Francis wrote:
 Ensure that the calculate initrd offset points to a valid address for
 the architecture.

 Signed-off-by: Alistair Francis 
 Suggested-by: Alexander Graf 
 Reported-by: Alexander Graf 
 ---
  hw/riscv/virt.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

 diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
 index 2b38f89070..4467195fac 100644
 --- a/hw/riscv/virt.c
 +++ b/hw/riscv/virt.c
 @@ -85,7 +85,12 @@ static hwaddr load_initrd(const char *filename, 
 uint64_t mem_size,
   * halfway into RAM, and for boards with 256MB of RAM or more we 
 put
   * the initrd at 128MB.
   */
 -*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
 +/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
 +#if defined(TARGET_RISCV32)
 +*start = (uint32_t) (kernel_entry + MIN(mem_size / 2, 128ULL * 
 MiB));
 +#elif defined(TARGET_RISCV64)
 +*start = (uint64_t) (kernel_entry + MIN(mem_size / 2, 128 * MiB));
 +#endif

  size = load_ramdisk(filename, *start, mem_size - *start);
  if (size == -1) {
 --
 2.19.1
>>>
>>> Maybe I'm missing something, but wouldn't something like
>>>
>>> uint64_t start_unclobbered = kernel_entry + MIN(mem_size / 2, 
>>> 128ULL * MiB);
>>> assert(start_unclobbered == (hwaddr)start_unclobbered);
>>> *start = (hwaddr)start_unclobbered;
>>>
>>> work better?  That should actually check this all lines up, as opposed 
>>> to just
>>> silently truncating a bad address.
>>
>> The problem is that hwaddr is always 64-bit.
>>
>> Stupidly I forgot about target_ulong, which should work basically the
>> same as above. An assert() seems a little harsh though, Alex reported
>> problem was fixed with just a cast.
>
> OK, I must be misunderstanding the problem, then.  With the current code, 
> isn't
> it possible to end up causing start to overflow a 32-bit address?  This 
> would
> happen if kernel_entry is high, with IIUC is coming from the ELF to load 
> and is
> therefor user input.  I think that's worth some sort of assertion, as 
> it'll
> definitely blow up trying to enter the kernel (and possible before that,
> assuming there's no target memory where it overflows into).

 I don't have a setup to reproduce this unfortunately, but Alex
 reported that he saw start being excessively high (0x8800)
 when loading an initrd.
>>>
>>> Sorry for only jumping in so late.
>>>
>>> I didn't actually propose the cast as a solution. The problem must be
>>> sign extension of some variable in the mix. I didn't find out quickly
>>> which one it was, so I figured I'd leave it for someone else to debug :).
>>>
>>> The issue is very easy to reproduce: Build U-Boot for the virt machine
>>> for riscv32. Then run it with
>>>
>>>   $ qemu-system-riscv32 -M virt -kernel u-boot -nographic -initrd 
>>
>> Ah, cool I can reproduce it now.
>>
>> It happens in load_elf32() (which is actually glue(load_elf, SZ)).
>>
>> This line ends up sign extending the value:
>> *pentry = (uint64_t)(elf_sword)ehdr.e_entry;
>>
>> and we just continue it from there.
>>
>> So I think this diff is a much better solution:
>>
>> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
>> index e7f0716fb6..348ecc39d5 100644
>> --- a/hw/riscv/virt.c
>> +++ b/hw/riscv/virt.c
>> @@ -62,7 +62,7 @@ static const struct MemmapEntry {
>>  [VIRT_PCIE_ECAM] =   { 0x3000,0x1000 },
>>  };
>>
>> -static uint64_t load_kernel(const char *kernel_filename)
>> +static target_ulong load_kernel(const char *kernel_filename)
>>  {
>>  uint64_t kernel_entry, kernel_high;
>>
>>
>>
>> Alistair
>>
>>>
>>> You can find the initrd address with
>>>
>>>   U-Boot# fdt addr $fdtcontroladdr
>>>   U-Boot# fdt ls /chosen
>>>
>>> Then take a peek at that address:
>>>
>>>   U-Boot# md.b 
>>>
>>> and you will see that there is nothing there without this patch. The
>>> reason is that the binary was loaded to a negative address. Again,
>>> probably some misguided sign extension.
>>>
 It looks like the kernel entry address ends up being converted to
 0x8000 incorrectly instead of being a real overflow.
>>>

[Qemu-devel] [Bug 1805445] Re: QEMU arm virt machine was stopped by STMFD command while debug process

2018-11-27 Thread Igor
** Description changed:

  Hello, i have a big problem with QEMU arm virtual machine. So...
  I run QEMU machine with bare-metal ThreadX fullflash from Texet TM-333 phone  
(Spreadtrum platform)
  [CODE]qemu-system-arm -S -gdb tcp::1234,ipv4 -drive 
file=C:\cygwin64\home\flash.bin,if=mtd,format=raw -M palmetto-bmc -cpu arm926 
-m 64M[/CODE]
  I use palmetto-bmc platform because it have ARM926EJ-S core and support SPI 
Flash.
  Then, i attach to gdb qemu process from IDA and run code step-by-step.
- [IMG]https://pp.userapi.com/c847218/v847218546/13ec1c/iSIcre5-js4.jpg[/IMG]
+ 
  
  When the IDA run 00032534 STR R11, [R10] command
- [IMG]https://pp.userapi.com/c846416/v846416708/133f60/GQzxORvf4Tg.jpg[/IMG]
+ 
  
  instead of store R11 on R10 adress, it jump 000328DC STMFD SP!, {R0-R12,LR} 
instruction...
- [IMG]https://pp.userapi.com/c847218/v847218546/13ec26/32A0VcaJywg.jpg[/IMG]
- and virt machine not execute new instruction... 
+ 
+ and virt machine not execute new instruction...
  [IMG]https://pp.userapi.com/c850624/v850624111/528f3/N7FTpgloWVU.jpg[/IMG]
  
  and why i did not change flash from n25q256a to n25q032a11 in aspeed.c
  without rebuild qemu?

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

Title:
  QEMU arm virt machine was stopped by STMFD command while debug process

Status in QEMU:
  New

Bug description:
  Hello, i have a big problem with QEMU arm virtual machine. So...
  I run QEMU machine with bare-metal ThreadX fullflash from Texet TM-333 phone  
(Spreadtrum platform)
  [CODE]qemu-system-arm -S -gdb tcp::1234,ipv4 -drive 
file=C:\cygwin64\home\flash.bin,if=mtd,format=raw -M palmetto-bmc -cpu arm926 
-m 64M[/CODE]
  I use palmetto-bmc platform because it have ARM926EJ-S core and support SPI 
Flash.
  Then, i attach to gdb qemu process from IDA and run code step-by-step.

  
  When the IDA run 00032534 STR R11, [R10] command

  
  instead of store R11 on R10 adress, it jump 000328DC STMFD SP!, {R0-R12,LR} 
instruction...

  and virt machine not execute new instruction...
  [IMG]https://pp.userapi.com/c850624/v850624111/528f3/N7FTpgloWVU.jpg[/IMG]

  and why i did not change flash from n25q256a to n25q032a11 in aspeed.c
  without rebuild qemu?

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



Re: [Qemu-devel] [PATCH v1 1/1] riscv: virt: Cast the initrd start address to target bit length

2018-11-27 Thread Alistair Francis
On Tue, Nov 27, 2018 at 2:24 PM Alistair Francis  wrote:
>
> On Tue, Nov 27, 2018 at 2:12 PM Alexander Graf  wrote:
> >
> >
> >
> > On 27.11.18 23:05, Alistair Francis wrote:
> > > On Mon, Nov 26, 2018 at 11:02 AM Palmer Dabbelt  wrote:
> > >>
> > >> On Wed, 21 Nov 2018 18:09:27 PST (-0800), alistai...@gmail.com wrote:
> > >>> On Wed, Nov 21, 2018 at 5:58 PM Palmer Dabbelt  
> > >>> wrote:
> > 
> >  On Wed, 21 Nov 2018 14:34:44 PST (-0800), Alistair Francis wrote:
> > > Ensure that the calculate initrd offset points to a valid address for
> > > the architecture.
> > >
> > > Signed-off-by: Alistair Francis 
> > > Suggested-by: Alexander Graf 
> > > Reported-by: Alexander Graf 
> > > ---
> > >  hw/riscv/virt.c | 7 ++-
> > >  1 file changed, 6 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > index 2b38f89070..4467195fac 100644
> > > --- a/hw/riscv/virt.c
> > > +++ b/hw/riscv/virt.c
> > > @@ -85,7 +85,12 @@ static hwaddr load_initrd(const char *filename, 
> > > uint64_t mem_size,
> > >   * halfway into RAM, and for boards with 256MB of RAM or more we 
> > > put
> > >   * the initrd at 128MB.
> > >   */
> > > -*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
> > > +/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
> > > +#if defined(TARGET_RISCV32)
> > > +*start = (uint32_t) (kernel_entry + MIN(mem_size / 2, 128ULL * 
> > > MiB));
> > > +#elif defined(TARGET_RISCV64)
> > > +*start = (uint64_t) (kernel_entry + MIN(mem_size / 2, 128 * 
> > > MiB));
> > > +#endif
> > >
> > >  size = load_ramdisk(filename, *start, mem_size - *start);
> > >  if (size == -1) {
> > > --
> > > 2.19.1
> > 
> >  Maybe I'm missing something, but wouldn't something like
> > 
> >  uint64_t start_unclobbered = kernel_entry + MIN(mem_size / 2, 
> >  128ULL * MiB);
> >  assert(start_unclobbered == (hwaddr)start_unclobbered);
> >  *start = (hwaddr)start_unclobbered;
> > 
> >  work better?  That should actually check this all lines up, as opposed 
> >  to just
> >  silently truncating a bad address.
> > >>>
> > >>> The problem is that hwaddr is always 64-bit.
> > >>>
> > >>> Stupidly I forgot about target_ulong, which should work basically the
> > >>> same as above. An assert() seems a little harsh though, Alex reported
> > >>> problem was fixed with just a cast.
> > >>
> > >> OK, I must be misunderstanding the problem, then.  With the current 
> > >> code, isn't
> > >> it possible to end up causing start to overflow a 32-bit address?  This 
> > >> would
> > >> happen if kernel_entry is high, with IIUC is coming from the ELF to load 
> > >> and is
> > >> therefor user input.  I think that's worth some sort of assertion, as 
> > >> it'll
> > >> definitely blow up trying to enter the kernel (and possible before that,
> > >> assuming there's no target memory where it overflows into).
> > >
> > > I don't have a setup to reproduce this unfortunately, but Alex
> > > reported that he saw start being excessively high (0x8800)
> > > when loading an initrd.
> >
> > Sorry for only jumping in so late.
> >
> > I didn't actually propose the cast as a solution. The problem must be
> > sign extension of some variable in the mix. I didn't find out quickly
> > which one it was, so I figured I'd leave it for someone else to debug :).
> >
> > The issue is very easy to reproduce: Build U-Boot for the virt machine
> > for riscv32. Then run it with
> >
> >   $ qemu-system-riscv32 -M virt -kernel u-boot -nographic -initrd 
>
> Ah, cool I can reproduce it now.
>
> It happens in load_elf32() (which is actually glue(load_elf, SZ)).
>
> This line ends up sign extending the value:
> *pentry = (uint64_t)(elf_sword)ehdr.e_entry;
>
> and we just continue it from there.
>
> So I think this diff is a much better solution:
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index e7f0716fb6..348ecc39d5 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -62,7 +62,7 @@ static const struct MemmapEntry {
>  [VIRT_PCIE_ECAM] =   { 0x3000,0x1000 },
>  };
>
> -static uint64_t load_kernel(const char *kernel_filename)
> +static target_ulong load_kernel(const char *kernel_filename)
>  {
>  uint64_t kernel_entry, kernel_high;
>
>
>
> Alistair
>
> >
> > You can find the initrd address with
> >
> >   U-Boot# fdt addr $fdtcontroladdr
> >   U-Boot# fdt ls /chosen
> >
> > Then take a peek at that address:
> >
> >   U-Boot# md.b 
> >
> > and you will see that there is nothing there without this patch. The
> > reason is that the binary was loaded to a negative address. Again,
> > probably some misguided sign extension.
> >
> > > It looks like the kernel entry address ends up being converted to
> > > 0x8000 incorrectly instead of being a real

Re: [Qemu-devel] [PATCH v1 1/1] riscv: virt: Cast the initrd start address to target bit length

2018-11-27 Thread Alistair Francis
On Tue, Nov 27, 2018 at 2:12 PM Alexander Graf  wrote:
>
>
>
> On 27.11.18 23:05, Alistair Francis wrote:
> > On Mon, Nov 26, 2018 at 11:02 AM Palmer Dabbelt  wrote:
> >>
> >> On Wed, 21 Nov 2018 18:09:27 PST (-0800), alistai...@gmail.com wrote:
> >>> On Wed, Nov 21, 2018 at 5:58 PM Palmer Dabbelt  wrote:
> 
>  On Wed, 21 Nov 2018 14:34:44 PST (-0800), Alistair Francis wrote:
> > Ensure that the calculate initrd offset points to a valid address for
> > the architecture.
> >
> > Signed-off-by: Alistair Francis 
> > Suggested-by: Alexander Graf 
> > Reported-by: Alexander Graf 
> > ---
> >  hw/riscv/virt.c | 7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 2b38f89070..4467195fac 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -85,7 +85,12 @@ static hwaddr load_initrd(const char *filename, 
> > uint64_t mem_size,
> >   * halfway into RAM, and for boards with 256MB of RAM or more we 
> > put
> >   * the initrd at 128MB.
> >   */
> > -*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
> > +/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
> > +#if defined(TARGET_RISCV32)
> > +*start = (uint32_t) (kernel_entry + MIN(mem_size / 2, 128ULL * 
> > MiB));
> > +#elif defined(TARGET_RISCV64)
> > +*start = (uint64_t) (kernel_entry + MIN(mem_size / 2, 128 * MiB));
> > +#endif
> >
> >  size = load_ramdisk(filename, *start, mem_size - *start);
> >  if (size == -1) {
> > --
> > 2.19.1
> 
>  Maybe I'm missing something, but wouldn't something like
> 
>  uint64_t start_unclobbered = kernel_entry + MIN(mem_size / 2, 128ULL 
>  * MiB);
>  assert(start_unclobbered == (hwaddr)start_unclobbered);
>  *start = (hwaddr)start_unclobbered;
> 
>  work better?  That should actually check this all lines up, as opposed 
>  to just
>  silently truncating a bad address.
> >>>
> >>> The problem is that hwaddr is always 64-bit.
> >>>
> >>> Stupidly I forgot about target_ulong, which should work basically the
> >>> same as above. An assert() seems a little harsh though, Alex reported
> >>> problem was fixed with just a cast.
> >>
> >> OK, I must be misunderstanding the problem, then.  With the current code, 
> >> isn't
> >> it possible to end up causing start to overflow a 32-bit address?  This 
> >> would
> >> happen if kernel_entry is high, with IIUC is coming from the ELF to load 
> >> and is
> >> therefor user input.  I think that's worth some sort of assertion, as it'll
> >> definitely blow up trying to enter the kernel (and possible before that,
> >> assuming there's no target memory where it overflows into).
> >
> > I don't have a setup to reproduce this unfortunately, but Alex
> > reported that he saw start being excessively high (0x8800)
> > when loading an initrd.
>
> Sorry for only jumping in so late.
>
> I didn't actually propose the cast as a solution. The problem must be
> sign extension of some variable in the mix. I didn't find out quickly
> which one it was, so I figured I'd leave it for someone else to debug :).
>
> The issue is very easy to reproduce: Build U-Boot for the virt machine
> for riscv32. Then run it with
>
>   $ qemu-system-riscv32 -M virt -kernel u-boot -nographic -initrd 

Ah, cool I can reproduce it now.

It happens in load_elf32() (which is actually glue(load_elf, SZ)).

This line ends up sign extending the value:
*pentry = (uint64_t)(elf_sword)ehdr.e_entry;

and we just continue it from there.

So I think this diff is a much better solution:

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e7f0716fb6..348ecc39d5 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -62,7 +62,7 @@ static const struct MemmapEntry {
 [VIRT_PCIE_ECAM] =   { 0x3000,0x1000 },
 };

-static uint64_t load_kernel(const char *kernel_filename)
+static target_ulong load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;



Alistair

>
> You can find the initrd address with
>
>   U-Boot# fdt addr $fdtcontroladdr
>   U-Boot# fdt ls /chosen
>
> Then take a peek at that address:
>
>   U-Boot# md.b 
>
> and you will see that there is nothing there without this patch. The
> reason is that the binary was loaded to a negative address. Again,
> probably some misguided sign extension.
>
> > It looks like the kernel entry address ends up being converted to
> > 0x8000 incorrectly instead of being a real overflow.
>
> Yeah, so we seem to cast from int32_t to int64_t somewhere. Can you spot
> where exactly? That's where the bug is :).
>
>
> Alex



Re: [Qemu-devel] [PATCH v1 1/1] riscv: virt: Cast the initrd start address to target bit length

2018-11-27 Thread Alexander Graf



On 27.11.18 23:05, Alistair Francis wrote:
> On Mon, Nov 26, 2018 at 11:02 AM Palmer Dabbelt  wrote:
>>
>> On Wed, 21 Nov 2018 18:09:27 PST (-0800), alistai...@gmail.com wrote:
>>> On Wed, Nov 21, 2018 at 5:58 PM Palmer Dabbelt  wrote:

 On Wed, 21 Nov 2018 14:34:44 PST (-0800), Alistair Francis wrote:
> Ensure that the calculate initrd offset points to a valid address for
> the architecture.
>
> Signed-off-by: Alistair Francis 
> Suggested-by: Alexander Graf 
> Reported-by: Alexander Graf 
> ---
>  hw/riscv/virt.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 2b38f89070..4467195fac 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -85,7 +85,12 @@ static hwaddr load_initrd(const char *filename, 
> uint64_t mem_size,
>   * halfway into RAM, and for boards with 256MB of RAM or more we put
>   * the initrd at 128MB.
>   */
> -*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
> +/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
> +#if defined(TARGET_RISCV32)
> +*start = (uint32_t) (kernel_entry + MIN(mem_size / 2, 128ULL * MiB));
> +#elif defined(TARGET_RISCV64)
> +*start = (uint64_t) (kernel_entry + MIN(mem_size / 2, 128 * MiB));
> +#endif
>
>  size = load_ramdisk(filename, *start, mem_size - *start);
>  if (size == -1) {
> --
> 2.19.1

 Maybe I'm missing something, but wouldn't something like

 uint64_t start_unclobbered = kernel_entry + MIN(mem_size / 2, 128ULL * 
 MiB);
 assert(start_unclobbered == (hwaddr)start_unclobbered);
 *start = (hwaddr)start_unclobbered;

 work better?  That should actually check this all lines up, as opposed to 
 just
 silently truncating a bad address.
>>>
>>> The problem is that hwaddr is always 64-bit.
>>>
>>> Stupidly I forgot about target_ulong, which should work basically the
>>> same as above. An assert() seems a little harsh though, Alex reported
>>> problem was fixed with just a cast.
>>
>> OK, I must be misunderstanding the problem, then.  With the current code, 
>> isn't
>> it possible to end up causing start to overflow a 32-bit address?  This would
>> happen if kernel_entry is high, with IIUC is coming from the ELF to load and 
>> is
>> therefor user input.  I think that's worth some sort of assertion, as it'll
>> definitely blow up trying to enter the kernel (and possible before that,
>> assuming there's no target memory where it overflows into).
> 
> I don't have a setup to reproduce this unfortunately, but Alex
> reported that he saw start being excessively high (0x8800)
> when loading an initrd.

Sorry for only jumping in so late.

I didn't actually propose the cast as a solution. The problem must be
sign extension of some variable in the mix. I didn't find out quickly
which one it was, so I figured I'd leave it for someone else to debug :).

The issue is very easy to reproduce: Build U-Boot for the virt machine
for riscv32. Then run it with

  $ qemu-system-riscv32 -M virt -kernel u-boot -nographic -initrd 

You can find the initrd address with

  U-Boot# fdt addr $fdtcontroladdr
  U-Boot# fdt ls /chosen

Then take a peek at that address:

  U-Boot# md.b 

and you will see that there is nothing there without this patch. The
reason is that the binary was loaded to a negative address. Again,
probably some misguided sign extension.

> It looks like the kernel entry address ends up being converted to
> 0x8000 incorrectly instead of being a real overflow.

Yeah, so we seem to cast from int32_t to int64_t somewhere. Can you spot
where exactly? That's where the bug is :).


Alex



Re: [Qemu-devel] [PATCH v1 1/1] riscv: virt: Cast the initrd start address to target bit length

2018-11-27 Thread Alistair Francis
On Mon, Nov 26, 2018 at 11:02 AM Palmer Dabbelt  wrote:
>
> On Wed, 21 Nov 2018 18:09:27 PST (-0800), alistai...@gmail.com wrote:
> > On Wed, Nov 21, 2018 at 5:58 PM Palmer Dabbelt  wrote:
> >>
> >> On Wed, 21 Nov 2018 14:34:44 PST (-0800), Alistair Francis wrote:
> >> > Ensure that the calculate initrd offset points to a valid address for
> >> > the architecture.
> >> >
> >> > Signed-off-by: Alistair Francis 
> >> > Suggested-by: Alexander Graf 
> >> > Reported-by: Alexander Graf 
> >> > ---
> >> >  hw/riscv/virt.c | 7 ++-
> >> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> >> > index 2b38f89070..4467195fac 100644
> >> > --- a/hw/riscv/virt.c
> >> > +++ b/hw/riscv/virt.c
> >> > @@ -85,7 +85,12 @@ static hwaddr load_initrd(const char *filename, 
> >> > uint64_t mem_size,
> >> >   * halfway into RAM, and for boards with 256MB of RAM or more we put
> >> >   * the initrd at 128MB.
> >> >   */
> >> > -*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
> >> > +/* As hwaddr is a 64-bit number we need to cast it for 32-bit */
> >> > +#if defined(TARGET_RISCV32)
> >> > +*start = (uint32_t) (kernel_entry + MIN(mem_size / 2, 128ULL * 
> >> > MiB));
> >> > +#elif defined(TARGET_RISCV64)
> >> > +*start = (uint64_t) (kernel_entry + MIN(mem_size / 2, 128 * MiB));
> >> > +#endif
> >> >
> >> >  size = load_ramdisk(filename, *start, mem_size - *start);
> >> >  if (size == -1) {
> >> > --
> >> > 2.19.1
> >>
> >> Maybe I'm missing something, but wouldn't something like
> >>
> >> uint64_t start_unclobbered = kernel_entry + MIN(mem_size / 2, 128ULL * 
> >> MiB);
> >> assert(start_unclobbered == (hwaddr)start_unclobbered);
> >> *start = (hwaddr)start_unclobbered;
> >>
> >> work better?  That should actually check this all lines up, as opposed to 
> >> just
> >> silently truncating a bad address.
> >
> > The problem is that hwaddr is always 64-bit.
> >
> > Stupidly I forgot about target_ulong, which should work basically the
> > same as above. An assert() seems a little harsh though, Alex reported
> > problem was fixed with just a cast.
>
> OK, I must be misunderstanding the problem, then.  With the current code, 
> isn't
> it possible to end up causing start to overflow a 32-bit address?  This would
> happen if kernel_entry is high, with IIUC is coming from the ELF to load and 
> is
> therefor user input.  I think that's worth some sort of assertion, as it'll
> definitely blow up trying to enter the kernel (and possible before that,
> assuming there's no target memory where it overflows into).

I don't have a setup to reproduce this unfortunately, but Alex
reported that he saw start being excessively high (0x8800)
when loading an initrd.

It looks like the kernel entry address ends up being converted to
0x8000 incorrectly instead of being a real overflow.

Alistair

>
> This won't happen with the default Linux setup, but could happen if users are
> trying to do something weird.



[Qemu-devel] [Bug 1805445] Re: QEMU arm virt machine was stopped by STMFD command while debug process

2018-11-27 Thread Igor
Maybe this is correct for palmetto-board, but qemu user should be able
to debug any basic arm instructions for generic arm board with general
purpose SPI, I2C etc... My SPI Flash has 4 Mb, and RAM adress may start
from 0x40, This is impossible for 256 Mb Flash. It would be great,
if qemu can build general arm device with var ram adr, cpu core and
block dev.

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

Title:
  QEMU arm virt machine was stopped by STMFD command while debug process

Status in QEMU:
  New

Bug description:
  Hello, i have a big problem with QEMU arm virtual machine. So...
  I run QEMU machine with bare-metal ThreadX fullflash from Texet TM-333 phone  
(Spreadtrum platform)
  [CODE]qemu-system-arm -S -gdb tcp::1234,ipv4 -drive 
file=C:\cygwin64\home\flash.bin,if=mtd,format=raw -M palmetto-bmc -cpu arm926 
-m 64M[/CODE]
  I use palmetto-bmc platform because it have ARM926EJ-S core and support SPI 
Flash.
  Then, i attach to gdb qemu process from IDA and run code step-by-step.
  [IMG]https://pp.userapi.com/c847218/v847218546/13ec1c/iSIcre5-js4.jpg[/IMG]

  When the IDA run 00032534 STR R11, [R10] command
  [IMG]https://pp.userapi.com/c846416/v846416708/133f60/GQzxORvf4Tg.jpg[/IMG]

  instead of store R11 on R10 adress, it jump 000328DC STMFD SP!, {R0-R12,LR} 
instruction...
  [IMG]https://pp.userapi.com/c847218/v847218546/13ec26/32A0VcaJywg.jpg[/IMG]
  and virt machine not execute new instruction... 
  [IMG]https://pp.userapi.com/c850624/v850624111/528f3/N7FTpgloWVU.jpg[/IMG]

  and why i did not change flash from n25q256a to n25q032a11 in aspeed.c
  without rebuild qemu?

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



Re: [Qemu-devel] [RFC v2 00/24] Add RISC-V TCG backend support

2018-11-27 Thread Alistair Francis
On Tue, Nov 27, 2018 at 1:06 PM Alistair Francis
 wrote:

It looks like the cover was lost, here it is:

This patch set adds RISC-V backend support to QEMU. This is based on
Michael Clark's original work with some patches ontop.

This has been slightly tested and can run other architecture softmmu
code for a number of instructions but eventually QEMU will do something
it shouldn't.

I haven't tested linux user support at all yet. I think Michael had that
working reliably though and hopefully my changes haven't broken it. I'll
test both a lot more before I send a full patchset.

There are still some todos in the code (there is missing instructions
and byte swapping) and I'll have to rebase this ontop of Richard's TCG
work. In the meantime I wanted to try and keep the ball rolling though.

There are two WIP patches at the end of the series that I am not sure
about, so they have been kept seperate from the series for the time
being.

This branch can be found here:
https://github.com/alistair23/qemu/tree/mainline/alistair/tcg-backend-upstream.next

The working version with Michael's orignal patch and work ontop can be
found here:
https://github.com/alistair23/qemu/tree/mainline/alistair/tcg-backend.next

RFC v2:
 - A large number of changes based on Richard's feedback


>
>
> Alistair Francis (24):
>   elf.h: Add the RISCV ELF magic numbers
>   linux-user: Add host dependency for RISC-V 32-bit
>   linux-user: Add host dependency for RISC-V 64-bit
>   exec: Add RISC-V GCC poison macro
>   riscv: Add the tcg-target header file
>   riscv: Add the tcg target registers
>   riscv: tcg-target: Add support for the constraints
>   riscv: tcg-target: Add the immediate encoders
>   riscv: tcg-target: Add the instruction emitters
>   riscv: tcg-target: Add the relocation functions
>   riscv: tcg-target: Add the mov and movi instruction
>   riscv: tcg-target: Add the extract instructions
>   riscv: tcg-target: Add the out load and store instructions
>   riscv: tcg-target: Add branch and jump instructions
>   riscv: tcg-target: Add slowpath load and store instructions
>   riscv: tcg-target: Add direct load and store instructions
>   riscv: tcg-target: Add the out op decoder
>   riscv: tcg-target: Add the prologue generation and register the JIT
>   riscv: tcg-target: Add the target init code
>   tcg: Add RISC-V cpu signal handler
>   dias: Add RISC-V support
>   configure: Add support for building RISC-V host
>   WIP: Add missing instructions
>   WIP: Try to patch longer branches
>
>  accel/tcg/user-exec.c |   75 ++
>  configure |   12 +-
>  disas.c   |   10 +-
>  include/elf.h |   55 +
>  include/exec/poison.h |1 +
>  linux-user/host/riscv32/hostdep.h |   11 +
>  linux-user/host/riscv64/hostdep.h |   11 +
>  tcg/riscv/tcg-target.h|  173 +++
>  tcg/riscv/tcg-target.inc.c| 1890 +
>  9 files changed, 2234 insertions(+), 4 deletions(-)
>  create mode 100644 linux-user/host/riscv32/hostdep.h
>  create mode 100644 linux-user/host/riscv64/hostdep.h
>  create mode 100644 tcg/riscv/tcg-target.h
>  create mode 100644 tcg/riscv/tcg-target.inc.c
>
> --
> 2.19.1
>



[Qemu-devel] [RFC v2 19/24] riscv: tcg-target: Add the target init code

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 51961ade81..13756f6d0d 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1683,6 +1683,37 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
 }
 
+static void tcg_target_init(TCGContext *s)
+{
+tcg_target_available_regs[TCG_TYPE_I32] = 0x;
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_target_available_regs[TCG_TYPE_I64] = 0x;
+}
+
+tcg_target_call_clobber_regs = -1u;
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S10);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S11);
+
+s->reserved_regs = 0;
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




[Qemu-devel] [RFC v2 16/24] riscv: tcg-target: Add direct load and store instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 162 -
 1 file changed, 158 insertions(+), 4 deletions(-)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 4f3a6de52c..e3b5f48848 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -816,14 +816,10 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
: offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
 int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
-int addend_offset = (offsetof(CPUTLBEntry, addend)) -
-(is_load ? offsetof(CPUTLBEntry, addr_read)
- : offsetof(CPUTLBEntry, addr_write));
 RISCVInsn load_cmp_op = (TARGET_LONG_BITS == 64 ? OPC_LD :
  TCG_TARGET_REG_BITS == 64 ? OPC_LWU : OPC_LW);
 RISCVInsn load_add_op = TCG_TARGET_REG_BITS == 64 ? OPC_LD : OPC_LW;
 TCGReg base = TCG_AREG0;
-TCGReg cmpr;
 
 /* We don't support oversize guests */
 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
@@ -991,6 +987,164 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 }
 #endif /* CONFIG_SOFTMMU */
 
+static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
+   TCGReg base, TCGMemOp opc, bool is_64)
+{
+const TCGMemOp bswap = opc & MO_BSWAP;
+
+/* We don't yet handle byteswapping, assert */
+g_assert(!bswap);
+
+switch (opc & (MO_SSIZE)) {
+case MO_UB:
+tcg_out_opc_imm(s, OPC_LBU, lo, base, 0);
+break;
+case MO_SB:
+tcg_out_opc_imm(s, OPC_LB, lo, base, 0);
+break;
+case MO_UW:
+tcg_out_opc_imm(s, OPC_LHU, lo, base, 0);
+break;
+case MO_SW:
+tcg_out_opc_imm(s, OPC_LH, lo, base, 0);
+break;
+case MO_UL:
+if (TCG_TARGET_REG_BITS == 64 && is_64) {
+tcg_out_opc_imm(s, OPC_LWU, lo, base, 0);
+break;
+}
+/* FALLTHRU */
+case MO_SL:
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+break;
+case MO_Q:
+/* Prefer to load from offset 0 first, but allow for overlap.  */
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_out_opc_imm(s, OPC_LD, lo, base, 0);
+} else if (lo != base) {
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+tcg_out_opc_imm(s, OPC_LW, hi, base, 4);
+} else {
+tcg_out_opc_imm(s, OPC_LW, hi, base, 4);
+tcg_out_opc_imm(s, OPC_LW, lo, base, 0);
+}
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
+{
+TCGReg addr_regl, addr_regh __attribute__((unused));
+TCGReg data_regl, data_regh;
+TCGMemOpIdx oi;
+TCGMemOp opc;
+#if defined(CONFIG_SOFTMMU)
+tcg_insn_unit *label_ptr[1];
+#endif
+TCGReg base = TCG_REG_TMP0;
+
+data_regl = *args++;
+data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
+addr_regl = *args++;
+addr_regh = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
+oi = *args++;
+opc = get_memop(oi);
+
+#if defined(CONFIG_SOFTMMU)
+tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
+tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
+add_qemu_ldst_label(s, 1, oi,
+(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+data_regl, data_regh, addr_regl, addr_regh,
+s->code_ptr, label_ptr);
+#else
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, base, addr_regl);
+addr_regl = base;
+}
+
+if (guest_base == 0) {
+tcg_out_opc_reg(s, OPC_ADD, base, addr_regl, TCG_REG_ZERO);
+} else {
+tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+}
+tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
+#endif
+}
+
+static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
+   TCGReg base, TCGMemOp opc)
+{
+const TCGMemOp bswap = opc & MO_BSWAP;
+
+/* We don't yet handle byteswapping, assert */
+g_assert(!bswap);
+
+switch (opc & (MO_SSIZE)) {
+case MO_8:
+tcg_out_opc_store(s, OPC_SB, base, lo, 0);
+break;
+case MO_16:
+tcg_out_opc_store(s, OPC_SH, base, lo, 0);
+break;
+case MO_32:
+tcg_out_opc_store(s, OPC_SW, base, lo, 0);
+break;
+case MO_64:
+if (TCG_TARGET_REG_BITS == 64) {
+tcg_out_opc_store(s, OPC_SD, base, lo, 0);
+} else {
+tcg_out_opc_store(s, OPC_SW, base, lo, 0);
+tcg_out_opc_store(s, OPC_SW, base, hi, 4);
+}
+break;
+default

[Qemu-devel] [RFC v2 24/24] WIP: Try to patch longer branches

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.inc.c | 44 +++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index b8e9c0e126..cf1680935a 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -418,10 +418,37 @@ static void reloc_call(tcg_insn_unit *code_ptr, 
tcg_insn_unit *target)
 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 intptr_t value, intptr_t addend)
 {
+uint32_t insn = *code_ptr;
+intptr_t diff;
+bool short_jmp;
+
 tcg_debug_assert(addend == 0);
+
 switch (type) {
 case R_RISCV_BRANCH:
-reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
+diff = value - (uintptr_t)code_ptr;
+#if TCG_TARGET_REG_BITS == 64
+short_jmp = diff == sextract64(diff, 0, 12);
+#else
+short_jmp = diff == sextract32(diff, 0, 12);
+#endif
+if (short_jmp) {
+reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
+} else {
+/* Invert the condition */
+insn = insn ^ (1 << 12);
+/* Clear the offset */
+insn &= 0xFFF;
+/* Set the offset to the PC + 8 */
+insn |= ((unsigned int)(code_ptr + 8)) << 12;
+
+/* Move forward */
+code_ptr++;
+insn = *code_ptr;
+
+/* Overwrite the NOP with jal x0,value */
+insn = encode_uj(OPC_JAL, TCG_REG_ZERO, value);
+}
 break;
 case R_RISCV_JAL:
 reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
@@ -677,16 +704,27 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, 
TCGReg arg1,
TCGReg arg2, TCGLabel *l)
 {
 RISCVInsn op = tcg_brcond_to_riscv[cond].op;
+intptr_t diff;
 bool swap = tcg_brcond_to_riscv[cond].swap;
+bool short_jmp;
+
+tcg_debug_assert(op != 0);
 
 tcg_out_opc_branch(s, op, swap ? arg2 : arg1, swap ? arg1 : arg2, 0);
 
-tcg_debug_assert(op != 0);
+diff = l->u.value_ptr - (uintptr_t)s->code_gen_ptr;
+#if TCG_TARGET_REG_BITS == 64
+short_jmp = diff == sextract64(diff, 0, 12);
+#else
+short_jmp = diff == sextract32(diff, 0, 12);
+#endif
 
-if (l->has_value) {
+if (l->has_value && short_jmp) {
 reloc_sbimm12(s->code_ptr - 1, l->u.value_ptr);
 } else {
 tcg_out_reloc(s, s->code_ptr - 1, R_RISCV_BRANCH, l, 0);
+/* NOP to allow patching later */
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
 }
 }
 
-- 
2.19.1




[Qemu-devel] [RFC v2 22/24] configure: Add support for building RISC-V host

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 configure | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 0a3c6a72c3..fb52954368 100755
--- a/configure
+++ b/configure
@@ -709,6 +709,12 @@ elif check_define __s390__ ; then
   else
 cpu="s390"
   fi
+elif check_define __riscv ; then
+  if check_define _LP64 ; then
+cpu="riscv64"
+  elif check_define _ILP32 ; then
+cpu="riscv32"
+  fi
 elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
@@ -721,7 +727,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390|s390x|sparc64|x32)
+  ppc|ppc64|s390|s390x|sparc64|x32|riscv32|riscv64)
 cpu="$cpu"
 supported_cpu="yes"
 eval "cross_cc_${cpu}=\$host_cc"
@@ -6900,6 +6906,8 @@ elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES"
 elif test "$ARCH" = "ppc64" ; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/ppc $QEMU_INCLUDES"
+elif test "$ARCH" = "riscv32" -o "$ARCH" = "riscv64" ; then
+  QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/riscv $QEMU_INCLUDES"
 else
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES"
 fi
@@ -7397,7 +7405,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
 disas_config "PPC"
   ;;
-  riscv)
+  riscv*)
 disas_config "RISCV"
   ;;
   s390*)
-- 
2.19.1




[Qemu-devel] [RFC v2 15/24] riscv: tcg-target: Add slowpath load and store instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 244 +
 1 file changed, 244 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 97831bfb9d..4f3a6de52c 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -747,6 +747,250 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit 
*arg)
 tcg_out_call_int(s, arg, false);
 }
 
+static void tcg_out_mb(TCGContext *s, TCGArg a0)
+{
+static const RISCVInsn fence[] = {
+[0 ... TCG_MO_ALL] = OPC_FENCE_RW_RW,
+[TCG_MO_LD_LD] = OPC_FENCE_R_R,
+[TCG_MO_ST_LD] = OPC_FENCE_W_R,
+[TCG_MO_LD_ST] = OPC_FENCE_R_W,
+[TCG_MO_ST_ST] = OPC_FENCE_W_W,
+};
+tcg_out32(s, fence[a0 & TCG_MO_ALL]);
+}
+
+/*
+ * Load/store and TLB
+ */
+
+#if defined(CONFIG_SOFTMMU)
+#include "tcg-ldst.inc.c"
+
+/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ * TCGMemOpIdx oi, uintptr_t ra)
+ */
+static void * const qemu_ld_helpers[16] = {
+[MO_UB]   = helper_ret_ldub_mmu,
+[MO_SB]   = helper_ret_ldsb_mmu,
+[MO_LEUW] = helper_le_lduw_mmu,
+[MO_LESW] = helper_le_ldsw_mmu,
+[MO_LEUL] = helper_le_ldul_mmu,
+#if TCG_TARGET_REG_BITS == 64
+[MO_LESL] = helper_le_ldsl_mmu,
+#endif
+[MO_LEQ]  = helper_le_ldq_mmu,
+[MO_BEUW] = helper_be_lduw_mmu,
+[MO_BESW] = helper_be_ldsw_mmu,
+[MO_BEUL] = helper_be_ldul_mmu,
+#if TCG_TARGET_REG_BITS == 64
+[MO_BESL] = helper_be_ldsl_mmu,
+#endif
+[MO_BEQ]  = helper_be_ldq_mmu,
+};
+
+/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ * uintxx_t val, TCGMemOpIdx oi,
+ * uintptr_t ra)
+ */
+static void * const qemu_st_helpers[16] = {
+[MO_UB]   = helper_ret_stb_mmu,
+[MO_LEUW] = helper_le_stw_mmu,
+[MO_LEUL] = helper_le_stl_mmu,
+[MO_LEQ]  = helper_le_stq_mmu,
+[MO_BEUW] = helper_be_stw_mmu,
+[MO_BEUL] = helper_be_stl_mmu,
+[MO_BEQ]  = helper_be_stq_mmu,
+};
+
+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
+ TCGReg addrh, TCGMemOpIdx oi,
+ tcg_insn_unit **label_ptr, bool is_load)
+{
+TCGMemOp opc = get_memop(oi);
+unsigned s_bits = opc & MO_SIZE;
+unsigned a_bits = get_alignment_bits(opc);
+target_ulong mask;
+int mem_index = get_mmuidx(oi);
+int cmp_off
+= (is_load
+   ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
+   : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
+int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
+int addend_offset = (offsetof(CPUTLBEntry, addend)) -
+(is_load ? offsetof(CPUTLBEntry, addr_read)
+ : offsetof(CPUTLBEntry, addr_write));
+RISCVInsn load_cmp_op = (TARGET_LONG_BITS == 64 ? OPC_LD :
+ TCG_TARGET_REG_BITS == 64 ? OPC_LWU : OPC_LW);
+RISCVInsn load_add_op = TCG_TARGET_REG_BITS == 64 ? OPC_LD : OPC_LW;
+TCGReg base = TCG_AREG0;
+TCGReg cmpr;
+
+/* We don't support oversize guests */
+if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
+g_assert_not_reached();
+}
+
+/* We don't support unaligned accesses. */
+if (a_bits < s_bits) {
+a_bits = s_bits;
+}
+mask = (target_ulong)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+
+
+/* Compensate for very large offsets.  */
+if (add_off >= 0x1000) {
+int adj;
+base = TCG_REG_TMP2;
+if (cmp_off <= 2 * 0xfff) {
+adj = 0xfff;
+tcg_out_opc_imm(s, OPC_ADDI, base, TCG_AREG0, adj);
+} else {
+adj = cmp_off - sextract32(cmp_off, 0, 12);
+tcg_debug_assert(add_off - adj >= -0x1000
+ && add_off - adj < 0x1000);
+
+tcg_out_opc_upper(s, OPC_LUI, base, adj);
+tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_AREG0);
+}
+add_off -= adj;
+cmp_off -= adj;
+}
+
+/* Extract the page index.  */
+if (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS < 12) {
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, addrl,
+TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP0, TCG_REG_TMP0,
+MAKE_64BIT_MASK(CPU_TLB_ENTRY_BITS, CPU_TLB_BITS));
+} else {
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, addrl, TARGET_PAGE_BITS);
+tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP0, TCG_REG_TMP0,
+MAKE_64BIT_MASK(0, CPU_TLB_BITS));
+tcg_out_opc_imm(s, OPC_SLLI, TCG_REG_TMP0, TCG_REG_TMP0,
+CPU_TLB_ENTRY_BITS);
+}
+
+/* Add that to the base address to index the tlb.  */
+tcg_out_opc_reg(s

[Qemu-devel] [RFC v2 11/24] riscv: tcg-target: Add the mov and movi instruction

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 78 ++
 1 file changed, 78 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 9c48679f11..e5a07b146f 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -434,6 +434,84 @@ static void patch_reloc(tcg_insn_unit *code_ptr, int type,
 }
 }
 
+/*
+ * TCG intrinsics
+ */
+
+static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+{
+if (ret == arg) {
+return;
+}
+switch (type) {
+case TCG_TYPE_I32:
+case TCG_TYPE_I64:
+tcg_out_opc_imm(s, OPC_ADDI, ret, arg, 0);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
+ tcg_target_long val)
+{
+#if TCG_TARGET_REG_BITS == 64
+tcg_target_long lo = sextract64(val, 0, 12);
+#else
+tcg_target_long lo = sextract32(val, 0, 12);
+#endif
+tcg_target_long hi = val - lo;
+int shift;
+tcg_target_long tmp;
+
+RISCVInsn add32_op = TCG_TARGET_REG_BITS == 64 ? OPC_ADDIW : OPC_ADDI;
+
+#if TCG_TARGET_REG_BITS == 64
+ptrdiff_t offset = tcg_pcrel_diff(s, (void *)val);
+#endif
+
+if (TCG_TARGET_REG_BITS == 32 || val == (int32_t)val) {
+tcg_out_opc_upper(s, OPC_LUI, rd, hi);
+if (lo != 0) {
+tcg_out_opc_imm(s, add32_op, rd, rd, lo);
+}
+
+return;
+}
+
+/* We can only be here if TCG_TARGET_REG_BITS != 32 */
+if (offset == sextract64(offset, 1, 31) << 1) {
+tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
+tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
+reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val);
+return;
+}
+
+shift = ctz64(val);
+tmp = val >> shift;
+
+if (tmp == sextract64(tmp, 0, 12)) {
+tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, 1);
+tcg_out_opc_imm(s, OPC_SLLI, rd, rd, ctz64(val));
+} else if (!(val >> 31 == 0 || val >> 31 == -1)) {
+shift = ctz64(hi);
+hi >>= shift;
+tcg_out_movi(s, type, rd, hi);
+tcg_out_opc_imm(s, OPC_SLLI, rd, rd, shift);
+if (lo != 0) {
+tcg_out_opc_imm(s, OPC_ADDI, rd, rd, lo);
+}
+} else {
+if (hi != 0) {
+tcg_out_opc_upper(s, OPC_LUI, rd, hi);
+}
+if (lo != 0) {
+tcg_out_opc_imm(s, add32_op, rd, hi == 0 ? TCG_REG_ZERO : rd, lo);
+}
+}
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




[Qemu-devel] [RFC v2 18/24] riscv: tcg-target: Add the prologue generation and register the JIT

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 111 +
 1 file changed, 111 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index d5fd7ca854..51961ade81 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1617,6 +1617,72 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 }
 }
 
+static const int tcg_target_callee_save_regs[] = {
+TCG_REG_S0,   /* used for the global env (TCG_AREG0) */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+TCG_REG_RA,   /* should be last for ABI compliance */
+};
+
+/* Stack frame parameters.  */
+#define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
+#define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
+#define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
+#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
+ + TCG_TARGET_STACK_ALIGN - 1) \
+& -TCG_TARGET_STACK_ALIGN)
+#define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
+
+/* We're expecting to be able to use an immediate for frame allocation.  */
+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff);
+
+/* Generate global QEMU prologue and epilogue code */
+static void tcg_target_qemu_prologue(TCGContext *s)
+{
+int i;
+
+tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
+
+/* TB prologue */
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+#if !defined(CONFIG_SOFTMMU)
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
+tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+#endif
+
+/* Call generated code */
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 
0);
+
+/* Return path for goto_ptr. Set return value to 0 */
+s->code_gen_epilogue = s->code_ptr;
+tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
+
+/* TB epilogue */
+tb_ret_addr = s->code_ptr;
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0);
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
@@ -1631,3 +1697,48 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, 
uintptr_t jmp_addr,
 
 flush_icache_range(jmp_addr, jmp_addr + 8);
 }
+
+typedef struct {
+DebugFrameHeader h;
+uint8_t fde_def_cfa[4];
+uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_RISCV
+
+static const DebugFrame debug_frame = {
+.h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
+.h.cie.id = -1,
+.h.cie.version = 1,
+.h.cie.code_align = 1,
+.h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
+.h.cie.return_column = TCG_REG_RA,
+
+/* Total FDE size does not include the "len" member.  */
+.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
+
+.fde_def_cfa = {
+12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */
+(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
+(FRAME_SIZE >> 7)
+},
+.fde_reg_ofs = {
+0x80 + 9,  12,  /* DW_CFA_offset, s1,  -96 */
+0x80 + 18, 11,  /* DW_CFA_offset, s2,  -88 */
+0x80 + 19, 10,  /* DW_CFA_offset, s3,  -80 */
+0x80 + 20, 9,   /* DW_CFA_offset, s4,  -72 */
+0x80 + 21, 8,   /* DW_CFA_offset, s5,  -64 */
+0x80 + 22, 7,   /* DW_CFA_offset, s6,  -56 */
+0x80 + 23, 6,   /* DW_CFA_offset, s7,  -48 */
+0x80 + 24, 5,   /* DW_CFA_offset, s8,  -40 */
+0x80 + 25, 4,   /* DW_CFA_offset, s9,  -32 */
+0x80 + 26, 3,   /* DW_CFA_offset, s10, -24 */
+0x80 + 27, 2,   /* DW_CFA_offset, s11, -16 */
+0x80 + 1 , 1,   /* DW_CFA_offset, ra,  -8 */
+}
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
-- 
2.19.1




[Qemu-devel] [RFC v2 23/24] WIP: Add missing instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.inc.c | 77 ++
 1 file changed, 77 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 13756f6d0d..b8e9c0e126 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -606,6 +606,57 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 return false;
 }
 
+static void tcg_out_addsub2(TCGContext *s,
+TCGReg rl, TCGReg rh,
+TCGReg al, TCGReg ah,
+TCGReg bl, TCGReg bh,
+bool cbl, bool cbh, bool is_sub)
+{
+/* FIXME: This is just copied from MIPS */
+TCGReg th = TCG_REG_TMP1;
+
+/* If we have a negative constant such that negating it would
+   make the high part zero, we can (usually) eliminate one insn.  */
+if (cbl && cbh && bh == -1 && bl != 0) {
+bl = -bl;
+bh = 0;
+is_sub = !is_sub;
+}
+
+/* By operating on the high part first, we get to use the final
+   carry operation to move back from the temporary.  */
+if (!cbh) {
+tcg_out_opc_reg(s, (is_sub ? OPC_SUB : OPC_ADDI), th, ah, bh);
+} else if (bh != 0 || ah == rl) {
+tcg_out_opc_imm(s, OPC_ADDI, th, ah, (is_sub ? -bh : bh));
+} else {
+th = ah;
+}
+
+if (is_sub) {
+if (cbl) {
+tcg_out_opc_imm(s, OPC_SLLI, TCG_REG_TMP0, al, bl);
+tcg_out_opc_imm(s, OPC_ADDI, rl, al, -bl);
+} else {
+tcg_out_opc_reg(s, OPC_SLLI, TCG_REG_TMP0, al, bl);
+tcg_out_opc_reg(s, OPC_SUB, rl, al, bl);
+}
+tcg_out_opc_reg(s, OPC_SUB, rh, th, TCG_REG_TMP0);
+} else {
+if (cbl) {
+tcg_out_opc_imm(s, OPC_ADDI, rl, al, bl);
+tcg_out_opc_imm(s, OPC_SLLI, TCG_REG_TMP0, rl, bl);
+} else if (rl == al && rl == bl) {
+tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, al, 31);
+tcg_out_opc_reg(s, OPC_ADDI, rl, al, bl);
+} else {
+tcg_out_opc_reg(s, OPC_ADDI, rl, al, bl);
+tcg_out_opc_reg(s, OPC_SLLI, TCG_REG_TMP0, rl, (rl == bl ? al : 
bl));
+}
+tcg_out_opc_reg(s, OPC_ADDI, rh, th, TCG_REG_TMP0);
+}
+}
+
 static const struct {
 RISCVInsn op;
 bool swap;
@@ -1384,6 +1435,18 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 break;
 
+case INDEX_op_add2_i32:
+case INDEX_op_add2_i64:
+tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
+const_args[4], const_args[5], false);
+break;
+
+case INDEX_op_sub2_i32:
+case INDEX_op_sub2_i64:
+tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
+const_args[4], const_args[5], true);
+break;
+
 case INDEX_op_brcond_i32:
 case INDEX_op_brcond_i64:
 tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
@@ -1439,6 +1502,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 break;
 
 case INDEX_op_ext32s_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_extrh_i64_i32:
 case INDEX_op_ext_i32_i64:
 tcg_out_ext32s(s, a0, a1);
 break;
@@ -1505,6 +1570,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 = { .args_ct_str = { "LZ", "LZ", "L" } };
 static const TCGTargetOpDef LZ_LZ_L_L
 = { .args_ct_str = { "LZ", "LZ", "L", "L" } };
+static const TCGTargetOpDef rZ_rZ_rZ_rZ_rZ_rZ
+= { .args_ct_str = { "rZ", "rZ", "rZ", "rZ", "rZ", "rZ" } };
 
 switch (op) {
 case INDEX_op_goto_ptr:
@@ -1537,6 +1604,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_ext16s_i32:
 case INDEX_op_ext16s_i64:
 case INDEX_op_ext32s_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_extrh_i64_i32:
 case INDEX_op_ext_i32_i64:
 return &r_r;
 
@@ -1593,6 +1662,14 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_brcond_i64:
 return &rZ_rZ;
 
+case INDEX_op_add2_i32:
+case INDEX_op_add2_i64:
+return &rZ_rZ_rZ_rZ_rZ_rZ;
+
+case INDEX_op_sub2_i32:
+case INDEX_op_sub2_i64:
+return &rZ_rZ_rZ_rZ_rZ_rZ;
+
 case INDEX_op_brcond2_i32:
 return &rZ_rZ_rZ_rZ;
 
-- 
2.19.1




[Qemu-devel] [RFC v2 20/24] tcg: Add RISC-V cpu signal handler

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 accel/tcg/user-exec.c | 75 +++
 1 file changed, 75 insertions(+)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index cd75829cf2..941295ea49 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -571,6 +571,81 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
 }
 
+#elif defined(__riscv)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+   void *puc)
+{
+siginfo_t *info = pinfo;
+ucontext_t *uc = puc;
+greg_t pc = uc->uc_mcontext.__gregs[REG_PC];
+uint32_t insn = *(uint32_t *)pc;
+int is_write = 0;
+
+/* Detect store by reading the instruction at the program
+   counter. Note: we currently only generate 32-bit
+   instructions so we thus only detect 32-bit stores */
+switch (((insn >> 0) & 0b11)) {
+case 3:
+switch (((insn >> 2) & 0b1)) {
+case 8:
+switch (((insn >> 12) & 0b111)) {
+case 0: /* sb */
+case 1: /* sh */
+case 2: /* sw */
+case 3: /* sd */
+case 4: /* sq */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+case 9:
+switch (((insn >> 12) & 0b111)) {
+case 2: /* fsw */
+case 3: /* fsd */
+case 4: /* fsq */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+default:
+break;
+}
+}
+
+/* Check for compressed instructions */
+switch (((insn >> 13) & 0b111)) {
+case 7:
+switch (insn & 0b11) {
+case 0: /*c.sd */
+case 2: /* c.sdsp */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+case 6:
+switch (insn & 0b11) {
+case 0: /* c.sw */
+case 3: /* c.swsp */
+is_write = 1;
+break;
+default:
+break;
+}
+break;
+default:
+break;
+}
+
+return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
+}
+
 #else
 
 #error host CPU specific signal handler needed
-- 
2.19.1




[Qemu-devel] [RFC v2 09/24] riscv: tcg-target: Add the instruction emitters

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 40 ++
 1 file changed, 40 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index c659c4de39..ca7ae8939a 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -343,6 +343,46 @@ static int32_t encode_uj(RISCVInsn opc, TCGReg rd, 
uint32_t imm)
 return opc | (rd & 0x1f) << 7 | encode_ujimm12(imm);
 }
 
+/*
+ * RISC-V instruction emitters
+ */
+
+static void tcg_out_opc_reg(TCGContext *s, RISCVInsn opc,
+TCGReg rd, TCGReg rs1, TCGReg rs2)
+{
+tcg_out32(s, encode_r(opc, rd, rs1, rs2));
+}
+
+static void tcg_out_opc_imm(TCGContext *s, RISCVInsn opc,
+TCGReg rd, TCGReg rs1, TCGArg imm)
+{
+tcg_out32(s, encode_i(opc, rd, rs1, imm));
+}
+
+static void tcg_out_opc_store(TCGContext *s, RISCVInsn opc,
+  TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+tcg_out32(s, encode_s(opc, rs1, rs2, imm));
+}
+
+static void tcg_out_opc_branch(TCGContext *s, RISCVInsn opc,
+   TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+tcg_out32(s, encode_sb(opc, rs1, rs2, imm));
+}
+
+static void tcg_out_opc_upper(TCGContext *s, RISCVInsn opc,
+  TCGReg rd, uint32_t imm)
+{
+tcg_out32(s, encode_u(opc, rd, imm));
+}
+
+static void tcg_out_opc_jump(TCGContext *s, RISCVInsn opc,
+ TCGReg rd, uint32_t imm)
+{
+tcg_out32(s, encode_uj(opc, rd, imm));
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




[Qemu-devel] [RFC v2 21/24] dias: Add RISC-V support

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 disas.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/disas.c b/disas.c
index 5325b7e6be..82a408f272 100644
--- a/disas.c
+++ b/disas.c
@@ -522,8 +522,14 @@ 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(__riscv) && defined(CONFIG_RISCV_DIS)
+#if defined(_ILP32)
+print_insn = print_insn_riscv32;
+#elif defined(_LP64)
+print_insn = print_insn_riscv64;
+#else
+#error unsupported RISC-V ABI
+#endif
 #elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
 print_insn = print_insn_arm_a64;
 s.info.cap_arch = CS_ARCH_ARM64;
-- 
2.19.1




[Qemu-devel] [RFC QEMU v2 1/2] arm/virt: Initialize generic timer scale factor dynamically

2018-11-27 Thread Bijan Mottahedeh
Initialize the generic timer scale factor based on the counter frequency
register cntfrq_el0, and default to the current static value if necessary.
Always use the default value for TCG.

Signed-off-by: Bijan Mottahedeh 
---
 hw/arm/virt.c  | 17 +
 target/arm/helper.c| 19 ---
 target/arm/internals.h |  8 ++--
 target/arm/kvm64.c |  1 +
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 281ddcd..792d223 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -59,6 +59,7 @@
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
+#include "target/arm/internals.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -1710,6 +1711,21 @@ static HotplugHandler 
*virt_machine_get_hotplug_handler(MachineState *machine,
 return NULL;
 }
 
+static void set_system_clock_scale(void)
+{
+unsigned long cntfrq_el0 = 0;
+
+#ifdef  CONFIG_KVM
+asm volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq_el0));
+#endif
+
+if (cntfrq_el0 == 0) {
+cntfrq_el0 = GTIMER_SCALE_DEF;
+}
+
+system_clock_scale = NANOSECONDS_PER_SECOND / (int)cntfrq_el0;
+}
+
 static void virt_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -1736,6 +1752,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 assert(!mc->get_hotplug_handler);
 mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
 hc->plug = virt_machine_device_plug_cb;
+set_system_clock_scale();
 }
 
 static const TypeInfo virt_machine_info = {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 66afb08..6330586 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -18,6 +18,7 @@
 #include "sysemu/kvm.h"
 #include "fpu/softfloat.h"
 #include "qemu/range.h"
+#include "hw/arm/arm.h"
 
 #define ARM_CPU_FREQ 10 /* FIXME: 1 GHz, should be configurable */
 
@@ -1614,6 +1615,18 @@ static CPAccessResult gt_cntfrq_access(CPUARMState *env, 
const ARMCPRegInfo *ri,
 return CP_ACCESS_OK;
 }
 
+static void gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+assert(GTIMER_SCALE);
+assert(ri->fieldoffset);
+
+if (cpreg_field_is_64bit(ri)) {
+CPREG_FIELD64(env, ri) = NANOSECONDS_PER_SECOND / GTIMER_SCALE;
+} else {
+CPREG_FIELD32(env, ri) = NANOSECONDS_PER_SECOND / GTIMER_SCALE;
+}
+}
+
 static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
 bool isread)
 {
@@ -1709,7 +1722,7 @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
 }
 }
 
-static uint64_t gt_get_countervalue(CPUARMState *env)
+uint64_t gt_get_countervalue(CPUARMState *env)
 {
 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
 }
@@ -1996,7 +2009,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
   .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
   .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
   .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
-  .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
+  .resetfn = gt_cntfrq_reset,
 },
 /* overall control: mostly access permissions */
 { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH,
@@ -2187,7 +2200,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
   .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
   .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
   .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
-  .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
+  .resetfn = gt_cntfrq_reset,
 },
 { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
diff --git a/target/arm/internals.h b/target/arm/internals.h
index dc93577..b66a1fa 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -52,9 +52,13 @@ static inline bool excp_is_internal(int excp)
 }
 
 /* Scale factor for generic timers, ie number of ns per tick.
- * This gives a 62.5MHz timer.
+ * Calculated dynamically based on CNTFRQ with a default value
+ * that gives a 62.5MHZ timer.
  */
-#define GTIMER_SCALE 16
+#define GTIMER_SCALEsystem_clock_scale
+#define GTIMER_SCALE_DEF16
+
+uint64_t gt_get_countervalue(CPUARMState *);
 
 /* Bit definitions for the v7M CONTROL register */
 FIELD(V7M_CONTROL, NPRIV, 0, 1)
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index e0b8246..5d1c394 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -485,6 +485,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
 set_feature(&features, ARM_FEATURE_NEON);
 set_feature(&features, ARM_FEATURE_AARCH64);
 set_feature(&features, ARM_FEATURE_PMU);
+set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
 
 ahcf->features = featu

[Qemu-devel] [RFC v2 13/24] riscv: tcg-target: Add the out load and store instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 4291a00962..cac4a4b615 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -546,6 +546,66 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, 
TCGReg arg)
 tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
 }
 
+static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
+ TCGReg addr, intptr_t offset)
+{
+#if TCG_TARGET_REG_BITS == 64
+int32_t imm12 = sextract64(offset, 0, 12);
+#else
+int32_t imm12 = sextract32(offset, 0, 12);
+#endif
+if (offset != imm12) {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
+if (addr != TCG_REG_ZERO) {
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP2, TCG_REG_TMP2, addr);
+}
+addr = TCG_REG_TMP2;
+}
+switch (opc) {
+case OPC_SB:
+case OPC_SH:
+case OPC_SW:
+case OPC_SD:
+tcg_out_opc_store(s, opc, addr, data, imm12);
+break;
+case OPC_LB:
+case OPC_LBU:
+case OPC_LH:
+case OPC_LHU:
+case OPC_LW:
+case OPC_LWU:
+case OPC_LD:
+tcg_out_opc_imm(s, opc, data, addr, imm12);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
+tcg_out_ldst(s, is32bit ? OPC_LW : OPC_LD, arg, arg1, arg2);
+}
+
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is32bit = (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32);
+tcg_out_ldst(s, is32bit ? OPC_SW : OPC_SD, arg, arg1, arg2);
+}
+
+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
+TCGReg base, intptr_t ofs)
+{
+if (val == 0) {
+tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
+return true;
+}
+return false;
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




[Qemu-devel] [RFC v2 17/24] riscv: tcg-target: Add the out op decoder

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 472 +
 1 file changed, 472 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index e3b5f48848..d5fd7ca854 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1145,6 +1145,478 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 #endif
 }
 
+static tcg_insn_unit *tb_ret_addr;
+
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+   const TCGArg *args, const int *const_args)
+{
+TCGArg a0 = args[0];
+TCGArg a1 = args[1];
+TCGArg a2 = args[2];
+int c2 = const_args[2];
+const bool is32bit = TCG_TARGET_REG_BITS == 32;
+
+switch (opc) {
+case INDEX_op_exit_tb:
+/* Reuse the zeroing that exists for goto_ptr.  */
+if (a0 == 0) {
+tcg_out_goto_long(s, s->code_gen_epilogue);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
+tcg_out_goto_long(s, tb_ret_addr);
+}
+break;
+
+case INDEX_op_goto_tb:
+if (s->tb_jmp_insn_offset) {
+/* direct jump method */
+s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+/* should align on 64-bit boundary for atomic patching */
+tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+} else {
+/* indirect jump method */
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
+   (uintptr_t)(s->tb_jmp_target_addr + a0));
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+}
+s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
+break;
+
+case INDEX_op_goto_ptr:
+tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, a0, 0);
+break;
+
+case INDEX_op_br:
+tcg_out_reloc(s, s->code_ptr, R_RISCV_JAL, arg_label(a0), 0);
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, 0);
+break;
+
+case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
+tcg_out_ldst(s, OPC_LBU, a0, a1, a2);
+break;
+case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
+tcg_out_ldst(s, OPC_LB, a0, a1, a2);
+break;
+case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
+tcg_out_ldst(s, OPC_LHU, a0, a1, a2);
+break;
+case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
+tcg_out_ldst(s, OPC_LH, a0, a1, a2);
+break;
+case INDEX_op_ld32u_i64:
+tcg_out_ldst(s, OPC_LWU, a0, a1, a2);
+break;
+case INDEX_op_ld_i32:
+case INDEX_op_ld32s_i64:
+tcg_out_ldst(s, OPC_LW, a0, a1, a2);
+break;
+case INDEX_op_ld_i64:
+tcg_out_ldst(s, OPC_LD, a0, a1, a2);
+break;
+
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+tcg_out_ldst(s, OPC_SB, a0, a1, a2);
+break;
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+tcg_out_ldst(s, OPC_SH, a0, a1, a2);
+break;
+case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+tcg_out_ldst(s, OPC_SW, a0, a1, a2);
+break;
+case INDEX_op_st_i64:
+tcg_out_ldst(s, OPC_SD, a0, a1, a2);
+break;
+
+case INDEX_op_add_i32:
+if (c2) {
+tcg_out_opc_imm(s, is32bit ? OPC_ADDI : OPC_ADDIW, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, is32bit ? OPC_ADD : OPC_ADDW, a0, a1, a2);
+}
+break;
+case INDEX_op_add_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_ADD, a0, a1, a2);
+}
+break;
+
+case INDEX_op_sub_i32:
+if (c2) {
+tcg_out_opc_imm(s, is32bit ? OPC_ADDI : OPC_ADDIW, a0, a1, -a2);
+} else {
+tcg_out_opc_reg(s, is32bit ? OPC_SUB : OPC_SUBW, a0, a1, a2);
+}
+break;
+case INDEX_op_sub_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ADDI, a0, a1, -a2);
+} else {
+tcg_out_opc_reg(s, OPC_SUB, a0, a1, a2);
+}
+break;
+
+case INDEX_op_and_i32:
+case INDEX_op_and_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ANDI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_AND, a0, a1, a2);
+}
+break;
+
+case INDEX_op_or_i32:
+case INDEX_op_or_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_ORI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_OR, a0, a1, a2);
+}
+break;
+
+case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
+if (c2) {
+tcg_out_opc_imm(s, OPC_XORI, a0, a1, a2);
+} else {
+tcg_out_opc_reg(s, OPC_XOR, a0, a1, a2);
+}
+break;
+
+

[Qemu-devel] [RFC v2 14/24] riscv: tcg-target: Add branch and jump instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 141 +
 1 file changed, 141 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index cac4a4b615..97831bfb9d 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -606,6 +606,147 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 return false;
 }
 
+static const struct {
+RISCVInsn op;
+bool swap;
+} tcg_brcond_to_riscv[] = {
+[TCG_COND_EQ] =  { OPC_BEQ,  false },
+[TCG_COND_NE] =  { OPC_BNE,  false },
+[TCG_COND_LT] =  { OPC_BLT,  false },
+[TCG_COND_GE] =  { OPC_BGE,  false },
+[TCG_COND_LE] =  { OPC_BGE,  true  },
+[TCG_COND_GT] =  { OPC_BLT,  true  },
+[TCG_COND_LTU] = { OPC_BLTU, false },
+[TCG_COND_GEU] = { OPC_BGEU, false },
+[TCG_COND_LEU] = { OPC_BGEU, true  },
+[TCG_COND_GTU] = { OPC_BLTU, true  }
+};
+
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+   TCGReg arg2, TCGLabel *l)
+{
+RISCVInsn op = tcg_brcond_to_riscv[cond].op;
+bool swap = tcg_brcond_to_riscv[cond].swap;
+
+tcg_out_opc_branch(s, op, swap ? arg2 : arg1, swap ? arg1 : arg2, 0);
+
+tcg_debug_assert(op != 0);
+
+if (l->has_value) {
+reloc_sbimm12(s->code_ptr - 1, l->u.value_ptr);
+} else {
+tcg_out_reloc(s, s->code_ptr - 1, R_RISCV_BRANCH, l, 0);
+}
+}
+
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+TCGReg arg1, TCGReg arg2)
+{
+switch (cond) {
+case TCG_COND_EQ:
+tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
+break;
+case TCG_COND_NE:
+tcg_out_opc_reg(s, OPC_SUB, ret, arg1, arg2);
+tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
+break;
+case TCG_COND_LT:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
+break;
+case TCG_COND_GE:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_LE:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_GT:
+tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
+break;
+case TCG_COND_LTU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
+break;
+case TCG_COND_GEU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_LEU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
+tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
+break;
+case TCG_COND_GTU:
+tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
+break;
+default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
+TCGReg bl, TCGReg bh, TCGLabel *l)
+{
+/* todo */
+g_assert_not_reached();
+}
+
+static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)
+{
+/* todo */
+g_assert_not_reached();
+}
+
+static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
+{
+ptrdiff_t offset = tcg_pcrel_diff(s, target);
+tcg_debug_assert(offset == sextract64(offset, 0, 26));
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
+}
+
+static inline void tcg_out_goto_long(TCGContext *s, tcg_insn_unit *target)
+{
+ptrdiff_t offset = tcg_pcrel_diff(s, target);
+
+if (offset == sextract64(offset, 0, 26)) {
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
+} else {
+tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, (intptr_t)target);
+tcg_out_opc_jump(s, OPC_JAL, TCG_REG_TMP0, 0);
+}
+}
+
+static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
+{
+TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
+ptrdiff_t offset = tcg_pcrel_diff(s, arg);
+if (offset == sextract64(offset, 1, 20) << 1) {
+/* short jump: -2097150 to 2097152 */
+tcg_out_opc_jump(s, OPC_JAL, link, offset);
+} else if (TCG_TARGET_REG_BITS == 32 ||
+offset == sextract64(offset, 1, 31) << 1) {
+/* long jump: -2147483646 to 2147483648 */
+tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
+tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0);
+reloc_call(s->code_ptr - 2, arg);
+} else if (TCG_TARGET_REG_BITS == 64) {
+/* far jump: 64-bit */
+tcg_target_long imm = sextract64((tcg_target_long)arg, 0, 12);
+tcg_target_long base = (tcg_target_long)arg - imm;
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, base);
+tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TM

[Qemu-devel] [RFC v2 10/24] riscv: tcg-target: Add the relocation functions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 51 ++
 1 file changed, 51 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index ca7ae8939a..9c48679f11 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -383,6 +383,57 @@ static void tcg_out_opc_jump(TCGContext *s, RISCVInsn opc,
 tcg_out32(s, encode_uj(opc, rd, imm));
 }
 
+/*
+ * Relocations
+ */
+
+static void reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+tcg_debug_assert(offset == sextract32(offset, 1, 12) << 1);
+
+code_ptr[0] |= encode_sbimm12(offset);
+}
+
+static void reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+tcg_debug_assert(offset == sextract32(offset, 1, 20) << 1);
+
+code_ptr[0] |= encode_ujimm12(offset);
+}
+
+static void reloc_call(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
+{
+intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
+tcg_debug_assert(offset == (int32_t)offset);
+
+int32_t hi20 = ((offset + 0x800) >> 12) << 12;
+int32_t lo12 = offset - hi20;
+
+code_ptr[0] |= encode_uimm20(hi20);
+code_ptr[1] |= encode_imm12(lo12);
+}
+
+static void patch_reloc(tcg_insn_unit *code_ptr, int type,
+intptr_t value, intptr_t addend)
+{
+tcg_debug_assert(addend == 0);
+switch (type) {
+case R_RISCV_BRANCH:
+reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
+break;
+case R_RISCV_JAL:
+reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
+break;
+case R_RISCV_CALL:
+reloc_call(code_ptr, (tcg_insn_unit *)value);
+break;
+default:
+tcg_abort();
+}
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




[Qemu-devel] [RFC QEMU v2 0/2] arm/virt: Account for guest pause time

2018-11-27 Thread Bijan Mottahedeh
v1 -> v2:

- Call the asm code only for kvm and always use the default value for TCG.

This patch series address two Qemu issues:

  - improper system clock frequency initialization
  - lack of pause (virtsh suspend) time accounting

A simple test to reproduce the problem executes one or more instances
of the following command in the guest:

dd if=/dev/zero of=/dev/null &

and then pauses and resumes the guest after a certain delay:

virsh suspend # pauses the guest
sleep 120
virsh resume 

After the guest is resumed, there are soft lockup warning messages
displayed on the console.

A comparison with x86 shows that hwclock and date values diverge after
the above pause and resume sequence for x86 but remain the same for Arm.

Patch 1 intializes the system clock frequency in Qemu similar to the
kernel.

Patch 2 accumulates the total guest pause time in QEMU and adjusts the
virtual offset counter accordingly before the guest is resumed.

The patches have been tested on an Ampere system.  With the patches the
time behavior is the same as x86 and the soft lockup messages go away.


Clock Frequency Initialization
==

Arm v8 provides the virtual counter (cntvct), virtual counter offset
(cntvoff), and counter frequency (cntfrq) registers for guest time
management.

Linux Arm platform code initializes the system clock frequency from
cntrfq_el0 register and sets the value into a statically created device
tree (DT) node.  It is not clear why the timer device node is created
with TIMER_OF_DECLARE().  The DT passed from Qemu to the kernel does not
contain a timer node.

drivers/clocksource/arm_arch_timer.c:

static inline u32 arch_timer_get_cntfrq(void)
{
return read_sysreg(cntfrq_el0);
}

rate = arch_timer_get_cntfrq();
arch_timer_of_configure_rate(rate, np);

/*
 * For historical reasons, when probing with DT we use whichever (non-zero)
 * rate was probed first, and don't verify that others match. If the first node
 * probed has a clock-frequency property, this overrides the HW register.
 */
static void arch_timer_of_configure_rate(u32 rate, struct device_node *np)
{
...
   if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
  arch_timer_rate = rate;
...
}

TIMER_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
TIMER_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);


Linux then initializes the clock frequency to 50MHZ.

Qemu however hard codes the clock frequency to 62.5MHZ.

target/arm/cpu.h:

/* Scale factor for generic timers, ie number of ns per tick.
 * This gives a 62.5MHz timer.
 */
#define GTIMER_SCALE 16

The suggested fix is to follow the kernel's arch_timer_get_cntfrq()
approach in order to set system_clock_scale to match the kernel's idea
of clock-frequency, rather than using a hard-coded value.

Ultimately, it seems that Qemu should construct the timer DT node and
pass the actual clock frequency value to the kernel that way but that
brings up an interface and backward compatibility considerations.
Furthermore, the implications for ACPI method of probing is not clear.


Pause Time Accounting
=

Linux registers two clock sources, a platform-independent jiffies
clocksource and a Arm-specific arch_sys_counter; the read interface
for the latter reads the virtual counter register:

static struct clocksource clocksource_jiffies = {
.name   = "jiffies",
.rating = 1, /* lowest valid rating*/
.read   = jiffies_read,
.mask   = CLOCKSOURCE_MASK(32),
.mult   = TICK_NSEC << JIFFIES_SHIFT, /* details above */
.shift  = JIFFIES_SHIFT,
.max_cycles = 10,
};

static struct clocksource clocksource_counter = {
.name   = "arch_sys_counter",
.rating = 400,
.read   = arch_counter_read,
.mask   = CLOCKSOURCE_MASK(56),
.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
};

arch_counter_read()
-> arch_timer_read_counter()
   -> arch_counter_get_cntvct()
  -> arch_timer_reg_read_stable(cntvct_el0)

The virtual counter offset register is set from:

kvm_timer_vcpu_load()
-> set_cntvoff()

The counter is zeroed from:

kvm_timer_vcpu_put()
-> set_cntvoff()

/*
 * The kernel may decide to run userspace after calling vcpu_put, so
 * we reset cntvoff to 0 to ensure a consistent read between user
 * accesses to the virtual counter and kernel access to the physical
 * counter of non-VHE case. For VHE, the virtual counter uses a fixed
 * virtual offset of zero, so no need to zero CNTVOFF_EL2 register.
 */
if (!has_vhe())
set_cntvoff(0);

The virtual counter offset is not modified anywhere however to account
for pause time.  The suggested fix is to add pause time accounting to
Qemu.

One potential issue is whether modifying the virtual counter offset
breaks any assumptions, e.g., see the kvm_timer_vcp

[Qemu-devel] [RFC v2 12/24] riscv: tcg-target: Add the extract instructions

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index e5a07b146f..4291a00962 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -512,6 +512,40 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 }
 }
 
+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_ANDI, ret, arg, 0xff);
+}
+
+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLI, ret, arg, TCG_TARGET_REG_BITS - 16);
+tcg_out_opc_imm(s, OPC_SRLI, ret, ret, TCG_TARGET_REG_BITS - 16);
+}
+
+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLI, ret, arg, 32);
+tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
+}
+
+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLI, ret, arg, TCG_TARGET_REG_BITS - 8);
+tcg_out_opc_imm(s, OPC_SRAI, ret, ret, TCG_TARGET_REG_BITS - 8);
+}
+
+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_SLLI, ret, arg, TCG_TARGET_REG_BITS - 16);
+tcg_out_opc_imm(s, OPC_SRAI, ret, ret, TCG_TARGET_REG_BITS - 16);
+}
+
+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
+}
+
 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
   uintptr_t addr)
 {
-- 
2.19.1




Re: [Qemu-devel] [PATCH] scsi: Address spurious clang warning

2018-11-27 Thread John Snow



On 11/27/18 2:02 PM, Eric Blake wrote:
> On 11/27/18 12:49 PM, John Snow wrote:
>> Some versions of Clang prior to 6.0 (and some builds of clang after,
>> such as 6.0.1-2.fc28) fail to recognize { 0 } as a valid initializer
>> for a struct with subobjects when -Wmissing-braces is enabled.
>>
>> https://bugs.llvm.org/show_bug.cgi?id=21689 and
>> https://reviews.llvm.org/rL314499 suggests this should be fixed in 6.0,
>> but it might not be the case for older versions or downstream versions.
>>
>> For now, follow the precedent of ebf2a499 and replace the standard { 0 }
>> with the accepted { } to silence this warning and allow the build to
>> work under clang 6.0.1-2.fc28, and builds prior to 6.0.
>>
>> Signed-off-by: John Snow 
>>
> 
> Reviewed-by: Eric Blake 
> 
> I'm okay if this goes into -rc3 as a build-fix; I'm also okay if it
> slips to 4.0.
> 
>> ---
>>
>> What I am actually less clear on is why this appears to be a problem
>> only now; since the introduction of { 0 } was in 2.11. It might be
>> a regression only in the fedora distribution of Clang 6.0.
> 
> Or even a redefinition of struct dm_ioctl in some header where you are
> just now picking up a new struct layout that tickles the Clang issue in
> relation to the previous layout (since it is possible to have two
> structs that are ABI-compatible but where only one of the two has a
> nested substruct).
> 
>> +++ b/scsi/qemu-pr-helper.c
>> @@ -236,7 +236,7 @@ static void dm_init(void)
>>   perror("Cannot open " CONTROL_PATH);
>>   exit(1);
>>   }
>> -    struct dm_ioctl dm = { 0 };
>> +    struct dm_ioctl dm = { };
> 
> Random thought: would it be worth having "qemu/compiler.h" define a macro:
> 
> #if ...broken clang
> #define ZERO_INIT {}
> #else
> #define ZERO_INIT {0}
> #endif
> 
> and then rewrite all our '= { 0? }' initializers into '= ZERO_INIT'?  Or
> is that aesthetically too ugly?
> 

Obscures perfectly legitimate C code without solving anything, IMO. As
much code as can reflect "naked" C89/C99/GNU99, the better.

--js



[Qemu-devel] [RFC v2 05/24] riscv: Add the tcg-target header file

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.h | 173 +
 1 file changed, 173 insertions(+)
 create mode 100644 tcg/riscv/tcg-target.h

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
new file mode 100644
index 00..76ce2acfb5
--- /dev/null
+++ b/tcg/riscv/tcg-target.h
@@ -0,0 +1,173 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef RISCV_TCG_TARGET_H
+#define RISCV_TCG_TARGET_H
+
+#if __riscv_xlen == 32
+# define TCG_TARGET_REG_BITS 32
+#elif __riscv_xlen == 64
+# define TCG_TARGET_REG_BITS 64
+#endif
+
+#define TCG_TARGET_INSN_UNIT_SIZE 4
+#define TCG_TARGET_TLB_DISPLACEMENT_BITS 20
+#define TCG_TARGET_NB_REGS 32
+
+typedef enum {
+TCG_REG_ZERO,
+TCG_REG_RA,
+TCG_REG_SP,
+TCG_REG_GP,
+TCG_REG_TP,
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_S0,
+TCG_REG_S1,
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+
+/* aliases */
+TCG_AREG0  = TCG_REG_S0,
+TCG_GUEST_BASE_REG = TCG_REG_S1,
+TCG_REG_TMP0   = TCG_REG_T6,
+TCG_REG_TMP1   = TCG_REG_T5,
+TCG_REG_TMP2   = TCG_REG_T4,
+} TCGReg;
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK  TCG_REG_SP
+#define TCG_TARGET_STACK_ALIGN  16
+#define TCG_TARGET_CALL_ALIGN_ARGS  1
+#define TCG_TARGET_CALL_STACK_OFFSET0
+
+/* optional instructions */
+#define TCG_TARGET_HAS_goto_ptr 1
+#define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_div_i32  1
+#define TCG_TARGET_HAS_rem_i32  1
+#define TCG_TARGET_HAS_div2_i32 0
+#define TCG_TARGET_HAS_rot_i32  0
+#define TCG_TARGET_HAS_deposit_i32  0
+#define TCG_TARGET_HAS_extract_i32  0
+#define TCG_TARGET_HAS_sextract_i32 0
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
+#define TCG_TARGET_HAS_mulu2_i320
+#define TCG_TARGET_HAS_muls2_i320
+#define TCG_TARGET_HAS_muluh_i32(TCG_TARGET_REG_BITS == 32)
+#define TCG_TARGET_HAS_mulsh_i32(TCG_TARGET_REG_BITS == 32)
+#define TCG_TARGET_HAS_ext8s_i321
+#define TCG_TARGET_HAS_ext16s_i32   1
+#define TCG_TARGET_HAS_ext8u_i321
+#define TCG_TARGET_HAS_ext16u_i32   1
+#define TCG_TARGET_HAS_bswap16_i32  0
+#define TCG_TARGET_HAS_bswap32_i32  0
+#define TCG_TARGET_HAS_not_i32  1
+#define TCG_TARGET_HAS_neg_i32  1
+#define TCG_TARGET_HAS_andc_i32 0
+#define TCG_TARGET_HAS_orc_i32  0
+#define TCG_TARGET_HAS_eqv_i32  0
+#define TCG_TARGET_HAS_nand_i32 0
+#define TCG_TARGET_HAS_nor_i32  0
+#define TCG_TARGET_HAS_clz_i32  0
+#define TCG_TARGET_HAS_ctz_i32  0
+#define TCG_TARGET_HAS_ctpop_i320
+#define TCG_TARGET_HAS_direct_jump  0
+#define TCG_TARGET_HAS_brcond2  1
+#define TCG_TARGET_HAS_setcond2 1
+
+#if TCG_TARGET_REG_BITS == 64
+#define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_div_i64  1
+#define TCG_TARGET_HAS_rem_i64  1
+#define TCG_TARGET_HAS_div2_i64 0
+#define TCG_TARGET_HAS_rot_i64  0
+#define TCG_TARGET_HAS_deposit_i64  0
+#define TCG_TARGET_HAS_extract_i64  0
+#define TCG_TARGET_HAS_sextract_i64 0
+#define TCG_TARGET_HAS_extrl_i64_i321
+#define TCG_TARGET_HAS_extrh_i64_i321
+#define TCG_TARGET_HAS_ext8s_i641
+#define TCG_TARGET_HAS_ext16s_i64   1
+#define TCG_TARGET_HAS_ext

[Qemu-devel] [RFC v2 08/24] riscv: tcg-target: Add the immediate encoders

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 105 +
 1 file changed, 105 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 5719af3c08..c659c4de39 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -252,3 +252,108 @@ typedef enum {
 OPC_FENCE_R_RW = 0x023f,
 OPC_FENCE_RW_W = 0x031f,
 } RISCVInsn;
+
+/*
+ * RISC-V immediate and instruction encoders (excludes 16-bit RVC)
+ */
+
+/* Type-R */
+
+static int32_t encode_r(RISCVInsn opc, TCGReg rd, TCGReg rs1, TCGReg rs2)
+{
+return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20;
+}
+
+/* Type-I */
+
+static int32_t encode_imm12(uint32_t imm)
+{
+return (imm & 0xfff) << 20;
+}
+
+static int32_t encode_i(RISCVInsn opc, TCGReg rd, TCGReg rs1, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | encode_imm12(imm);
+}
+
+/* Type-S */
+
+static int32_t encode_simm12(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0xFE0) << 20;
+ret |= (imm & 0x1F) << 7;
+
+return ret;
+}
+
+static int32_t encode_s(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_simm12(imm);
+}
+
+/* Type-SB */
+
+static int32_t encode_sbimm12(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0x1000) << 19;
+ret |= (imm & 0x7e0) << 20;
+ret |= (imm & 0x1e) << 7;
+ret |= (imm & 0x800) >> 4;
+
+return ret;
+}
+
+static int32_t encode_sb(RISCVInsn opc, TCGReg rs1, TCGReg rs2, uint32_t imm)
+{
+return opc | (rs1 & 0x1f) << 15 | (rs2 & 0x1f) << 20 | encode_sbimm12(imm);
+}
+
+/* Type-U */
+
+static int32_t encode_uimm20(uint32_t imm)
+{
+return imm & 0xf000;
+}
+
+static int32_t encode_u(RISCVInsn opc, TCGReg rd, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | encode_uimm20(imm);
+}
+
+/* Type-UJ */
+
+static int32_t encode_ujimm12(uint32_t imm)
+{
+int32_t ret = 0;
+
+ret |= (imm & 0x10) << 11;
+ret |= (imm & 0xffe) << 20;
+ret |= (imm & 0x800) << 9;
+ret |= imm & 0xff000;
+
+return ret;
+}
+
+static int32_t encode_uj(RISCVInsn opc, TCGReg rd, uint32_t imm)
+{
+return opc | (rd & 0x1f) << 7 | encode_ujimm12(imm);
+}
+
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
+  uintptr_t addr)
+{
+intptr_t offset = (intptr_t)addr - (intptr_t)jmp_addr;
+tcg_debug_assert(offset == (int32_t)offset);
+
+int32_t hi20 = ((offset + 0x800) >> 12) << 12;
+int32_t lo12 = offset - hi20;
+
+atomic_set((uint32_t *)jmp_addr, encode_uimm20(hi20));
+atomic_set((uint32_t *)jmp_addr + 4, encode_imm12(lo12));
+
+flush_icache_range(jmp_addr, jmp_addr + 8);
+}
-- 
2.19.1




[Qemu-devel] [RFC v2 06/24] riscv: Add the tcg target registers

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 tcg/riscv/tcg-target.inc.c | 116 +
 1 file changed, 116 insertions(+)
 create mode 100644 tcg/riscv/tcg-target.inc.c

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
new file mode 100644
index 00..a4a1579440
--- /dev/null
+++ b/tcg/riscv/tcg-target.inc.c
@@ -0,0 +1,116 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2018 SiFive, Inc
+ * Copyright (c) 2008-2009 Arnaud Patard 
+ * Copyright (c) 2009 Aurelien Jarno 
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Based on i386/tcg-target.c and mips/tcg-target.c
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_DEBUG_TCG
+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+"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"
+};
+#endif
+
+static const int tcg_target_reg_alloc_order[] = {
+/* Call saved registers */
+/* TCG_REG_S0 reservered for TCG_AREG0 */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_S10,
+TCG_REG_S11,
+
+/* Call clobbered registers */
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+
+/* Argument registers */
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+};
+
+static const int tcg_target_call_iarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+};
+
+static const int tcg_target_call_oarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+};
-- 
2.19.1




[Qemu-devel] [RFC v2 07/24] riscv: tcg-target: Add support for the constraints

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
---
 tcg/riscv/tcg-target.inc.c | 138 +
 1 file changed, 138 insertions(+)

diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index a4a1579440..5719af3c08 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -114,3 +114,141 @@ static const int tcg_target_call_oarg_regs[] = {
 TCG_REG_A0,
 TCG_REG_A1,
 };
+
+#define TCG_CT_CONST_ZERO  0x100
+#define TCG_CT_CONST_S12   0x200
+#define TCG_CT_CONST_N12   0x400
+
+/* parse target specific constraints */
+static const char *target_parse_constraint(TCGArgConstraint *ct,
+   const char *ct_str, TCGType type)
+{
+switch (*ct_str++) {
+case 'r':
+ct->ct |= TCG_CT_REG;
+ct->u.regs = 0x;
+break;
+case 'L':
+/* qemu_ld/qemu_st constraint */
+ct->ct |= TCG_CT_REG;
+ct->u.regs = 0x;
+/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
+#if defined(CONFIG_SOFTMMU)
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[3]);
+tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[4]);
+#endif
+break;
+case 'I':
+ct->ct |= TCG_CT_CONST_S12;
+break;
+case 'N':
+ct->ct |= TCG_CT_CONST_N12;
+break;
+case 'Z':
+/* we can use a zero immediate as a zero register argument. */
+ct->ct |= TCG_CT_CONST_ZERO;
+break;
+default:
+return NULL;
+}
+return ct_str;
+}
+
+/* test if a constant matches the constraint */
+static int tcg_target_const_match(tcg_target_long val, TCGType type,
+  const TCGArgConstraint *arg_ct)
+{
+int ct = arg_ct->ct;
+if (ct & TCG_CT_CONST) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_S12) && val == sextract32(val, 0, 12)) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_N12) && val == sextract32(-val, 0, 12)) {
+return 1;
+}
+return 0;
+}
+
+/*
+ * RISC-V Base ISA opcodes (IM)
+ */
+
+typedef enum {
+OPC_ADD = 0x33,
+OPC_ADDI = 0x13,
+OPC_ADDIW = 0x1b,
+OPC_ADDW = 0x3b,
+OPC_AND = 0x7033,
+OPC_ANDI = 0x7013,
+OPC_AUIPC = 0x17,
+OPC_BEQ = 0x63,
+OPC_BGE = 0x5063,
+OPC_BGEU = 0x7063,
+OPC_BLT = 0x4063,
+OPC_BLTU = 0x6063,
+OPC_BNE = 0x1063,
+OPC_DIV = 0x2004033,
+OPC_DIVU = 0x2005033,
+OPC_DIVUW = 0x200503b,
+OPC_DIVW = 0x200403b,
+OPC_JAL = 0x6f,
+OPC_JALR = 0x67,
+OPC_LB = 0x3,
+OPC_LBU = 0x4003,
+OPC_LD = 0x3003,
+OPC_LH = 0x1003,
+OPC_LHU = 0x5003,
+OPC_LUI = 0x37,
+OPC_LW = 0x2003,
+OPC_LWU = 0x6003,
+OPC_MUL = 0x233,
+OPC_MULH = 0x2001033,
+OPC_MULHSU = 0x2002033,
+OPC_MULHU = 0x2003033,
+OPC_MULW = 0x23b,
+OPC_OR = 0x6033,
+OPC_ORI = 0x6013,
+OPC_REM = 0x2006033,
+OPC_REMU = 0x2007033,
+OPC_REMUW = 0x200703b,
+OPC_REMW = 0x200603b,
+OPC_SB = 0x23,
+OPC_SD = 0x3023,
+OPC_SH = 0x1023,
+OPC_SLL = 0x1033,
+OPC_SLLI = 0x1013,
+OPC_SLLIW = 0x101b,
+OPC_SLLW = 0x103b,
+OPC_SLT = 0x2033,
+OPC_SLTI = 0x2013,
+OPC_SLTIU = 0x3013,
+OPC_SLTU = 0x3033,
+OPC_SRA = 0x40005033,
+OPC_SRAI = 0x40005013,
+OPC_SRAIW = 0x4000501b,
+OPC_SRAW = 0x4000503b,
+OPC_SRL = 0x5033,
+OPC_SRLI = 0x5013,
+OPC_SRLIW = 0x501b,
+OPC_SRLW = 0x503b,
+OPC_SUB = 0x4033,
+OPC_SUBW = 0x403b,
+OPC_SW = 0x2023,
+OPC_XOR = 0x4033,
+OPC_XORI = 0x4013,
+OPC_FENCE_RW_RW = 0x033f,
+OPC_FENCE_R_R = 0x022f,
+OPC_FENCE_W_R = 0x012f,
+OPC_FENCE_R_W = 0x021f,
+OPC_FENCE_W_W = 0x011f,
+OPC_FENCE_R_RW = 0x023f,
+OPC_FENCE_RW_W = 0x031f,
+} RISCVInsn;
-- 
2.19.1




[Qemu-devel] [RFC v2 04/24] exec: Add RISC-V GCC poison macro

2018-11-27 Thread Alistair Francis
Signed-off-by: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 include/exec/poison.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 32d53789f8..ecdc83c147 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -79,6 +79,7 @@
 #pragma GCC poison CONFIG_MOXIE_DIS
 #pragma GCC poison CONFIG_NIOS2_DIS
 #pragma GCC poison CONFIG_PPC_DIS
+#pragma GCC poison CONFIG_RISCV_DIS
 #pragma GCC poison CONFIG_S390_DIS
 #pragma GCC poison CONFIG_SH4_DIS
 #pragma GCC poison CONFIG_SPARC_DIS
-- 
2.19.1




  1   2   3   4   5   >