Re: [Qemu-devel] [PATCH v7 1/8] vhost-user: add vhost_user_gpu_set_socket()

2019-05-13 Thread Gerd Hoffmann
  Hi,

> +VhostUserGpuCursorUpdate
> +
> +
> ++-+---+---++
> +| pos | hot_x | hot_y | cursor |
> ++-+---+---++
> +
> +:pos: a ``VhostUserGpuCursorPos``, the cursor location
> +
> +:hot_x/hot_y: ``u32``, the cursor hot location
> +
> +:cursor: ``[u32; 64 * 64]``, 64x64 RGBA cursor data

Should clarify here what exactly RGBA is. (PIXMAN_a8r8g8b8 I guess).

> +VhostUserGpuUpdate
> +^^
> +
> +++---+---+---+---+--+
> +| scanout-id | x | y | w | h | data |
> +++---+---+---+---+--+
> +
> +:scanout-id: ``u32``, the scanout content to update
> +
> +:x/y/w/h: ``u32``, region of the update
> +
> +:data: RGBA data (the size is computed based on the region size, and
> +   the request type)

Likewise.  Also: alpha channel for the framebuffer?

> +C structure
> +---
> +
> +In QEMU the vhost-user-gpu message is implemented with the following struct:
> +
> +.. code:: c
> +
> +  typedef struct VhostUserGpuMsg {
> +  uint32_t request; /* VhostUserGpuRequest */
> +  uint32_t flags;
> +  uint32_t size; /* the following payload size */

uint32_t padding;

> +  union {
> +  VhostUserGpuCursorPos cursor_pos;
> +  VhostUserGpuCursorUpdate cursor_update;
> +  VhostUserGpuScanout scanout;
> +  VhostUserGpuUpdate update;
> +  VhostUserGpuDMABUFScanout dmabuf_scanout;
> +  struct virtio_gpu_resp_display_info display_info;
> +  uint64_t u64;

... so this 64bit value will be aligned.

cheers,
  Gerd




[Qemu-devel] [PULL 06/31] tcg/arm: Use tcg_out_mov_reg in tcg_out_mov

2019-05-13 Thread Richard Henderson
We have a function that takes an additional condition parameter
over the standard backend interface.  It already takes care of
eliding no-op moves.

Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target.inc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index abf0c444b4..130b6bef1e 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -2267,7 +2267,7 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType 
type, TCGArg val,
 static inline void tcg_out_mov(TCGContext *s, TCGType type,
TCGReg ret, TCGReg arg)
 {
-tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
+tcg_out_mov_reg(s, COND_AL, ret, arg);
 }
 
 static inline void tcg_out_movi(TCGContext *s, TCGType type,
-- 
2.17.1




Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 5/6] ppc: spapr: Enable FWNMI capability

2019-05-13 Thread Aravinda Prasad



On Tuesday 14 May 2019 10:17 AM, David Gibson wrote:
> On Mon, May 13, 2019 at 04:00:43PM +0530, Aravinda Prasad wrote:
>>
>>
>> On Friday 10 May 2019 03:23 PM, David Gibson wrote:
>>> On Fri, May 10, 2019 at 12:45:29PM +0530, Aravinda Prasad wrote:


 On Friday 10 May 2019 12:16 PM, David Gibson wrote:
> On Mon, Apr 22, 2019 at 12:33:35PM +0530, Aravinda Prasad wrote:
>> Enable the KVM capability KVM_CAP_PPC_FWNMI so that
>> the KVM causes guest exit with NMI as exit reason
>> when it encounters a machine check exception on the
>> address belonging to a guest. Without this capability
>> enabled, KVM redirects machine check exceptions to
>> guest's 0x200 vector.
>>
>> This patch also deals with the case when a guest with
>> the KVM_CAP_PPC_FWNMI capability enabled is attempted
>> to migrate to a host that does not support this
>> capability.
>>
>> Signed-off-by: Aravinda Prasad 
>> ---
>>  hw/ppc/spapr.c |1 +
>>  hw/ppc/spapr_caps.c|   26 ++
>>  hw/ppc/spapr_rtas.c|   14 ++
>>  include/hw/ppc/spapr.h |4 +++-
>>  target/ppc/kvm.c   |   14 ++
>>  target/ppc/kvm_ppc.h   |6 ++
>>  6 files changed, 64 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index ffd1715..44e09bb 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -4372,6 +4372,7 @@ static void spapr_machine_class_init(ObjectClass 
>> *oc, void *data)
>>  smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
>>  smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
>>  smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
>> +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
>>  spapr_caps_add_properties(smc, _abort);
>>  smc->irq = _irq_xics;
>>  smc->dr_phb_enabled = true;
>> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
>> index edc5ed0..5b3af04 100644
>> --- a/hw/ppc/spapr_caps.c
>> +++ b/hw/ppc/spapr_caps.c
>> @@ -473,6 +473,22 @@ static void cap_ccf_assist_apply(SpaprMachineState 
>> *spapr, uint8_t val,
>>  }
>>  }
>>  
>> +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
>> +Error **errp)
>> +{
>> +PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>> +
>> +if (!val) {
>> +return; /* Disabled by default */
>> +}
>> +
>> +if (kvm_enabled()) {
>> +if (kvmppc_fwnmi_enable(cpu)) {
>> +error_setg(errp, "Requested fwnmi capability not support by 
>> KVM");
>> +}
>> +}
>> +}
>> +
>>  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>>  [SPAPR_CAP_HTM] = {
>>  .name = "htm",
>> @@ -571,6 +587,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] 
>> = {
>>  .type = "bool",
>>  .apply = cap_ccf_assist_apply,
>>  },
>> +[SPAPR_CAP_FWNMI_MCE] = {
>> +.name = "fwnmi-mce",
>> +.description = "Handle fwnmi machine check exceptions",
>> +.index = SPAPR_CAP_FWNMI_MCE,
>> +.get = spapr_cap_get_bool,
>> +.set = spapr_cap_set_bool,
>> +.type = "bool",
>> +.apply = cap_fwnmi_mce_apply,
>> +},
>>  };
>>  
>>  static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
>> @@ -706,6 +731,7 @@ SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
>>  SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
>>  SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
>>  SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
>> +SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI_MCE);
>>  
>>  void spapr_caps_init(SpaprMachineState *spapr)
>>  {
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index d3499f9..997cf19 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -49,6 +49,7 @@
>>  #include "hw/ppc/fdt.h"
>>  #include "target/ppc/mmu-hash64.h"
>>  #include "target/ppc/mmu-book3s-v3.h"
>> +#include "kvm_ppc.h"
>>  
>>  static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState 
>> *spapr,
>> uint32_t token, uint32_t nargs,
>> @@ -354,6 +355,7 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>target_ulong args,
>>uint32_t nret, target_ulong rets)
>>  {
>> +int ret;
>>  uint64_t rtas_addr = spapr_get_rtas_addr();
>>  
>>  if (!rtas_addr) {
>> @@ -361,6 +363,18 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>>  

Re: [Qemu-devel] [PATCH 08/13] target/arm/monitor: Add query-sve-vector-lengths

2019-05-13 Thread Markus Armbruster
Andrew Jones  writes:

> On Mon, May 13, 2019 at 06:12:38PM +0200, Markus Armbruster wrote:
>> Andrew Jones  writes:
>> 
>> > Provide a QMP interface to query the supported SVE vector lengths.
>> > A migratable guest will need to explicitly specify a valid set of
>> > lengths on the command line and that set can be obtained from the
>> > list returned with this QMP command.
>> >
>> > This patch only introduces the QMP command with the TCG implementation.
>> > The result may not yet be correct for KVM. Following patches ensure
>> > the KVM result is correct.
>> >
>> > Signed-off-by: Andrew Jones 
>> > ---
>> >  qapi/target.json | 34 
>> >  target/arm/monitor.c | 62 
>> >  tests/qmp-cmd-test.c |  1 +
>> >  3 files changed, 97 insertions(+)
>> >
>> > diff --git a/qapi/target.json b/qapi/target.json
>> > index 1d4d54b6002e..ca1e85254780 100644
>> > --- a/qapi/target.json
>> > +++ b/qapi/target.json
>> > @@ -397,6 +397,40 @@
>> >  { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
>> >'if': 'defined(TARGET_ARM)' }
>> >  
>> > +##
>> > +# @SVEVectorLengths:
>> > +#
>> > +# The struct contains a list of integers where each integer is a valid
>> 
>> Suggest to s/The struct contains/Contains/.
>
> OK
>
>> 
>> > +# SVE vector length for a KVM guest on this host. The vector lengths
>> > +# are in quadword (128-bit) units, e.g. '4' means 512 bits (64 bytes).
>> 
>> Any particular reason for counting quad-words instead of bytes, or
>> perhaps bits?
>
> It can be considered just bits here, but when set in sve-vls-map those
> bits are chosen to mean quadwords as that allows us to get up to 8192-bit
> vectors with a single 64-bit word. Maybe I should write more of that here
> to clarify.

Please do.

In general, QMP prefers the plain units over arbitrary multiples,
e.g. Byte, not Mebibyte.  Sadly, many violations of this rule have crept
in.

More complete documentation should help us determine the unit we want
here.

>> > +#
>> > +# @vls:  list of vector lengths in quadwords.
>> > +#
>> > +# Since: 4.1
>> > +##
>> > +{ 'struct': 'SVEVectorLengths',
>> > +  'data': { 'vls': ['int'] },
>> > +  'if': 'defined(TARGET_ARM)' }
>> > +
>> > +##
>> > +# @query-sve-vector-lengths:
>> > +#
>> > +# This command is ARM-only. It will return a list of SVEVectorLengths
>> 
>> No other target-specific command documents its target-specificness like
>> this.  Suggest
>
> Well, it's pretty similar to query-gic-capabilities, which is what I used
> as a template, but I'm happy to change it to whatever you suggest :)

Here's the documentation we generate for query-gic-capabilities:

 -- Command: query-gic-capabilities

 This command is ARM-only.  It will return a list of GICCapability
 objects that describe its capability bits.

 Returns: a list of GICCapability objects.

 Since: 2.6

 Example:
  -> { "execute": "query-gic-capabilities" }
  <- { "return": [{ "version": 2, "emulated": true, "kernel": false },
  { "version": 3, "emulated": false, "kernel": true } ] 
}

 If: 'defined(TARGET_ARM)'

The "If:" line is generated from the schema's condition.  It's not as
readable as I'd like it to be, but it's there, and it always matches the
code.

"This command is ARM-only" is redundant.  Escaped review.  A patch to
drop it would be welcome.

>># Query valid SVE vector length sets.
>> 
>> > +# objects. The list describes all valid SVE vector length sets.
>> > +#
>> > +# Returns: a list of SVEVectorLengths objects
>> > +#
>> > +# Since: 4.1
>> > +#
>> > +# -> { "execute": "query-sve-vector-lengths" }
>> > +# <- { "return": [ { "vls": [ 1 ] },
>> > +#  { "vls": [ 1, 2 ] },
>> > +#  { "vls": [ 1, 2, 4 ] } ] }
>> > +#
>> > +##
>> > +{ 'command': 'query-sve-vector-lengths', 'returns': ['SVEVectorLengths'],
>> > +  'if': 'defined(TARGET_ARM)' }
>> > +
>
> Yup, will do

Took me a few seconds to connect this to my "# Query valid SVE vector
length sets." line %-}

>> >  ##
>> >  # @CpuModelExpansionInfo:
>> >  #
[...]



Re: [Qemu-devel] [PATCH v8 3/6] libnvdimm: add dax_dev sync flag

2019-05-13 Thread Pankaj Gupta


> >
> >
> > Hi Dan,
> >
> > While testing device mapper with DAX, I faced a bug with the commit:
> >
> > commit ad428cdb525a97d15c0349fdc80f3d58befb50df
> > Author: Dan Williams 
> > Date:   Wed Feb 20 21:12:50 2019 -0800
> >
> > When I reverted the condition to old code[1] it worked for me. I
> > am thinking when we map two different devices (e.g with device mapper),
> > will
> > start & end pfn still point to same pgmap? Or there is something else which
> > I am missing here.
> >
> > Note: I tested only EXT4.
> >
> > [1]
> >
> > -   if (pgmap && pgmap->type == MEMORY_DEVICE_FS_DAX)
> > +   end_pgmap = get_dev_pagemap(pfn_t_to_pfn(end_pfn), NULL);
> > +   if (pgmap && pgmap == end_pgmap && pgmap->type ==
> > MEMORY_DEVICE_FS_DAX
> > +   && pfn_t_to_page(pfn)->pgmap == pgmap
> > +   && pfn_t_to_page(end_pfn)->pgmap == pgmap
> > +   && pfn_t_to_pfn(pfn) ==
> > PHYS_PFN(__pa(kaddr))
> > +   && pfn_t_to_pfn(end_pfn) ==
> > PHYS_PFN(__pa(end_kaddr)))
> 
> Ugh, yes, device-mapper continues to be an awkward fit for dax (or
> vice versa). We would either need a way to have a multi-level pfn to
> pagemap lookup for composite devices, or a way to discern that even
> though the pagemap is different that the result is still valid / not
> an indication that we have leaked into an unassociated address range.
> Perhaps a per-daxdev callback for ->dax_supported() so that
> device-mapper internals can be used for this validation.

Yes, Will look at it.

> 
> We need to get that fixed up, but I don't see it as a blocker /
> pre-requisite for virtio-pmem.

Agree. Will send virtio-pmem patch series.

Thank you,
Pankaj
> 
> 



[Qemu-devel] [PULL 20/31] tcg: Add support for integer absolute value

2019-05-13 Thread Richard Henderson
Remove a function of the same name from target/arm/.
Use a branchless implementation of abs gleaned from gcc.

Reviewed-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.h   |  5 +
 target/arm/translate.c | 10 --
 tcg/tcg-op.c   | 20 
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 472b73cb38..660fe205d0 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -335,6 +335,7 @@ void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 
arg2);
 void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
 void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
 void tcg_gen_umax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
+void tcg_gen_abs_i32(TCGv_i32, TCGv_i32);
 
 static inline void tcg_gen_discard_i32(TCGv_i32 arg)
 {
@@ -534,6 +535,7 @@ void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 
arg2);
 void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
 void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
 void tcg_gen_umax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
+void tcg_gen_abs_i64(TCGv_i64, TCGv_i64);
 
 #if TCG_TARGET_REG_BITS == 64
 static inline void tcg_gen_discard_i64(TCGv_i64 arg)
@@ -973,6 +975,7 @@ void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, 
TCGv_vec b);
 void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
 void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
 void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
+void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
 void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
 void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
 void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
@@ -1019,6 +1022,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg 
offset, TCGType t);
 #define tcg_gen_addi_tl tcg_gen_addi_i64
 #define tcg_gen_sub_tl tcg_gen_sub_i64
 #define tcg_gen_neg_tl tcg_gen_neg_i64
+#define tcg_gen_abs_tl tcg_gen_abs_i64
 #define tcg_gen_subfi_tl tcg_gen_subfi_i64
 #define tcg_gen_subi_tl tcg_gen_subi_i64
 #define tcg_gen_and_tl tcg_gen_and_i64
@@ -1131,6 +1135,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg 
offset, TCGType t);
 #define tcg_gen_addi_tl tcg_gen_addi_i32
 #define tcg_gen_sub_tl tcg_gen_sub_i32
 #define tcg_gen_neg_tl tcg_gen_neg_i32
+#define tcg_gen_abs_tl tcg_gen_abs_i32
 #define tcg_gen_subfi_tl tcg_gen_subfi_i32
 #define tcg_gen_subi_tl tcg_gen_subi_i32
 #define tcg_gen_and_tl tcg_gen_and_i32
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 35bd426a3d..b25781554f 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -604,16 +604,6 @@ static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 
t1)
 tcg_temp_free_i32(tmp1);
 }
 
-static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
-{
-TCGv_i32 c0 = tcg_const_i32(0);
-TCGv_i32 tmp = tcg_temp_new_i32();
-tcg_gen_neg_i32(tmp, src);
-tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
-tcg_temp_free_i32(c0);
-tcg_temp_free_i32(tmp);
-}
-
 static void shifter_out_im(TCGv_i32 var, int shift)
 {
 if (shift == 0) {
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index a00d1df37e..0ac291f1c4 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -1091,6 +1091,16 @@ void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 
b)
 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
 }
 
+void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
+{
+TCGv_i32 t = tcg_temp_new_i32();
+
+tcg_gen_sari_i32(t, a, 31);
+tcg_gen_xor_i32(ret, a, t);
+tcg_gen_sub_i32(ret, ret, t);
+tcg_temp_free_i32(t);
+}
+
 /* 64-bit ops */
 
 #if TCG_TARGET_REG_BITS == 32
@@ -2548,6 +2558,16 @@ void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 
b)
 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
 }
 
+void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_sari_i64(t, a, 63);
+tcg_gen_xor_i64(ret, a, t);
+tcg_gen_sub_i64(ret, ret, t);
+tcg_temp_free_i64(t);
+}
+
 /* Size changing operations.  */
 
 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
-- 
2.17.1




Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 4/6] target/ppc: Build rtas error log upon an MCE

2019-05-13 Thread Aravinda Prasad



On Tuesday 14 May 2019 10:10 AM, David Gibson wrote:
> On Tue, May 14, 2019 at 09:56:41AM +0530, Aravinda Prasad wrote:
>>
>>
>> On Tuesday 14 May 2019 05:38 AM, David Gibson wrote:
>>> On Mon, May 13, 2019 at 01:30:53PM +0200, Greg Kurz wrote:
 On Mon, 22 Apr 2019 12:33:26 +0530
 Aravinda Prasad  wrote:

> Upon a machine check exception (MCE) in a guest address space,
> KVM causes a guest exit to enable QEMU to build and pass the
> error to the guest in the PAPR defined rtas error log format.
>
> This patch builds the rtas error log, copies it to the rtas_addr
> and then invokes the guest registered machine check handler. The
> handler in the guest takes suitable action(s) depending on the type
> and criticality of the error. For example, if an error is
> unrecoverable memory corruption in an application inside the
> guest, then the guest kernel sends a SIGBUS to the application.
> For recoverable errors, the guest performs recovery actions and
> logs the error.
>
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c |4 +
>  hw/ppc/spapr_events.c  |  245 
> 
>  include/hw/ppc/spapr.h |4 +
>  3 files changed, 253 insertions(+)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 2779efe..ffd1715 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2918,6 +2918,10 @@ static void spapr_machine_init(MachineState 
> *machine)
>  error_report("Could not get size of LPAR rtas '%s'", filename);
>  exit(1);
>  }
> +
> +/* Resize blob to accommodate error log. */
> +spapr->rtas_size = spapr_get_rtas_size(spapr->rtas_size);
> +

 This is the only user for spapr_get_rtas_size(), which is trivial.
 I suggest you simply open-code it here.
>>>
>>> I agree.
>>
>> Sure.
>>
>>>
 But also, spapr->rtas_size is a guest visible thing, "rtas-size" prop in 
 the
 DT. Since existing machine types don't do that, I guess we should only use
 the new size if cap-fwnmi-mce=on for the sake of compatibility.
>>>
>>> Yes, that's a good idea.  Changing this is very unlikely to break a
>>> guest, but it's easy to be safe here so let's do it.
>>
>> I did it like that because the rtas_blob is allocated based on rtas_size
>> in spapr_machine_init(). During spapr_machine_init() it is not know if
>> the guest calls "ibm, nmi-register". So if we want to use the new size
>> only when cap_fwnmi=on, then we have to realloc the blob in "ibm,
>> nmi-register".
> 
> What?  Just always allocate the necessary space in
> spapr_machine_init() if cap_fwnmi=on, it'll be wasted if
> ibm,nmi-register is never called, but it's not that much space so we
> don't really care.

Yes, not that much space, and ibm,nmi-register is called when the Linux
kernel boots. I guess, even though other OSes might not call
ibm,nmi-register, they do not constitute significant QEMU on Power users.

So I think, I will keep the code as is.

> 

-- 
Regards,
Aravinda




Re: [Qemu-devel] How do we do user input bitmap properties?

2019-05-13 Thread Markus Armbruster
Andrew Jones  writes:

> On Thu, Apr 18, 2019 at 07:48:09PM +0200, Markus Armbruster wrote:
>> Daniel P. Berrangé  writes:
>> 
>> > On Thu, Apr 18, 2019 at 11:28:41AM +0200, Andrew Jones wrote:
>> >> Hi all,
>> >> 
>> >> First some background:
>> >> 
>> >> For the userspace side of AArch64 guest SVE support we need to
>> >> expose KVM's allowed vector lengths bitmap to the user and allow
>> >> the user to choose a subset of that bitmap. Since bitmaps are a
>> >> bit awkward to work with then we'll likely want to expose it as
>> >> an array of vector lengths instead. Also, assuming we want to
>> >> expose the lengths as number-of-quadwords (quadword == 128 bits
>> >> for AArch64 and vector lengths must be multiples of quadwords)
>> >> rather than number-of-bits, then an example array (which will
>> >> always be a sequence) might be
>> >> 
>> >>  [ 8, 16, 32 ]
>> >> 
>> >> The user may choose a subsequence, but only through truncation,
>> >> i.e. [ 8, 32 ] is not valid, but [ 8, 16 ] is.
>> >> 
>> >> Furthermore, different hosts may support different sequences
>> >> which have the same maximum. For example, if the above sequence
>> >> is for Host_A, then Host_B could be
>> >> 
>> >>  [ 8, 16, 24, 32 ]
>> >> 
>> >> The host must support all lengths in the sequence, which means
>> >> that while Host_A supports 32, since it doesn't support 24 and
>> >> we can only truncate sequences, we must use either [ 8 ] or
>> >> [ 8, 16 ] for a compatible sequence if we intend to migrate
>> >> between the hosts.
>> >> 
>> >> Now to the $SUBJECT question:
>> >> 
>> >> My feeling is that we should require the sequence to be
>> >> provided on the command line as a cpu property. Something
>> >> like
>> >> 
>> >>   -cpu host,sve-vl-list=8:16
>> >> 
>> >> (I chose ':' for the delimiter because ',' can't work, but
>> >> if there's a better choice, then that's fine by me.)
>> >> 
>> >> Afaict a property list like this will require a new parser,
>> 
>> We had 20+ of those when I last counted.  Among the more annoying
>> reasons CLI QAPIfication is hard[1].
>> 
>> >> which feels a bit funny since it seems we should already
>> >> have support for this type of thing somewhere in QEMU. So,
>> >> the question is: do we? I see we have array properties, but
>> >> I don't believe that works with the command line. Should we
>> >> only use QMP for this? We already want some QMP in order to
>> >> query the supported vector lengths. Maybe we should use QMP
>> >> to set the selection too? But then what about command line
>> >> support for developers? And if the property is on the command
>> >> line then we don't have to add it to the migration stream.
>> >
>> > You should be able to use arrays from the CLI with QemuOpts by repeating
>> > the same option name many times, though I can't say it is a very
>> > nice approach if you have many values to list as it gets very repetative.
>> 
>> Yes, this is one of the ways the current CLI does lists.  It's also one
>> of the more annoying reasons CLI QAPIfication is hard[2].
>> 
>> QemuOpts let the last param=value win the stupidest way that could
>> possibly work (I respect that): add to the front of the list, search it
>> front to back.
>> 
>> Then somebody discovered that if you search the list manually, you can
>> see them all, and abuse that to get a list-valued param.  I'm sure that
>> felt clever at the time.
>> 
>> Another way to do lists the funky list feature of string input and opts
>> visitor.  Yet another annoying reason CLI QAPIfication is hard[3].
>> 
>> We use the opts visitor's list feature for -numa node,cpus=...  Hmm,
>> looks like we even combine it with the "multiple param=value build up a
>> list" technique: -smp node,cpus=0-1,cpus=4-5 denotes [0,1,4,5].
>> 
>> > That's the curse of not having a good CLI syntax for non-scalar data in
>> > QemuOpts & why Markus believes we should switch to JSON for the CLI too
>> >
>> >  -cpu host,sve-vl=8,sve-vl=16
>> 
>> We actually have CLI syntax for non-scalar data: dotted keys.  Dotted
>> keys are syntactic sugar for JSON.  It looks friendlier than JSON for
>> simple cases, then gets uglier as things get more complex, and then it
>> falls apart: it can't quite express all of JSON.
>> 
>> Example: sve-vl.0=8,sve-vl.1=16
>> gets desugared into {"sve": [8, 16]}
>> if the QAPI schema has 'sve': ['int'].
>> 
>> The comment at the beginning of util/keyval.c explains it in more
>> detail.
>> 
>> It powers -blockdev and -display.  Both options accept either JSON or
>> dotted keys.  If the option argument starts with '{', it's JSON.
>> Management applications should stick to JSON.
>> 
>> 
>> [1] Towards a more expressive and introspectable QEMU command line
>> https://www.linux-kvm.org/images/f/f2/Armbru-qapi-cmdline_1.pdf
>> Slide 34 "Backward compatibility" item 1
>> 
>> [2] ibid, item 4
>> 
>> [3] ibid, item 3
>>
>
> Sorry I forgot to follow up to this earlier. I looked at the examples
> provided and saw they were all for independent 

[Qemu-devel] [PULL 17/31] tcg/aarch64: Support vector variable shift opcodes

2019-05-13 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  2 +-
 tcg/aarch64/tcg-target.opc.h |  2 ++
 tcg/aarch64/tcg-target.inc.c | 42 
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index ce2bb1f90b..f5640a229b 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -134,7 +134,7 @@ typedef enum {
 #define TCG_TARGET_HAS_neg_vec  1
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  0
-#define TCG_TARGET_HAS_shv_vec  0
+#define TCG_TARGET_HAS_shv_vec  1
 #define TCG_TARGET_HAS_cmp_vec  1
 #define TCG_TARGET_HAS_mul_vec  1
 #define TCG_TARGET_HAS_sat_vec  1
diff --git a/tcg/aarch64/tcg-target.opc.h b/tcg/aarch64/tcg-target.opc.h
index 4816a6c3d4..59e1d3f7f7 100644
--- a/tcg/aarch64/tcg-target.opc.h
+++ b/tcg/aarch64/tcg-target.opc.h
@@ -1,3 +1,5 @@
 /* Target-specific opcodes for host vector expansion.  These will be
emitted by tcg_expand_vec_op.  For those familiar with GCC internals,
consider these to be UNSPEC with names.  */
+
+DEF(aa64_sshl_vec, 1, 2, 0, IMPLVEC)
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 3dda66e777..df123c07f1 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -536,12 +536,14 @@ typedef enum {
 I3616_CMEQ  = 0x2e208c00,
 I3616_SMAX  = 0x0e206400,
 I3616_SMIN  = 0x0e206c00,
+I3616_SSHL  = 0x0e204400,
 I3616_SQADD = 0x0e200c00,
 I3616_SQSUB = 0x0e202c00,
 I3616_UMAX  = 0x2e206400,
 I3616_UMIN  = 0x2e206c00,
 I3616_UQADD = 0x2e200c00,
 I3616_UQSUB = 0x2e202c00,
+I3616_USHL  = 0x2e204400,
 
 /* AdvSIMD two-reg misc.  */
 I3617_CMGT0 = 0x0e208800,
@@ -2257,6 +2259,12 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_sari_vec:
 tcg_out_insn(s, 3614, SSHR, is_q, a0, a1, (16 << vece) - a2);
 break;
+case INDEX_op_shlv_vec:
+tcg_out_insn(s, 3616, USHL, is_q, vece, a0, a1, a2);
+break;
+case INDEX_op_aa64_sshl_vec:
+tcg_out_insn(s, 3616, SSHL, is_q, vece, a0, a1, a2);
+break;
 case INDEX_op_cmp_vec:
 {
 TCGCond cond = args[3];
@@ -2324,7 +2332,11 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_smin_vec:
 case INDEX_op_umax_vec:
 case INDEX_op_umin_vec:
+case INDEX_op_shlv_vec:
 return 1;
+case INDEX_op_shrv_vec:
+case INDEX_op_sarv_vec:
+return -1;
 case INDEX_op_mul_vec:
 return vece < MO_64;
 
@@ -2336,6 +2348,32 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg a0, ...)
 {
+va_list va;
+TCGv_vec v0, v1, v2, t1;
+
+va_start(va, a0);
+v0 = temp_tcgv_vec(arg_temp(a0));
+v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
+v2 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
+
+switch (opc) {
+case INDEX_op_shrv_vec:
+case INDEX_op_sarv_vec:
+/* Right shifts are negative left shifts for AArch64.  */
+t1 = tcg_temp_new_vec(type);
+tcg_gen_neg_vec(vece, t1, v2);
+opc = (opc == INDEX_op_shrv_vec
+   ? INDEX_op_shlv_vec : INDEX_op_aa64_sshl_vec);
+vec_gen_3(opc, type, vece, tcgv_vec_arg(v0),
+  tcgv_vec_arg(v1), tcgv_vec_arg(t1));
+tcg_temp_free_vec(t1);
+break;
+
+default:
+g_assert_not_reached();
+}
+
+va_end(va);
 }
 
 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
@@ -2517,6 +2555,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_smin_vec:
 case INDEX_op_umax_vec:
 case INDEX_op_umin_vec:
+case INDEX_op_shlv_vec:
+case INDEX_op_shrv_vec:
+case INDEX_op_sarv_vec:
+case INDEX_op_aa64_sshl_vec:
 return _w_w;
 case INDEX_op_not_vec:
 case INDEX_op_neg_vec:
-- 
2.17.1




Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 4/6] target/ppc: Build rtas error log upon an MCE

2019-05-13 Thread David Gibson
On Tue, May 14, 2019 at 09:56:41AM +0530, Aravinda Prasad wrote:
> 
> 
> On Tuesday 14 May 2019 05:38 AM, David Gibson wrote:
> > On Mon, May 13, 2019 at 01:30:53PM +0200, Greg Kurz wrote:
> >> On Mon, 22 Apr 2019 12:33:26 +0530
> >> Aravinda Prasad  wrote:
> >>
> >>> Upon a machine check exception (MCE) in a guest address space,
> >>> KVM causes a guest exit to enable QEMU to build and pass the
> >>> error to the guest in the PAPR defined rtas error log format.
> >>>
> >>> This patch builds the rtas error log, copies it to the rtas_addr
> >>> and then invokes the guest registered machine check handler. The
> >>> handler in the guest takes suitable action(s) depending on the type
> >>> and criticality of the error. For example, if an error is
> >>> unrecoverable memory corruption in an application inside the
> >>> guest, then the guest kernel sends a SIGBUS to the application.
> >>> For recoverable errors, the guest performs recovery actions and
> >>> logs the error.
> >>>
> >>> Signed-off-by: Aravinda Prasad 
> >>> ---
> >>>  hw/ppc/spapr.c |4 +
> >>>  hw/ppc/spapr_events.c  |  245 
> >>> 
> >>>  include/hw/ppc/spapr.h |4 +
> >>>  3 files changed, 253 insertions(+)
> >>>
> >>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >>> index 2779efe..ffd1715 100644
> >>> --- a/hw/ppc/spapr.c
> >>> +++ b/hw/ppc/spapr.c
> >>> @@ -2918,6 +2918,10 @@ static void spapr_machine_init(MachineState 
> >>> *machine)
> >>>  error_report("Could not get size of LPAR rtas '%s'", filename);
> >>>  exit(1);
> >>>  }
> >>> +
> >>> +/* Resize blob to accommodate error log. */
> >>> +spapr->rtas_size = spapr_get_rtas_size(spapr->rtas_size);
> >>> +
> >>
> >> This is the only user for spapr_get_rtas_size(), which is trivial.
> >> I suggest you simply open-code it here.
> > 
> > I agree.
> 
> Sure.
> 
> > 
> >> But also, spapr->rtas_size is a guest visible thing, "rtas-size" prop in 
> >> the
> >> DT. Since existing machine types don't do that, I guess we should only use
> >> the new size if cap-fwnmi-mce=on for the sake of compatibility.
> > 
> > Yes, that's a good idea.  Changing this is very unlikely to break a
> > guest, but it's easy to be safe here so let's do it.
> 
> I did it like that because the rtas_blob is allocated based on rtas_size
> in spapr_machine_init(). During spapr_machine_init() it is not know if
> the guest calls "ibm, nmi-register". So if we want to use the new size
> only when cap_fwnmi=on, then we have to realloc the blob in "ibm,
> nmi-register".

What?  Just always allocate the necessary space in
spapr_machine_init() if cap_fwnmi=on, it'll be wasted if
ibm,nmi-register is never called, but it's not that much space so we
don't really care.

-- 
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] [Qemu-ppc] [PATCH v8 5/6] ppc: spapr: Enable FWNMI capability

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 04:00:43PM +0530, Aravinda Prasad wrote:
> 
> 
> On Friday 10 May 2019 03:23 PM, David Gibson wrote:
> > On Fri, May 10, 2019 at 12:45:29PM +0530, Aravinda Prasad wrote:
> >>
> >>
> >> On Friday 10 May 2019 12:16 PM, David Gibson wrote:
> >>> On Mon, Apr 22, 2019 at 12:33:35PM +0530, Aravinda Prasad wrote:
>  Enable the KVM capability KVM_CAP_PPC_FWNMI so that
>  the KVM causes guest exit with NMI as exit reason
>  when it encounters a machine check exception on the
>  address belonging to a guest. Without this capability
>  enabled, KVM redirects machine check exceptions to
>  guest's 0x200 vector.
> 
>  This patch also deals with the case when a guest with
>  the KVM_CAP_PPC_FWNMI capability enabled is attempted
>  to migrate to a host that does not support this
>  capability.
> 
>  Signed-off-by: Aravinda Prasad 
>  ---
>   hw/ppc/spapr.c |1 +
>   hw/ppc/spapr_caps.c|   26 ++
>   hw/ppc/spapr_rtas.c|   14 ++
>   include/hw/ppc/spapr.h |4 +++-
>   target/ppc/kvm.c   |   14 ++
>   target/ppc/kvm_ppc.h   |6 ++
>   6 files changed, 64 insertions(+), 1 deletion(-)
> 
>  diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>  index ffd1715..44e09bb 100644
>  --- a/hw/ppc/spapr.c
>  +++ b/hw/ppc/spapr.c
>  @@ -4372,6 +4372,7 @@ static void spapr_machine_class_init(ObjectClass 
>  *oc, void *data)
>   smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
>   smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
>   smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
>  +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
>   spapr_caps_add_properties(smc, _abort);
>   smc->irq = _irq_xics;
>   smc->dr_phb_enabled = true;
>  diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
>  index edc5ed0..5b3af04 100644
>  --- a/hw/ppc/spapr_caps.c
>  +++ b/hw/ppc/spapr_caps.c
>  @@ -473,6 +473,22 @@ static void cap_ccf_assist_apply(SpaprMachineState 
>  *spapr, uint8_t val,
>   }
>   }
>   
>  +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
>  +Error **errp)
>  +{
>  +PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>  +
>  +if (!val) {
>  +return; /* Disabled by default */
>  +}
>  +
>  +if (kvm_enabled()) {
>  +if (kvmppc_fwnmi_enable(cpu)) {
>  +error_setg(errp, "Requested fwnmi capability not support by 
>  KVM");
>  +}
>  +}
>  +}
>  +
>   SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>   [SPAPR_CAP_HTM] = {
>   .name = "htm",
>  @@ -571,6 +587,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] 
>  = {
>   .type = "bool",
>   .apply = cap_ccf_assist_apply,
>   },
>  +[SPAPR_CAP_FWNMI_MCE] = {
>  +.name = "fwnmi-mce",
>  +.description = "Handle fwnmi machine check exceptions",
>  +.index = SPAPR_CAP_FWNMI_MCE,
>  +.get = spapr_cap_get_bool,
>  +.set = spapr_cap_set_bool,
>  +.type = "bool",
>  +.apply = cap_fwnmi_mce_apply,
>  +},
>   };
>   
>   static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
>  @@ -706,6 +731,7 @@ SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
>   SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
>   SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
>   SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
>  +SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI_MCE);
>   
>   void spapr_caps_init(SpaprMachineState *spapr)
>   {
>  diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>  index d3499f9..997cf19 100644
>  --- a/hw/ppc/spapr_rtas.c
>  +++ b/hw/ppc/spapr_rtas.c
>  @@ -49,6 +49,7 @@
>   #include "hw/ppc/fdt.h"
>   #include "target/ppc/mmu-hash64.h"
>   #include "target/ppc/mmu-book3s-v3.h"
>  +#include "kvm_ppc.h"
>   
>   static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState 
>  *spapr,
>  uint32_t token, uint32_t nargs,
>  @@ -354,6 +355,7 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> target_ulong args,
> uint32_t nret, target_ulong rets)
>   {
>  +int ret;
>   uint64_t rtas_addr = spapr_get_rtas_addr();
>   
>   if (!rtas_addr) {
>  @@ -361,6 +363,18 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>   return;
>   }
>   
>  +ret = 

Re: [Qemu-devel] [RFC v2 PATCH 3/3] spapr: Add Hcalls to support PAPR NVDIMM device

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 04:28:36AM -0500, Shivaprasad G Bhat wrote:
> This patch implements few of the necessary hcalls for the nvdimm support.
> 
> PAPR semantics is such that each NVDIMM device is comprising of multiple
> SCM(Storage Class Memory) blocks. The guest requests the hypervisor to bind
> each of the SCM blocks of the NVDIMM device using hcalls. There can be
> SCM block unbind requests in case of driver errors or unplug(not supported 
> now)
> use cases. The NVDIMM label read/writes are done through hcalls.
> 
> Since each virtual NVDIMM device is divided into multiple SCM blocks, the 
> bind,
> unbind, and queries using hcalls on those blocks can come independently. This
> doesn't fit well into the qemu device semantics, where the map/unmap are done
> at the (whole)device/object level granularity. The patch doesnt actually
> bind/unbind on hcalls but let it happen at the object_add/del phase itself
> instead.
> 
> The guest kernel makes bind/unbind requests for the virtual NVDIMM device at 
> the
> region level granularity. Without interleaving, each virtual NVDIMM device is
> presented as separate region. There is no way to configure the virtual NVDIMM
> interleaving for the guests today. So, there is no way a partial bind/unbind
> request can come for the vNVDIMM in a hcall for a subset of SCM blocks of a
> virtual NVDIMM. Hence it is safe to do bind/unbind everything during the
> object_add/del.
> 
> Signed-off-by: Shivaprasad G Bhat 
> ---
>  hw/ppc/spapr_hcall.c   |  202 
> 
>  include/hw/ppc/spapr.h |7 +-
>  2 files changed, 208 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 6c16d2b120..b6e7d04dcf 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -3,11 +3,13 @@
>  #include "sysemu/hw_accel.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/log.h"
> +#include "qemu/range.h"
>  #include "qemu/error-report.h"
>  #include "cpu.h"
>  #include "exec/exec-all.h"
>  #include "helper_regs.h"
>  #include "hw/ppc/spapr.h"
> +#include "hw/ppc/spapr_drc.h"
>  #include "hw/ppc/spapr_cpu_core.h"
>  #include "mmu-hash64.h"
>  #include "cpu-models.h"
> @@ -16,6 +18,7 @@
>  #include "hw/ppc/spapr_ovec.h"
>  #include "mmu-book3s-v3.h"
>  #include "hw/mem/memory-device.h"
> +#include "hw/mem/nvdimm.h"
>  
>  static bool has_spr(PowerPCCPU *cpu, int spr)
>  {
> @@ -1795,6 +1798,199 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  return H_SUCCESS;
>  }
>  
> +static target_ulong h_scm_read_metadata(PowerPCCPU *cpu,
> +SpaprMachineState *spapr,
> +target_ulong opcode,
> +target_ulong *args)
> +{
> +uint32_t drc_index = args[0];
> +uint64_t offset = args[1];
> +uint64_t numBytesToRead = args[2];
> +SpaprDrc *drc = spapr_drc_by_index(drc_index);
> +NVDIMMDevice *nvdimm = NULL;
> +NVDIMMClass *ddc = NULL;
> +
> +if (drc && spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
> +return H_PARAMETER;
> +}
> +
> +if (numBytesToRead != 1 && numBytesToRead != 2 &&
> +numBytesToRead != 4 && numBytesToRead != 8) {
> +return H_P3;
> +}
> +
> +nvdimm = NVDIMM(drc->dev);
> +if ((offset + numBytesToRead < offset) ||
> +(nvdimm->label_size < numBytesToRead + offset)) {
> +return H_P2;
> +}
> +
> +ddc = NVDIMM_GET_CLASS(nvdimm);
> +ddc->read_label_data(nvdimm, [0], numBytesToRead, offset);

I'm pretty sure this will need some sort of byteswap.  args[0] is
effectively in host native order (since it maps to a register, not
memory).  But the guest will have to assume some byteorder (BE, I'm
guessing, because PAPR) in order to map that register to an in-memory
byteorder.  So, you'll need to compensate for that here.

> +return H_SUCCESS;
> +}
> +
> +
> +static target_ulong h_scm_write_metadata(PowerPCCPU *cpu,
> + SpaprMachineState *spapr,
> + target_ulong opcode,
> + target_ulong *args)
> +{
> +uint32_t drc_index = args[0];
> +uint64_t offset = args[1];
> +uint64_t data = args[2];
> +int8_t numBytesToWrite = args[3];
> +SpaprDrc *drc = spapr_drc_by_index(drc_index);
> +NVDIMMDevice *nvdimm = NULL;
> +DeviceState *dev = NULL;
> +NVDIMMClass *ddc = NULL;
> +
> +if (drc && spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
> +return H_PARAMETER;
> +}
> +
> +if (numBytesToWrite != 1 && numBytesToWrite != 2 &&
> +numBytesToWrite != 4 && numBytesToWrite != 8) {
> +return H_P4;
> +}
> +
> +dev = drc->dev;
> +nvdimm = NVDIMM(dev);
> +if ((nvdimm->label_size < numBytesToWrite + offset) ||
> +(offset + numBytesToWrite < offset)) {
> +

[Qemu-devel] [PULL 18/31] tcg: Add gvec expanders for vector shift by scalar

2019-05-13 Thread Richard Henderson
Allow expansion either via shift by scalar or by replicating
the scalar for shift by vector.

Signed-off-by: Richard Henderson 
---
v3: Use a private structure for do_gvec_shifts.
---
 tcg/tcg-op-gvec.h |   7 ++
 tcg/tcg-op.h  |   4 +
 tcg/tcg-op-gvec.c | 214 ++
 tcg/tcg-op-vec.c  |  54 
 4 files changed, 279 insertions(+)

diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index 84a6247b16..6ee98f3378 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -318,6 +318,13 @@ void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
 
+void tcg_gen_gvec_shls(unsigned vece, uint32_t dofs, uint32_t aofs,
+   TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_shrs(unsigned vece, uint32_t dofs, uint32_t aofs,
+   TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_sars(unsigned vece, uint32_t dofs, uint32_t aofs,
+   TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
+
 /*
  * Perform vector shift by vector element, modulo the element size.
  * E.g.  D[i] = A[i] << (B[i] % (8 << vece)).
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 833c6330b5..472b73cb38 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -986,6 +986,10 @@ void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec 
a, int64_t i);
 void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
 void tcg_gen_sari_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
 
+void tcg_gen_shls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
+void tcg_gen_shrs_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
+void tcg_gen_sars_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
+
 void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
 void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
 void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 061ef329f1..c69c7960b8 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -2555,6 +2555,220 @@ void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 }
 }
 
+/*
+ * Specialized generation vector shifts by a non-constant scalar.
+ */
+
+typedef struct {
+void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32);
+void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64);
+void (*fniv_s)(unsigned, TCGv_vec, TCGv_vec, TCGv_i32);
+void (*fniv_v)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
+gen_helper_gvec_2 *fno[4];
+TCGOpcode s_list[2];
+TCGOpcode v_list[2];
+} GVecGen2sh;
+
+static void expand_2sh_vec(unsigned vece, uint32_t dofs, uint32_t aofs,
+   uint32_t oprsz, uint32_t tysz, TCGType type,
+   TCGv_i32 shift,
+   void (*fni)(unsigned, TCGv_vec, TCGv_vec, TCGv_i32))
+{
+TCGv_vec t0 = tcg_temp_new_vec(type);
+uint32_t i;
+
+for (i = 0; i < oprsz; i += tysz) {
+tcg_gen_ld_vec(t0, cpu_env, aofs + i);
+fni(vece, t0, t0, shift);
+tcg_gen_st_vec(t0, cpu_env, dofs + i);
+}
+tcg_temp_free_vec(t0);
+}
+
+static void
+do_gvec_shifts(unsigned vece, uint32_t dofs, uint32_t aofs, TCGv_i32 shift,
+   uint32_t oprsz, uint32_t maxsz, const GVecGen2sh *g)
+{
+TCGType type;
+uint32_t some;
+
+check_size_align(oprsz, maxsz, dofs | aofs);
+check_overlap_2(dofs, aofs, maxsz);
+
+/* If the backend has a scalar expansion, great.  */
+type = choose_vector_type(g->s_list, vece, oprsz, vece == MO_64);
+if (type) {
+const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL);
+switch (type) {
+case TCG_TYPE_V256:
+some = QEMU_ALIGN_DOWN(oprsz, 32);
+expand_2sh_vec(vece, dofs, aofs, some, 32,
+   TCG_TYPE_V256, shift, g->fniv_s);
+if (some == oprsz) {
+break;
+}
+dofs += some;
+aofs += some;
+oprsz -= some;
+maxsz -= some;
+/* fallthru */
+case TCG_TYPE_V128:
+expand_2sh_vec(vece, dofs, aofs, oprsz, 16,
+   TCG_TYPE_V128, shift, g->fniv_s);
+break;
+case TCG_TYPE_V64:
+expand_2sh_vec(vece, dofs, aofs, oprsz, 8,
+   TCG_TYPE_V64, shift, g->fniv_s);
+break;
+default:
+g_assert_not_reached();
+}
+tcg_swap_vecop_list(hold_list);
+goto clear_tail;
+}
+
+/* If the backend supports variable vector shifts, also cool.  */
+type = choose_vector_type(g->v_list, vece, oprsz, vece == MO_64);
+if (type) {
+const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL);
+TCGv_vec v_shift = 

[Qemu-devel] [PATCH 0/2] target/arm: Minor bit field improvements

2019-05-13 Thread Richard Henderson
The tcg extract2 patch on which this depended is now in master.


r~


Richard Henderson (2):
  target/arm: Use extract2 for EXTR
  target/arm: Simplify BFXIL expansion

 target/arm/translate-a64.c | 44 --
 1 file changed, 23 insertions(+), 21 deletions(-)

-- 
2.17.1




Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 4/6] target/ppc: Build rtas error log upon an MCE

2019-05-13 Thread Aravinda Prasad



On Tuesday 14 May 2019 05:38 AM, David Gibson wrote:
> On Mon, May 13, 2019 at 01:30:53PM +0200, Greg Kurz wrote:
>> On Mon, 22 Apr 2019 12:33:26 +0530
>> Aravinda Prasad  wrote:
>>
>>> Upon a machine check exception (MCE) in a guest address space,
>>> KVM causes a guest exit to enable QEMU to build and pass the
>>> error to the guest in the PAPR defined rtas error log format.
>>>
>>> This patch builds the rtas error log, copies it to the rtas_addr
>>> and then invokes the guest registered machine check handler. The
>>> handler in the guest takes suitable action(s) depending on the type
>>> and criticality of the error. For example, if an error is
>>> unrecoverable memory corruption in an application inside the
>>> guest, then the guest kernel sends a SIGBUS to the application.
>>> For recoverable errors, the guest performs recovery actions and
>>> logs the error.
>>>
>>> Signed-off-by: Aravinda Prasad 
>>> ---
>>>  hw/ppc/spapr.c |4 +
>>>  hw/ppc/spapr_events.c  |  245 
>>> 
>>>  include/hw/ppc/spapr.h |4 +
>>>  3 files changed, 253 insertions(+)
>>>
>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>> index 2779efe..ffd1715 100644
>>> --- a/hw/ppc/spapr.c
>>> +++ b/hw/ppc/spapr.c
>>> @@ -2918,6 +2918,10 @@ static void spapr_machine_init(MachineState *machine)
>>>  error_report("Could not get size of LPAR rtas '%s'", filename);
>>>  exit(1);
>>>  }
>>> +
>>> +/* Resize blob to accommodate error log. */
>>> +spapr->rtas_size = spapr_get_rtas_size(spapr->rtas_size);
>>> +
>>
>> This is the only user for spapr_get_rtas_size(), which is trivial.
>> I suggest you simply open-code it here.
> 
> I agree.

Sure.

> 
>> But also, spapr->rtas_size is a guest visible thing, "rtas-size" prop in the
>> DT. Since existing machine types don't do that, I guess we should only use
>> the new size if cap-fwnmi-mce=on for the sake of compatibility.
> 
> Yes, that's a good idea.  Changing this is very unlikely to break a
> guest, but it's easy to be safe here so let's do it.

I did it like that because the rtas_blob is allocated based on rtas_size
in spapr_machine_init(). During spapr_machine_init() it is not know if
the guest calls "ibm, nmi-register". So if we want to use the new size
only when cap_fwnmi=on, then we have to realloc the blob in "ibm,
nmi-register".


> 
>>
>>>  spapr->rtas_blob = g_malloc(spapr->rtas_size);
>>>  if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) 
>>> {
>>>  error_report("Could not load LPAR rtas '%s'", filename);
>>> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
>>> index 9922a23..4032db0 100644
>>> --- a/hw/ppc/spapr_events.c
>>> +++ b/hw/ppc/spapr_events.c
>>> @@ -212,6 +212,106 @@ struct hp_extended_log {
>>>  struct rtas_event_log_v6_hp hp;
>>>  } QEMU_PACKED;
>>>  
>>> +struct rtas_event_log_v6_mc {
>>
>> Even if the rest of the code in this file seems to ignore CODING_STYLE,
>> maybe it's time to start using CamelCase.
>>
>> David ?
> 
> Out of scope here, I think.
> 
>>> +#define RTAS_LOG_V6_SECTION_ID_MC   0x4D43 /* MC */
>>> +struct rtas_event_log_v6_section_header hdr;
>>> +uint32_t fru_id;
>>> +uint32_t proc_id;
>>> +uint8_t error_type;
>>> +#define RTAS_LOG_V6_MC_TYPE_UE   0
>>> +#define RTAS_LOG_V6_MC_TYPE_SLB  1
>>> +#define RTAS_LOG_V6_MC_TYPE_ERAT 2
>>> +#define RTAS_LOG_V6_MC_TYPE_TLB  4
>>> +#define RTAS_LOG_V6_MC_TYPE_D_CACHE  5
>>> +#define RTAS_LOG_V6_MC_TYPE_I_CACHE  7
>>> +uint8_t sub_err_type;
>>> +#define RTAS_LOG_V6_MC_UE_INDETERMINATE  0
>>> +#define RTAS_LOG_V6_MC_UE_IFETCH 1
>>> +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_IFETCH 2
>>> +#define RTAS_LOG_V6_MC_UE_LOAD_STORE 3
>>> +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_LOAD_STORE 4
>>> +#define RTAS_LOG_V6_MC_SLB_PARITY0
>>> +#define RTAS_LOG_V6_MC_SLB_MULTIHIT  1
>>> +#define RTAS_LOG_V6_MC_SLB_INDETERMINATE 2
>>> +#define RTAS_LOG_V6_MC_ERAT_PARITY   1
>>> +#define RTAS_LOG_V6_MC_ERAT_MULTIHIT 2
>>> +#define RTAS_LOG_V6_MC_ERAT_INDETERMINATE3
>>> +#define RTAS_LOG_V6_MC_TLB_PARITY1
>>> +#define RTAS_LOG_V6_MC_TLB_MULTIHIT  2
>>> +#define RTAS_LOG_V6_MC_TLB_INDETERMINATE 3
>>> +uint8_t reserved_1[6];
>>> +uint64_t effective_address;
>>> +uint64_t logical_address;
>>> +} QEMU_PACKED;
>>> +
>>> +struct mc_extended_log {
>>> +struct rtas_event_log_v6 v6hdr;
>>> +struct rtas_event_log_v6_mc mc;
>>> +} QEMU_PACKED;
>>> +
>>> +struct MC_ierror_table {
>>> +unsigned long srr1_mask;
>>> +unsigned long srr1_value;
>>> +bool 

[Qemu-devel] [PATCH] kbd-state: fix autorepeat handling

2019-05-13 Thread Gerd Hoffmann
When allowing multiple down-events in a row (key autorepeat) we can't
use change_bit() any more to update the state, because autorepeat events
don't change the key state.  We have to explicitly use set_bit() and
clear_bit() instead.

Cc: qemu-sta...@nongnu.org
Fixes: 35921860156e kbd-state: don't block auto-repeat events
Buglink: https://bugs.launchpad.net/qemu/+bug/1828272
Signed-off-by: Gerd Hoffmann 
---
 ui/kbd-state.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ui/kbd-state.c b/ui/kbd-state.c
index f3ab2d7a665d..1668d17ddabc 100644
--- a/ui/kbd-state.c
+++ b/ui/kbd-state.c
@@ -59,7 +59,11 @@ void qkbd_state_key_event(QKbdState *kbd, QKeyCode qcode, 
bool down)
 }
 
 /* update key and modifier state */
-change_bit(qcode, kbd->keys);
+if (down) {
+set_bit(qcode, kbd->keys);
+} else {
+clear_bit(qcode, kbd->keys);
+}
 switch (qcode) {
 case Q_KEY_CODE_SHIFT:
 case Q_KEY_CODE_SHIFT_R:
-- 
2.18.1




[Qemu-devel] [PULL 26/31] target/ppc: Use tcg_gen_abs_i32

2019-05-13 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20190423102145.14812-2-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/ppc/translate/spe-impl.inc.c | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/target/ppc/translate/spe-impl.inc.c 
b/target/ppc/translate/spe-impl.inc.c
index 7ab0a29b5f..36b4d5654d 100644
--- a/target/ppc/translate/spe-impl.inc.c
+++ b/target/ppc/translate/spe-impl.inc.c
@@ -126,19 +126,7 @@ static inline void gen_##name(DisasContext *ctx)   
   \
 tcg_temp_free_i32(t0);\
 }
 
-static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
-{
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-
-tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
-tcg_gen_neg_i32(ret, arg1);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_mov_i32(ret, arg1);
-gen_set_label(l2);
-}
-GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
+GEN_SPEOP_ARITH1(evabs, tcg_gen_abs_i32);
 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
-- 
2.17.1




[Qemu-devel] [PULL 11/31] tcg: Add tcg_out_dupm_vec to the backend interface

2019-05-13 Thread Richard Henderson
Currently stubbed out in all backends that support vectors.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c |  6 ++
 tcg/i386/tcg-target.inc.c|  7 +++
 tcg/tcg.c| 19 ++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 3cefdd1e43..4a3cfa778a 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -822,6 +822,12 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, 
unsigned vece,
 return true;
 }
 
+static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg r, TCGReg base, intptr_t offset)
+{
+return false;
+}
+
 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
  tcg_target_long value)
 {
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 3c8229d413..f04933bc19 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -891,6 +891,13 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, 
unsigned vece,
 return true;
 }
 
+static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg r, TCGReg base, intptr_t offset)
+{
+return false;
+}
+
+
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
  TCGReg ret, tcg_target_long arg)
 {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2b715bf099..b9945794c4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -111,6 +111,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const 
TCGArg *args,
 #if TCG_TARGET_MAYBE_vec
 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
 TCGReg dst, TCGReg src);
+static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg dst, TCGReg base, intptr_t offset);
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
  TCGReg dst, tcg_target_long arg);
 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
@@ -122,6 +124,11 @@ static inline bool tcg_out_dup_vec(TCGContext *s, TCGType 
type, unsigned vece,
 {
 g_assert_not_reached();
 }
+static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
+TCGReg dst, TCGReg base, intptr_t offset)
+{
+g_assert_not_reached();
+}
 static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 TCGReg dst, tcg_target_long arg)
 {
@@ -3422,6 +3429,7 @@ static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp 
*op)
 TCGRegSet dup_out_regs, dup_in_regs;
 TCGTemp *its, *ots;
 TCGType itype, vtype;
+intptr_t endian_fixup;
 unsigned vece;
 bool ok;
 
@@ -3491,7 +3499,16 @@ static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp 
*op)
 /* fall through */
 
 case TEMP_VAL_MEM:
-/* TODO: dup from memory */
+#ifdef HOST_WORDS_BIGENDIAN
+endian_fixup = itype == TCG_TYPE_I32 ? 4 : 8;
+endian_fixup -= 1 << vece;
+#else
+endian_fixup = 0;
+#endif
+if (tcg_out_dupm_vec(s, vtype, vece, ots->reg, its->mem_base->reg,
+ its->mem_offset + endian_fixup)) {
+goto done;
+}
 tcg_out_ld(s, itype, ots->reg, its->mem_base->reg, its->mem_offset);
 break;
 
-- 
2.17.1




[Qemu-devel] [PATCH 2/2] target/arm: Simplify BFXIL expansion

2019-05-13 Thread Richard Henderson
The mask implied by the extract is redundant with the one
implied by the deposit.  Also, fix spelling of BFXIL.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c4bee74ce5..472d898096 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4043,8 +4043,8 @@ static void disas_bitfield(DisasContext *s, uint32_t insn)
 tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
 return;
 }
-/* opc == 1, BXFIL fall through to deposit */
-tcg_gen_extract_i64(tcg_tmp, tcg_tmp, ri, len);
+/* opc == 1, BFXIL fall through to deposit */
+tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
 pos = 0;
 } else {
 /* Handle the ri > si case with a deposit
@@ -4062,7 +4062,7 @@ static void disas_bitfield(DisasContext *s, uint32_t insn)
 len = ri;
 }
 
-if (opc == 1) { /* BFM, BXFIL */
+if (opc == 1) { /* BFM, BFXIL */
 tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
 } else {
 /* SBFM or UBFM: We start with zero, and we haven't modified
-- 
2.17.1




Re: [Qemu-devel] [PATCH v3 38/39] tcg/arm: Use LDRD to load tlb mask+table

2019-05-13 Thread Alistair Francis
On Sat, May 11, 2019 at 12:13 PM Richard Henderson
 wrote:
>
> On 5/10/19 2:08 PM, Alistair Francis wrote:
> >> +if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
> >> +tcg_out_ldrd_8(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
> ...
> >
> > This is complex and I'm probably misunderstanding something but isn't
> > it possible for TCG_REG_R3 to not be set if use_armv6_instructions is
> > true and TARGET_LONG_BITS is 64?
>
> No, the LDRD instruction loads data into both R2 and R2+1 = R3.

Ah ok. This looks fine to me then but I don't think I fully grasp it
enough to Ack it.

Alistair

>
>
> r~



[Qemu-devel] [PATCH 1/2] target/arm: Use extract2 for EXTR

2019-05-13 Thread Richard Henderson
This is, after all, how we implement extract2 in tcg/aarch64.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 38 --
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 9dcc5ff3a3..c4bee74ce5 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4114,25 +4114,27 @@ static void disas_extract(DisasContext *s, uint32_t 
insn)
 } else {
 tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
 }
-} else if (rm == rn) { /* ROR */
-tcg_rm = cpu_reg(s, rm);
-if (sf) {
-tcg_gen_rotri_i64(tcg_rd, tcg_rm, imm);
-} else {
-TCGv_i32 tmp = tcg_temp_new_i32();
-tcg_gen_extrl_i64_i32(tmp, tcg_rm);
-tcg_gen_rotri_i32(tmp, tmp, imm);
-tcg_gen_extu_i32_i64(tcg_rd, tmp);
-tcg_temp_free_i32(tmp);
-}
 } else {
-tcg_rm = read_cpu_reg(s, rm, sf);
-tcg_rn = read_cpu_reg(s, rn, sf);
-tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
-tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
-tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
-if (!sf) {
-tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
+tcg_rm = cpu_reg(s, rm);
+tcg_rn = cpu_reg(s, rn);
+
+if (sf) {
+/* Specialization to ROR happens in EXTRACT2.  */
+tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, imm);
+} else {
+TCGv_i32 t0 = tcg_temp_new_i32();
+
+tcg_gen_extrl_i64_i32(t0, tcg_rm);
+if (rm == rn) {
+tcg_gen_rotri_i32(t0, t0, imm);
+} else {
+TCGv_i32 t1 = tcg_temp_new_i32();
+tcg_gen_extrl_i64_i32(t1, tcg_rn);
+tcg_gen_extract2_i32(t0, t0, t1, imm);
+tcg_temp_free_i32(t1);
+}
+tcg_gen_extu_i32_i64(tcg_rd, t0);
+tcg_temp_free_i32(t0);
 }
 }
 }
-- 
2.17.1




Re: [Qemu-devel] [RFC v2 PATCH 2/3] spapr: Add NVDIMM device support

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 04:28:02AM -0500, Shivaprasad G Bhat wrote:
> Add support for NVDIMM devices for sPAPR. Piggyback on existing nvdimm
> device interface in QEMU to support virtual NVDIMM devices for Power (May have
> to re-look at this later).  Create the required DT entries for the
> device (some entries have dummy values right now).
> 
> The patch creates the required DT node and sends a hotplug
> interrupt to the guest. Guest is expected to undertake the normal
> DR resource add path in response and start issuing PAPR SCM hcalls.
> 
> This is how it can be used ..
> Add nvdimm=on to the qemu machine argument.
> Ex : -machine pseries,nvdimm=on
> For coldplug, the device to be added in qemu command line as shown below
> -object 
> memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm0,share=yes,size=1073872896
> -device 
> nvdimm,label-size=128k,uuid=75a3cdd7-6a2f-4791-8d15-fe0a920e8e9e,memdev=memnvdimm0,id=nvdimm0,slot=0
> 
> For hotplug, the device to be added from monitor as below
> object_add 
> memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm0,share=yes,size=1073872896
> device_add 
> nvdimm,label-size=128k,uuid=75a3cdd7-6a2f-4791-8d15-fe0a920e8e9e,memdev=memnvdimm0,id=nvdimm0,slot=0
> 
> Signed-off-by: Shivaprasad G Bhat 
> Signed-off-by: Bharata B Rao 
>[Early implementation]
> ---
> ---
>  default-configs/ppc64-softmmu.mak |1 
>  hw/mem/Kconfig|2 
>  hw/mem/nvdimm.c   |   43 
>  hw/ppc/spapr.c|  202 
> +++--
>  hw/ppc/spapr_drc.c|   18 +++
>  hw/ppc/spapr_events.c |4 +
>  include/hw/mem/nvdimm.h   |6 +
>  include/hw/ppc/spapr.h|   12 ++
>  include/hw/ppc/spapr_drc.h|9 ++
>  9 files changed, 286 insertions(+), 11 deletions(-)
> 
> diff --git a/default-configs/ppc64-softmmu.mak 
> b/default-configs/ppc64-softmmu.mak
> index cca52665d9..ae0841fa3a 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -8,3 +8,4 @@ CONFIG_POWERNV=y
>  
>  # For pSeries
>  CONFIG_PSERIES=y
> +CONFIG_NVDIMM=y
> diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
> index 620fd4cb59..2ad052a536 100644
> --- a/hw/mem/Kconfig
> +++ b/hw/mem/Kconfig
> @@ -8,4 +8,4 @@ config MEM_DEVICE
>  config NVDIMM
>  bool
>  default y
> -depends on PC
> +depends on (PC || PSERIES)
> diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
> index f221ec7a9a..deaeb5 100644
> --- a/hw/mem/nvdimm.c
> +++ b/hw/mem/nvdimm.c
> @@ -93,11 +93,54 @@ out:
>  error_propagate(errp, local_err);
>  }
>  
> +static void nvdimm_get_uuid(Object *obj, Visitor *v, const char *name,
> +  void *opaque, Error **errp)
> +{
> +NVDIMMDevice *nvdimm = NVDIMM(obj);
> +char *value = NULL;
> +
> +value = qemu_uuid_unparse_strdup(>uuid);
> +
> +visit_type_str(v, name, , errp);
> +}
> +
> +
> +static void nvdimm_set_uuid(Object *obj, Visitor *v, const char *name,
> +  void *opaque, Error **errp)
> +{
> +NVDIMMDevice *nvdimm = NVDIMM(obj);
> +Error *local_err = NULL;
> +char *value;
> +
> +visit_type_str(v, name, , _err);
> +if (local_err) {
> +goto out;
> +}
> +
> +if (strcmp(value, "") == 0) {
> +error_setg(_err, "Property '%s.%s' %s is required"
> +   " at least 0x%lx", object_get_typename(obj),
> +   name, value, MIN_NAMESPACE_LABEL_SIZE);
> +goto out;
> +}
> +
> +if (qemu_uuid_parse(value, >uuid) != 0) {
> +error_setg(errp, "Invalid UUID");
> +return;
> +}
> +out:
> +error_propagate(errp, local_err);
> +}
> +
> +
>  static void nvdimm_init(Object *obj)
>  {
>  object_property_add(obj, NVDIMM_LABEL_SIZE_PROP, "int",
>  nvdimm_get_label_size, nvdimm_set_label_size, NULL,
>  NULL, NULL);
> +
> +object_property_add(obj, NVDIMM_UUID_PROP, "QemuUUID", nvdimm_get_uuid,
> +nvdimm_set_uuid, NULL, NULL, NULL);
>  }
>  
>  static void nvdimm_finalize(Object *obj)
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 2ef3ce4362..b6951577e7 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -74,6 +74,7 @@
>  #include "qemu/cutils.h"
>  #include "hw/ppc/spapr_cpu_core.h"
>  #include "hw/mem/memory-device.h"
> +#include "hw/mem/nvdimm.h"
>  
>  #include 
>  
> @@ -699,6 +700,7 @@ static int spapr_populate_drmem_v2(SpaprMachineState 
> *spapr, void *fdt,
>  uint8_t *int_buf, *cur_index;
>  int ret;
>  uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
> +uint64_t scm_block_size = SPAPR_MINIMUM_SCM_BLOCK_SIZE;
>  uint64_t addr, cur_addr, size;
>  uint32_t nr_boot_lmbs = (machine->device_memory->base / lmb_size);
>  uint64_t mem_end = machine->device_memory->base +
> @@ -735,12 +737,20 @@ static int 

Re: [Qemu-devel] [PATCH v11 00/12] Add RX archtecture support

2019-05-13 Thread Yoshinori Sato
Oh. Sorry.

I fount one other problem.
I will fix it and re-send later.

2019年5月14日(火) 2:26 Philippe Mathieu-Daudé :
>
> Hi Yoshinori,
>
> On 5/13/19 7:25 AM, Yoshinori Sato wrote:
> > Hello.
> > This patch series is added Renesas RX target emulation.
> >
> > Fixed build errors and cleaned up the code.
> >
> > My git repository is bellow.
> > git://git.pf.osdn.net/gitroot/y/ys/ysato/qemu.git tags/rx-20190513
>
> This tag isn't exactly the same as the series you posted, some patches
> are ordered differently, leading to this failure at commit fc564da941a
> (Add rx-softmmu) of your tag:
>
> ((fc564da941a...))$ make -C rx-softmmu hw/intc/rx_icu.o
>   CC  hw/intc/rx_icu.o
> hw/intc/rx_icu.c:35:9: error: expected ‘)’ before numeric constant
>  REG8(IR, 0)
>  ^~
>  )
> ...
> hw/intc/rx_icu.c: In function ‘icu_read’:
> hw/intc/rx_icu.c:174:18: error: ‘A_FIR’ undeclared (first use in this
> function); did you mean ‘A_FPSW’?
>  if ((addr != A_FIR && size != 1) ||
>   ^
>   A_FPSW
> hw/intc/rx_icu.c:174:18: note: each undeclared identifier is reported
> only once for each function it appears in
> hw/intc/rx_icu.c:181:10: error: ‘A_IR’ undeclared (first use in this
> function); did you mean ‘DIR’?
>  case A_IR ... A_IR + 0xff:
>   ^~~~
>   DIR
> ...
> hw/intc/rx_icu.c:199:44: error: ‘R_IRQCR_IRQMD_SHIFT’ undeclared (first
> use in this function); did you mean ‘R_IRQCR_IRQMD_MASK’?
>  return icu->src[64 + reg].sense << R_IRQCR_IRQMD_SHIFT;
> ^~~
> R_IRQCR_IRQMD_MASK
>
> This is because the commit "hw/registerfields.h" is added after.
> I see this series seems ordered correctly, so I'll keep testing.
>
> >
> > Testing binaries bellow.
> > u-boot
> > Download - https://osdn.net/users/ysato/pf/qemu/dl/u-boot.bin.gz
> >
> > starting
> > $ gzip -d u-boot.bin.gz
> > $ qemu-system-rx -bios u-boot.bin
> >
> > linux and pico-root (only sash)
> > Download - https://osdn.net/users/ysato/pf/qemu/dl/zImage (kernel)
> >https://osdn.net/users/ysato/pf/qemu/dl/rx-qemu.dtb (DeviceTree)
> >
> > starting
> > $ qemu-system-rx -kernel zImage -dtb rx-qemu.dtb -append "earlycon"
> >
> > Changes for v10.
> > - Fix build error for 32bit system.
> > - Use "object_initialize_child" in create device instance.
> > - Remove unused headers.
> > - Avoid some magic number.
> > - Clean up Kconfig symbols.
> >
> > Yoshinori Sato (12):
> >   target/rx: TCG translation
> >   target/rx: TCG helper
> >   target/rx: CPU definition
> >   target/rx: RX disassembler
> >   hw/intc: RX62N interrupt controller (ICUa)
> >   hw/timer: RX62N internal timer modules
> >   hw/char: RX62N serial communication interface (SCI)
> >   hw/rx: RX Target hardware definition
> >   hw/registerfields.h: Add 8bit and 16bit register macros.
> >   qemu/bitops.h: Add extract8 and extract16
> >   Add rx-softmmu
> >   MAINTAINERS: Add RX
> >
> >  MAINTAINERS|   19 +
> >  arch_init.c|2 +
> >  configure  |8 +
> >  default-configs/rx-softmmu.mak |3 +
> >  hw/Kconfig |1 +
> >  hw/char/Kconfig|3 +
> >  hw/char/Makefile.objs  |1 +
> >  hw/char/renesas_sci.c  |  340 ++
> >  hw/intc/Kconfig|3 +
> >  hw/intc/Makefile.objs  |1 +
> >  hw/intc/rx_icu.c   |  376 +++
> >  hw/rx/Kconfig  |   14 +
> >  hw/rx/Makefile.objs|2 +
> >  hw/rx/rx-virt.c|  105 ++
> >  hw/rx/rx62n.c  |  238 
> >  hw/timer/Kconfig   |6 +
> >  hw/timer/Makefile.objs |3 +
> >  hw/timer/renesas_cmt.c |  275 +
> >  hw/timer/renesas_tmr.c |  455 
> >  include/disas/dis-asm.h|5 +
> >  include/hw/char/renesas_sci.h  |   45 +
> >  include/hw/intc/rx_icu.h   |   57 +
> >  include/hw/registerfields.h|   32 +-
> >  include/hw/rx/rx.h |7 +
> >  include/hw/rx/rx62n.h  |   94 ++
> >  include/hw/timer/renesas_cmt.h |   38 +
> >  include/hw/timer/renesas_tmr.h |   50 +
> >  include/qemu/bitops.h  |   38 +
> >  include/sysemu/arch_init.h |1 +
> >  target/rx/Makefile.objs

Re: [Qemu-devel] [PATCH v4 12/14] spapr/irq: initialize the IRQ device only once

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 10:42:43AM +0200, Cédric Le Goater wrote:
> Add a check to make sure that the routine initializing the emulated
> IRQ device is called once. We don't have much to test on the XICS
> side, so we introduce a 'init' boolean under ICSState.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

I'm not entirely sure it's the best way to accomplish what we need,
but it will do for now.

> ---
> 
>  Changes since v3:
> 
>  - introduced a 'init' boolean under ICSState
>  
>  include/hw/ppc/xics.h | 1 +
>  hw/intc/spapr_xive.c  | 9 +
>  hw/intc/xics_spapr.c  | 7 +++
>  3 files changed, 17 insertions(+)
> 
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index eb65ad7e43b7..d6f8e4c4c282 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -119,6 +119,7 @@ struct ICSState {
>  uint32_t offset;
>  ICSIRQState *irqs;
>  XICSFabric *xics;
> +bool init; /* sPAPR ICS device initialized */
>  };
>  
>  #define ICS_PROP_XICS "xics"
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 246b21ae7f31..1e649d6cdbe1 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -338,6 +338,15 @@ void spapr_xive_init(SpaprXive *xive, Error **errp)
>  XiveSource *xsrc = >source;
>  XiveENDSource *end_xsrc = >end_source;
>  
> +/*
> + * The emulated XIVE device can only be initialized once. If the
> + * ESB memory region has been already mapped, it means we have been
> + * through there.
> + */
> +if (memory_region_is_mapped(>esb_mmio)) {
> +return;
> +}
> +
>  /* TIMA initialization */
>  memory_region_init_io(>tm_mmio, OBJECT(xive), _tm_ops, xive,
>"xive.tima", 4ull << TM_SHIFT);
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 9d2b8adef7c5..5a1835e8b1ed 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -239,6 +239,13 @@ static void rtas_int_on(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  
>  void xics_spapr_init(SpaprMachineState *spapr)
>  {
> +/* Emulated mode can only be initialized once. */
> +if (spapr->ics->init) {
> +return;
> +}
> +
> +spapr->ics->init = true;
> +
>  /* Registration of global state belongs into realize */
>  spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
>  spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);

-- 
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 v4 13/14] ppc/xics: fix irq priority in ics_set_irq_type()

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 10:42:44AM +0200, Cédric Le Goater wrote:
> Recent commits changed the behavior of ics_set_irq_type() to
> initialize correctly LSIs at the KVM level. ics_set_irq_type() is also
> called by the realize routine of the different devices of the machine
> when initial interrupts are claimed, before the ICSState device is
> reseted.
> 
> In the case, the ICSIRQState priority is 0x0 and the call to
> ics_set_irq_type() results in configuring the target of the
> interrupt. On P9, when using the KVM XICS-on-XIVE device, the target
> is configured to be server 0, priority 0 and the event queue 0 is
> created automatically by KVM.
> 
> With the dual interrupt mode creating the KVM device at reset, it
> leads to unexpected effects on the guest, mostly blocking IPIs. This
> is wrong, fix it by reseting the ICSIRQState structure when
> ics_set_irq_type() is called.
> 
> Fixes: commit 6cead90c5c9c ("xics: Write source state to KVM at claim time")
> Signed-off-by: Greg Kurz 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  hw/intc/xics.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index af7dc709abab..79f5a8a91665 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -610,6 +610,12 @@ static const TypeInfo ics_simple_info = {
>  .class_size = sizeof(ICSStateClass),
>  };
>  
> +static void ics_reset_irq(ICSIRQState *irq)
> +{
> +irq->priority = 0xff;
> +irq->saved_priority = 0xff;
> +}
> +
>  static void ics_base_reset(DeviceState *dev)
>  {
>  ICSState *ics = ICS_BASE(dev);
> @@ -623,8 +629,7 @@ static void ics_base_reset(DeviceState *dev)
>  memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
>  
>  for (i = 0; i < ics->nr_irqs; i++) {
> -ics->irqs[i].priority = 0xff;
> -ics->irqs[i].saved_priority = 0xff;
> +ics_reset_irq(ics->irqs + i);
>  ics->irqs[i].flags = flags[i];
>  }
>  }
> @@ -760,6 +765,7 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
>  lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
>  
>  if (kvm_irqchip_in_kernel()) {
> +ics_reset_irq(ics->irqs + srcno);
>  ics_set_kvm_state_one(ics, srcno);
>  }
>  }

-- 
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 v4 04/14] spapr/xive: add state synchronization with KVM

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 10:42:35AM +0200, Cédric Le Goater wrote:
> This extends the KVM XIVE device backend with 'synchronize_state'
> methods used to retrieve the state from KVM. The HW state of the
> sources, the KVM device and the thread interrupt contexts are
> collected for the monitor usage and also migration.
> 
> These get operations rely on their KVM counterpart in the host kernel
> which acts as a proxy for OPAL, the host firmware. The set operations
> will be added for migration support later.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  include/hw/ppc/spapr_xive.h |  8 
>  include/hw/ppc/xive.h   |  1 +
>  hw/intc/spapr_xive.c| 17 ---
>  hw/intc/spapr_xive_kvm.c| 90 +
>  hw/intc/xive.c  | 10 +
>  5 files changed, 119 insertions(+), 7 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 03685910e76b..7e49badd8c9a 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -44,6 +44,13 @@ typedef struct SpaprXive {
>  void  *tm_mmap;
>  } SpaprXive;
>  
> +/*
> + * The sPAPR machine has a unique XIVE IC device. Assign a fixed value
> + * to the controller block id value. It can nevertheless be changed
> + * for testing purpose.
> + */
> +#define SPAPR_XIVE_BLOCK_ID 0x0
> +
>  bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
>  bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
> @@ -74,5 +81,6 @@ void kvmppc_xive_set_queue_config(SpaprXive *xive, uint8_t 
> end_blk,
>  void kvmppc_xive_get_queue_config(SpaprXive *xive, uint8_t end_blk,
>   uint32_t end_idx, XiveEND *end,
>   Error **errp);
> +void kvmppc_xive_synchronize_state(SpaprXive *xive, Error **errp);
>  
>  #endif /* PPC_SPAPR_XIVE_H */
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index dd115da30ebc..78c919c4a590 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -435,5 +435,6 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int 
> srcno, Error **errp);
>  void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp);
>  void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
>  void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
> +void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
>  
>  #endif /* PPC_XIVE_H */
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 6beda26ee440..84cd30e1faff 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -40,13 +40,6 @@
>  
>  #define SPAPR_XIVE_NVT_BASE 0x400
>  
> -/*
> - * The sPAPR machine has a unique XIVE IC device. Assign a fixed value
> - * to the controller block id value. It can nevertheless be changed
> - * for testing purpose.
> - */
> -#define SPAPR_XIVE_BLOCK_ID 0x0
> -
>  /*
>   * sPAPR NVT and END indexing helpers
>   */
> @@ -157,6 +150,16 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor 
> *mon)
>  XiveSource *xsrc = >source;
>  int i;
>  
> +if (kvm_irqchip_in_kernel()) {
> +Error *local_err = NULL;
> +
> +kvmppc_xive_synchronize_state(xive, _err);
> +if (local_err) {
> +error_report_err(local_err);
> +return;
> +}
> +}
> +
>  monitor_printf(mon, "  LISN PQEISN CPU/PRIO EQ\n");
>  
>  for (i = 0; i < xive->nr_irqs; i++) {
> diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> index 964bad0c23fb..8dd4f96e0b97 100644
> --- a/hw/intc/spapr_xive_kvm.c
> +++ b/hw/intc/spapr_xive_kvm.c
> @@ -60,6 +60,54 @@ static void kvm_cpu_enable(CPUState *cs)
>  /*
>   * XIVE Thread Interrupt Management context (KVM)
>   */
> +static void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp)
> +{
> +uint64_t state[2] = { 0 };
> +int ret;
> +
> +ret = kvm_get_one_reg(tctx->cs, KVM_REG_PPC_VP_STATE, state);
> +if (ret != 0) {
> +error_setg_errno(errp, errno,
> + "XIVE: could not capture KVM state of CPU %ld",
> + kvm_arch_vcpu_id(tctx->cs));
> +return;
> +}
> +
> +/* word0 and word1 of the OS ring. */
> +*((uint64_t *) >regs[TM_QW1_OS]) = state[0];
> +}
> +
> +typedef struct {
> +XiveTCTX *tctx;
> +Error *err;
> +} XiveCpuGetState;
> +
> +static void kvmppc_xive_cpu_do_synchronize_state(CPUState *cpu,
> + run_on_cpu_data arg)
> +{
> +XiveCpuGetState *s = arg.host_ptr;
> +
> +kvmppc_xive_cpu_get_state(s->tctx, >err);
> +}
> +
> +void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp)
> +{
> +XiveCpuGetState s = {
> +.tctx = tctx,
> +.err = NULL,
> +};
> +
> +/*
> + * Kick the vCPU to make sure they are available for the KVM ioctl.
> + 

Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 4/6] target/ppc: Build rtas error log upon an MCE

2019-05-13 Thread David Gibson
On Mon, May 13, 2019 at 01:30:53PM +0200, Greg Kurz wrote:
> On Mon, 22 Apr 2019 12:33:26 +0530
> Aravinda Prasad  wrote:
> 
> > Upon a machine check exception (MCE) in a guest address space,
> > KVM causes a guest exit to enable QEMU to build and pass the
> > error to the guest in the PAPR defined rtas error log format.
> > 
> > This patch builds the rtas error log, copies it to the rtas_addr
> > and then invokes the guest registered machine check handler. The
> > handler in the guest takes suitable action(s) depending on the type
> > and criticality of the error. For example, if an error is
> > unrecoverable memory corruption in an application inside the
> > guest, then the guest kernel sends a SIGBUS to the application.
> > For recoverable errors, the guest performs recovery actions and
> > logs the error.
> > 
> > Signed-off-by: Aravinda Prasad 
> > ---
> >  hw/ppc/spapr.c |4 +
> >  hw/ppc/spapr_events.c  |  245 
> > 
> >  include/hw/ppc/spapr.h |4 +
> >  3 files changed, 253 insertions(+)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 2779efe..ffd1715 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -2918,6 +2918,10 @@ static void spapr_machine_init(MachineState *machine)
> >  error_report("Could not get size of LPAR rtas '%s'", filename);
> >  exit(1);
> >  }
> > +
> > +/* Resize blob to accommodate error log. */
> > +spapr->rtas_size = spapr_get_rtas_size(spapr->rtas_size);
> > +
> 
> This is the only user for spapr_get_rtas_size(), which is trivial.
> I suggest you simply open-code it here.

I agree.

> But also, spapr->rtas_size is a guest visible thing, "rtas-size" prop in the
> DT. Since existing machine types don't do that, I guess we should only use
> the new size if cap-fwnmi-mce=on for the sake of compatibility.

Yes, that's a good idea.  Changing this is very unlikely to break a
guest, but it's easy to be safe here so let's do it.

> 
> >  spapr->rtas_blob = g_malloc(spapr->rtas_size);
> >  if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) 
> > {
> >  error_report("Could not load LPAR rtas '%s'", filename);
> > diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> > index 9922a23..4032db0 100644
> > --- a/hw/ppc/spapr_events.c
> > +++ b/hw/ppc/spapr_events.c
> > @@ -212,6 +212,106 @@ struct hp_extended_log {
> >  struct rtas_event_log_v6_hp hp;
> >  } QEMU_PACKED;
> >  
> > +struct rtas_event_log_v6_mc {
> 
> Even if the rest of the code in this file seems to ignore CODING_STYLE,
> maybe it's time to start using CamelCase.
> 
> David ?

Out of scope here, I think.

> > +#define RTAS_LOG_V6_SECTION_ID_MC   0x4D43 /* MC */
> > +struct rtas_event_log_v6_section_header hdr;
> > +uint32_t fru_id;
> > +uint32_t proc_id;
> > +uint8_t error_type;
> > +#define RTAS_LOG_V6_MC_TYPE_UE   0
> > +#define RTAS_LOG_V6_MC_TYPE_SLB  1
> > +#define RTAS_LOG_V6_MC_TYPE_ERAT 2
> > +#define RTAS_LOG_V6_MC_TYPE_TLB  4
> > +#define RTAS_LOG_V6_MC_TYPE_D_CACHE  5
> > +#define RTAS_LOG_V6_MC_TYPE_I_CACHE  7
> > +uint8_t sub_err_type;
> > +#define RTAS_LOG_V6_MC_UE_INDETERMINATE  0
> > +#define RTAS_LOG_V6_MC_UE_IFETCH 1
> > +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_IFETCH 2
> > +#define RTAS_LOG_V6_MC_UE_LOAD_STORE 3
> > +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_LOAD_STORE 4
> > +#define RTAS_LOG_V6_MC_SLB_PARITY0
> > +#define RTAS_LOG_V6_MC_SLB_MULTIHIT  1
> > +#define RTAS_LOG_V6_MC_SLB_INDETERMINATE 2
> > +#define RTAS_LOG_V6_MC_ERAT_PARITY   1
> > +#define RTAS_LOG_V6_MC_ERAT_MULTIHIT 2
> > +#define RTAS_LOG_V6_MC_ERAT_INDETERMINATE3
> > +#define RTAS_LOG_V6_MC_TLB_PARITY1
> > +#define RTAS_LOG_V6_MC_TLB_MULTIHIT  2
> > +#define RTAS_LOG_V6_MC_TLB_INDETERMINATE 3
> > +uint8_t reserved_1[6];
> > +uint64_t effective_address;
> > +uint64_t logical_address;
> > +} QEMU_PACKED;
> > +
> > +struct mc_extended_log {
> > +struct rtas_event_log_v6 v6hdr;
> > +struct rtas_event_log_v6_mc mc;
> > +} QEMU_PACKED;
> > +
> > +struct MC_ierror_table {
> > +unsigned long srr1_mask;
> > +unsigned long srr1_value;
> > +bool nip_valid; /* nip is a valid indicator of faulting address */
> > +uint8_t error_type;
> > +uint8_t error_subtype;
> > +unsigned int initiator;
> > +unsigned int severity;
> > +};
> > +
> > +static const struct MC_ierror_table mc_ierror_table[] = {
> > +{ 0x081c, 0x0004, true,
> > +  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_IFETCH,
> > +  

[Qemu-devel] [PULL 14/31] tcg: Add INDEX_op_dupm_vec

2019-05-13 Thread Richard Henderson
Allow the backend to expand dup from memory directly, instead of
forcing the value into a temp first.  This is especially important
if integer/vector register moves do not exist.

Note that officially tcg_out_dupm_vec is allowed to fail.
If it did, we could fix this up relatively easily:

  VECE == 32/64:
Load the value into a vector register, then dup.
Both of these must work.

  VECE == 8/16:
If the value happens to be at an offset such that an aligned
load would place the desired value in the least significant
end of the register, go ahead and load w/garbage in high bits.

Load the value w/INDEX_op_ld{8,16}_i32.
Attempt a move directly to vector reg, which may fail.
Store the value into the backing store for OTS.
Load the value into the vector reg w/TCG_TYPE_I32, which must work.
Duplicate from the vector reg into itself, which must work.

All of which is well and good, except that all supported
hosts can support dupm for all vece, so all of the failure
paths would be dead code and untestable.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.h |  1 +
 tcg/tcg-opc.h|  1 +
 tcg/aarch64/tcg-target.inc.c |  4 ++
 tcg/i386/tcg-target.inc.c|  4 ++
 tcg/tcg-op-gvec.c| 89 +++-
 tcg/tcg-op-vec.c | 11 +
 tcg/tcg.c|  1 +
 7 files changed, 70 insertions(+), 41 deletions(-)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 1f1824c30a..9fff9864f6 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -954,6 +954,7 @@ void tcg_gen_atomic_umax_fetch_i64(TCGv_i64, TCGv, 
TCGv_i64, TCGArg, TCGMemOp);
 void tcg_gen_mov_vec(TCGv_vec, TCGv_vec);
 void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec, TCGv_i32);
 void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec, TCGv_i64);
+void tcg_gen_dup_mem_vec(unsigned vece, TCGv_vec, TCGv_ptr, tcg_target_long);
 void tcg_gen_dup8i_vec(TCGv_vec, uint32_t);
 void tcg_gen_dup16i_vec(TCGv_vec, uint32_t);
 void tcg_gen_dup32i_vec(TCGv_vec, uint32_t);
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 1bad6e4208..4bf71f261f 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -219,6 +219,7 @@ DEF(dup2_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_REG_BITS 
== 32))
 
 DEF(ld_vec, 1, 1, 1, IMPLVEC)
 DEF(st_vec, 0, 2, 1, IMPLVEC)
+DEF(dupm_vec, 1, 1, 1, IMPLVEC)
 
 DEF(add_vec, 1, 2, 0, IMPLVEC)
 DEF(sub_vec, 1, 2, 0, IMPLVEC)
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index b4585724d3..3dda66e777 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -2191,6 +2191,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_st_vec:
 tcg_out_st(s, type, a0, a1, a2);
 break;
+case INDEX_op_dupm_vec:
+tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
+break;
 case INDEX_op_add_vec:
 tcg_out_insn(s, 3616, ADD, is_q, vece, a0, a1, a2);
 break;
@@ -2523,6 +2526,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 return _w;
 case INDEX_op_ld_vec:
 case INDEX_op_st_vec:
+case INDEX_op_dupm_vec:
 return _r;
 case INDEX_op_dup_vec:
 return _wr;
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index f4bd00e24f..5b33bbd99b 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -2829,6 +2829,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_st_vec:
 tcg_out_st(s, type, a0, a1, a2);
 break;
+case INDEX_op_dupm_vec:
+tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
+break;
 
 case INDEX_op_x86_shufps_vec:
 insn = OPC_SHUFPS;
@@ -3115,6 +3118,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 
 case INDEX_op_ld_vec:
 case INDEX_op_st_vec:
+case INDEX_op_dupm_vec:
 return _r;
 
 case INDEX_op_add_vec:
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 3fcb2352d9..35ebc5a201 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -395,6 +395,41 @@ static TCGType choose_vector_type(const TCGOpcode *list, 
unsigned vece,
 return 0;
 }
 
+static void do_dup_store(TCGType type, uint32_t dofs, uint32_t oprsz,
+ uint32_t maxsz, TCGv_vec t_vec)
+{
+uint32_t i = 0;
+
+switch (type) {
+case TCG_TYPE_V256:
+/*
+ * Recall that ARM SVE allows vector sizes that are not a
+ * power of 2, but always a multiple of 16.  The intent is
+ * that e.g. size == 80 would be expanded with 2x32 + 1x16.
+ */
+for (; i + 32 <= oprsz; i += 32) {
+tcg_gen_stl_vec(t_vec, cpu_env, dofs + i, TCG_TYPE_V256);
+}
+/* fallthru */
+case TCG_TYPE_V128:
+for (; i + 16 <= oprsz; i += 16) {
+tcg_gen_stl_vec(t_vec, cpu_env, dofs + i, TCG_TYPE_V128);
+}
+break;
+case TCG_TYPE_V64:
+for (; i < 

[Qemu-devel] [PULL 30/31] target/xtensa: Use tcg_gen_abs_i32

2019-05-13 Thread Richard Henderson
Acked-by: Max Filippov 
Signed-off-by: Richard Henderson 
---
 target/xtensa/translate.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 301c8e3161..b063fa85f2 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -1709,14 +1709,7 @@ void restore_state_to_opc(CPUXtensaState *env, 
TranslationBlock *tb,
 static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
   const uint32_t par[])
 {
-TCGv_i32 zero = tcg_const_i32(0);
-TCGv_i32 neg = tcg_temp_new_i32();
-
-tcg_gen_neg_i32(neg, arg[1].in);
-tcg_gen_movcond_i32(TCG_COND_GE, arg[0].out,
-arg[1].in, zero, arg[1].in, neg);
-tcg_temp_free(neg);
-tcg_temp_free(zero);
+tcg_gen_abs_i32(arg[0].out, arg[1].in);
 }
 
 static void translate_add(DisasContext *dc, const OpcodeArg arg[],
-- 
2.17.1




[Qemu-devel] [PULL 01/31] tcg: Implement tcg_gen_gvec_3i()

2019-05-13 Thread Richard Henderson
From: David Hildenbrand 

Let's add tcg_gen_gvec_3i(), similar to tcg_gen_gvec_2i(), however
without introducing "gen_helper_gvec_3i *fnoi", as it isn't needed
for now.

Reviewed-by: Alex Bennée 
Signed-off-by: David Hildenbrand 
Message-Id: <20190416185301.25344-2-da...@redhat.com>
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op-gvec.h |  24 
 tcg/tcg-op-gvec.c | 139 ++
 2 files changed, 163 insertions(+)

diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index 850da32ded..c093243c4c 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -164,6 +164,27 @@ typedef struct {
 bool load_dest;
 } GVecGen3;
 
+typedef struct {
+/*
+ * Expand inline as a 64-bit or 32-bit integer. Only one of these will be
+ * non-NULL.
+ */
+void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, int64_t);
+void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, int32_t);
+/* Expand inline with a host vector type.  */
+void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
+/* Expand out-of-line helper w/descriptor, data in descriptor.  */
+gen_helper_gvec_3 *fno;
+/* The opcode, if any, to which this corresponds.  */
+TCGOpcode opc;
+/* The vector element size, if applicable.  */
+uint8_t vece;
+/* Prefer i64 to v64.  */
+bool prefer_i64;
+/* Load dest as a 3rd source operand.  */
+bool load_dest;
+} GVecGen3i;
+
 typedef struct {
 /* Expand inline as a 64-bit or 32-bit integer.
Only one of these will be non-NULL.  */
@@ -193,6 +214,9 @@ void tcg_gen_gvec_2s(uint32_t dofs, uint32_t aofs, uint32_t 
oprsz,
  uint32_t maxsz, TCGv_i64 c, const GVecGen2s *);
 void tcg_gen_gvec_3(uint32_t dofs, uint32_t aofs, uint32_t bofs,
 uint32_t oprsz, uint32_t maxsz, const GVecGen3 *);
+void tcg_gen_gvec_3i(uint32_t dofs, uint32_t aofs, uint32_t bofs,
+ uint32_t oprsz, uint32_t maxsz, int64_t c,
+ const GVecGen3i *);
 void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
 uint32_t oprsz, uint32_t maxsz, const GVecGen4 *);
 
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 0996ef0812..f831adb4e7 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -663,6 +663,29 @@ static void expand_3_i32(uint32_t dofs, uint32_t aofs,
 tcg_temp_free_i32(t0);
 }
 
+static void expand_3i_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs,
+  uint32_t oprsz, int32_t c, bool load_dest,
+  void (*fni)(TCGv_i32, TCGv_i32, TCGv_i32, int32_t))
+{
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+uint32_t i;
+
+for (i = 0; i < oprsz; i += 4) {
+tcg_gen_ld_i32(t0, cpu_env, aofs + i);
+tcg_gen_ld_i32(t1, cpu_env, bofs + i);
+if (load_dest) {
+tcg_gen_ld_i32(t2, cpu_env, dofs + i);
+}
+fni(t2, t0, t1, c);
+tcg_gen_st_i32(t2, cpu_env, dofs + i);
+}
+tcg_temp_free_i32(t0);
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t2);
+}
+
 /* Expand OPSZ bytes worth of three-operand operations using i32 elements.  */
 static void expand_4_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs,
  uint32_t cofs, uint32_t oprsz, bool write_aofs,
@@ -770,6 +793,29 @@ static void expand_3_i64(uint32_t dofs, uint32_t aofs,
 tcg_temp_free_i64(t0);
 }
 
+static void expand_3i_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs,
+  uint32_t oprsz, int64_t c, bool load_dest,
+  void (*fni)(TCGv_i64, TCGv_i64, TCGv_i64, int64_t))
+{
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+TCGv_i64 t2 = tcg_temp_new_i64();
+uint32_t i;
+
+for (i = 0; i < oprsz; i += 8) {
+tcg_gen_ld_i64(t0, cpu_env, aofs + i);
+tcg_gen_ld_i64(t1, cpu_env, bofs + i);
+if (load_dest) {
+tcg_gen_ld_i64(t2, cpu_env, dofs + i);
+}
+fni(t2, t0, t1, c);
+tcg_gen_st_i64(t2, cpu_env, dofs + i);
+}
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+tcg_temp_free_i64(t2);
+}
+
 /* Expand OPSZ bytes worth of three-operand operations using i64 elements.  */
 static void expand_4_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs,
  uint32_t cofs, uint32_t oprsz, bool write_aofs,
@@ -883,6 +929,35 @@ static void expand_3_vec(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 tcg_temp_free_vec(t0);
 }
 
+/*
+ * Expand OPSZ bytes worth of three-vector operands and an immediate operand
+ * using host vectors.
+ */
+static void expand_3i_vec(unsigned vece, uint32_t dofs, uint32_t aofs,
+  uint32_t bofs, uint32_t oprsz, uint32_t tysz,
+  TCGType type, int64_t c, bool load_dest,
+  void (*fni)(unsigned, TCGv_vec, 

Re: [Qemu-devel] [PATCH v1 1/1] target/arm: Fix vector operation segfault

2019-05-13 Thread Richard Henderson
On 5/13/19 5:08 PM, Alistair Francis wrote:
> We hit the second switch case as
> NEON_3R_VQADD and NEON_3R_VQSUB don't return from the function in the
> first switch case.

That's the bug, not here in this second switch.


r~



[Qemu-devel] [PULL 23/31] tcg/aarch64: Support vector absolute value

2019-05-13 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h | 2 +-
 tcg/aarch64/tcg-target.inc.c | 6 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 21d06d928c..e43554c3c7 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -132,7 +132,7 @@ typedef enum {
 #define TCG_TARGET_HAS_orc_vec  1
 #define TCG_TARGET_HAS_not_vec  1
 #define TCG_TARGET_HAS_neg_vec  1
-#define TCG_TARGET_HAS_abs_vec  0
+#define TCG_TARGET_HAS_abs_vec  1
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  0
 #define TCG_TARGET_HAS_shv_vec  1
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index df123c07f1..1248dfd04c 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -552,6 +552,7 @@ typedef enum {
 I3617_CMGE0 = 0x2e208800,
 I3617_CMLE0 = 0x2e20a800,
 I3617_NOT   = 0x2e205800,
+I3617_ABS   = 0x0e20b800,
 I3617_NEG   = 0x2e20b800,
 
 /* System instructions.  */
@@ -2208,6 +2209,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_neg_vec:
 tcg_out_insn(s, 3617, NEG, is_q, vece, a0, a1);
 break;
+case INDEX_op_abs_vec:
+tcg_out_insn(s, 3617, ABS, is_q, vece, a0, a1);
+break;
 case INDEX_op_and_vec:
 tcg_out_insn(s, 3616, AND, is_q, 0, a0, a1, a2);
 break;
@@ -2319,6 +2323,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_andc_vec:
 case INDEX_op_orc_vec:
 case INDEX_op_neg_vec:
+case INDEX_op_abs_vec:
 case INDEX_op_not_vec:
 case INDEX_op_cmp_vec:
 case INDEX_op_shli_vec:
@@ -2562,6 +2567,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 return _w_w;
 case INDEX_op_not_vec:
 case INDEX_op_neg_vec:
+case INDEX_op_abs_vec:
 case INDEX_op_shli_vec:
 case INDEX_op_shri_vec:
 case INDEX_op_sari_vec:
-- 
2.17.1




[Qemu-devel] [PULL 25/31] target/cris: Use tcg_gen_abs_tl

2019-05-13 Thread Richard Henderson
Reviewed-by: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index b005a5c20e..31b40a57f9 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -1686,18 +1686,11 @@ static int dec_cmp_r(CPUCRISState *env, DisasContext 
*dc)
 
 static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
 {
-TCGv t0;
-
 LOG_DIS("abs $r%u, $r%u\n",
 dc->op1, dc->op2);
 cris_cc_mask(dc, CC_MASK_NZ);
 
-t0 = tcg_temp_new();
-tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
-tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
-tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
-tcg_temp_free(t0);
-
+tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
 cris_alu(dc, CC_OP_MOVE,
 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
 return 2;
-- 
2.17.1




[Qemu-devel] [PULL 00/31] tcg: gvec improvments

2019-05-13 Thread Richard Henderson
Most of these patches are in support of David's guest vector
patches for target/s390x.


r~


The following changes since commit e24f44dbeab8e54c72bdaedbd35453fb2a6c38da:

  Merge remote-tracking branch 
'remotes/huth-gitlab/tags/pull-request-2019-05-13' into staging (2019-05-13 
16:52:56 +0100)

are available in the Git repository at:

  https://github.com/rth7680/qemu.git tags/pull-tcg-20190513

for you to fetch changes up to a7b6d286cfb5205b9f5330aefc5727269b3d810f:

  tcg/aarch64: Do not advertise minmax for MO_64 (2019-05-13 22:52:08 +)


Improve code generation for vector duplication.
Add vector expansions for shifts by non-constant scalar.
Add vector expansions for shifts by vector.
Add integer and vector expansions for absolute value.
Several patches in preparation for Altivec.
Bug fix for tcg/aarch64 vs min/max.


David Hildenbrand (1):
  tcg: Implement tcg_gen_gvec_3i()

Philippe Mathieu-Daudé (2):
  target/ppc: Use tcg_gen_abs_i32
  target/tricore: Use tcg_gen_abs_tl

Richard Henderson (28):
  tcg: Do not recreate INDEX_op_neg_vec unless supported
  tcg: Allow add_vec, sub_vec, neg_vec, not_vec to be expanded
  tcg: Specify optional vector requirements with a list
  tcg: Assert fixed_reg is read-only
  tcg/arm: Use tcg_out_mov_reg in tcg_out_mov
  tcg: Return bool success from tcg_out_mov
  tcg: Support cross-class moves without instruction support
  tcg: Promote tcg_out_{dup,dupi}_vec to backend interface
  tcg: Manually expand INDEX_op_dup_vec
  tcg: Add tcg_out_dupm_vec to the backend interface
  tcg/i386: Implement tcg_out_dupm_vec
  tcg/aarch64: Implement tcg_out_dupm_vec
  tcg: Add INDEX_op_dupm_vec
  tcg: Add gvec expanders for variable shift
  tcg/i386: Support vector variable shift opcodes
  tcg/aarch64: Support vector variable shift opcodes
  tcg: Add gvec expanders for vector shift by scalar
  tcg/i386: Support vector scalar shift opcodes
  tcg: Add support for integer absolute value
  tcg: Add support for vector absolute value
  tcg/i386: Support vector absolute value
  tcg/aarch64: Support vector absolute value
  target/arm: Use tcg_gen_abs_i64 and tcg_gen_gvec_abs
  target/cris: Use tcg_gen_abs_tl
  target/ppc: Use tcg_gen_abs_tl
  target/s390x: Use tcg_gen_abs_i64
  target/xtensa: Use tcg_gen_abs_i32
  tcg/aarch64: Do not advertise minmax for MO_64

 accel/tcg/tcg-runtime.h |  20 +
 target/arm/helper.h |   2 -
 tcg/aarch64/tcg-target.h|   3 +-
 tcg/aarch64/tcg-target.opc.h|   2 +
 tcg/i386/tcg-target.h   |   5 +-
 tcg/tcg-op-gvec.h   |  64 ++-
 tcg/tcg-op.h|  14 +
 tcg/tcg-opc.h   |   2 +
 tcg/tcg.h   |  21 +
 accel/tcg/tcg-runtime-gvec.c| 192 
 target/arm/neon_helper.c|   5 -
 target/arm/translate-a64.c  |  41 +-
 target/arm/translate-sve.c  |   9 +-
 target/arm/translate.c  | 144 +++---
 target/cris/translate.c |   9 +-
 target/ppc/translate.c  |  68 +--
 target/ppc/translate/spe-impl.inc.c |  14 +-
 target/ppc/translate/vmx-impl.inc.c |   7 +-
 target/s390x/translate.c|   8 +-
 target/tricore/translate.c  |  27 +-
 target/xtensa/translate.c   |   9 +-
 tcg/aarch64/tcg-target.inc.c| 121 -
 tcg/arm/tcg-target.inc.c|   5 +-
 tcg/i386/tcg-target.inc.c   | 163 ++-
 tcg/mips/tcg-target.inc.c   |   3 +-
 tcg/optimize.c  |   8 +-
 tcg/ppc/tcg-target.inc.c|   3 +-
 tcg/riscv/tcg-target.inc.c  |   5 +-
 tcg/s390/tcg-target.inc.c   |   3 +-
 tcg/sparc/tcg-target.inc.c  |   3 +-
 tcg/tcg-op-gvec.c   | 945 ++--
 tcg/tcg-op-vec.c| 270 ++-
 tcg/tcg-op.c|  20 +
 tcg/tcg.c   | 271 +--
 tcg/tci/tcg-target.inc.c|   3 +-
 tcg/README  |   4 +
 36 files changed, 2020 insertions(+), 473 deletions(-)



[Qemu-devel] [PATCH v1 1/1] target/arm: Fix vector operation segfault

2019-05-13 Thread Alistair Francis
Commit 89e68b575 "target/arm: Use vector operations for saturation"
causes this abort() when booting QEMU ARM with a Cortex-A15:

0  0x74c2382f in raise () at /usr/lib/libc.so.6
1  0x74c0e672 in abort () at /usr/lib/libc.so.6
2  0x559c1839 in disas_neon_data_insn (insn=, 
s=) at ./target/arm/translate.c:6673
3  0x559c1839 in disas_neon_data_insn (s=, 
insn=) at ./target/arm/translate.c:6386
4  0x559cd8a4 in disas_arm_insn (insn=4081107068, s=0x7fffe59a9510) at 
./target/arm/translate.c:9289
5  0x559cd8a4 in arm_tr_translate_insn (dcbase=0x7fffe59a9510, 
cpu=) at ./target/arm/translate.c:13612
6  0x558d1d39 in translator_loop (ops=0x561cc580 
, db=0x7fffe59a9510, cpu=0x5686a2f0, tb=, max_insns=) at ./accel/tcg/translator.c:96
7  0x559d10d4 in gen_intermediate_code (cpu=cpu@entry=0x5686a2f0, 
tb=tb@entry=0x7fffd7840080 , 
max_insns=max_insns@entry=512) at ./target/arm/translate.c:13901
8  0x558d06b9 in tb_gen_code (cpu=cpu@entry=0x5686a2f0, 
pc=3067096216, cs_base=0, flags=192, cflags=-16252928, cflags@entry=524288) at 
./accel/tcg/translate-all.c:1736
9  0x558ce467 in tb_find (cf_mask=524288, tb_exit=1, 
last_tb=0x7fffd783e640 , cpu=0x1) at 
./accel/tcg/cpu-exec.c:407
10 0x558ce467 in cpu_exec (cpu=cpu@entry=0x5686a2f0) at 
./accel/tcg/cpu-exec.c:728
11 0x5588b0cf in tcg_cpu_exec (cpu=0x5686a2f0) at ./cpus.c:1431
12 0x5588d223 in qemu_tcg_cpu_thread_fn (arg=0x5686a2f0) at 
./cpus.c:1735
13 0x5588d223 in qemu_tcg_cpu_thread_fn (arg=arg@entry=0x5686a2f0) 
at ./cpus.c:1709
14 0x55d2629a in qemu_thread_start (args=) at 
./util/qemu-thread-posix.c:502
15 0x74db8a92 in start_thread () at /usr/lib/libpthread.

This patch ensures that we don't hit the abort() in the second switch
case in disas_neon_data_insn(). We hit the second switch case as
NEON_3R_VQADD and NEON_3R_VQSUB don't return from the function in the
first switch case.

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

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 10bc53f91c..cbb32757e9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6749,6 +6749,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 tmp2 = neon_load_reg(rm, pass);
 }
 switch (op) {
+case NEON_3R_VQADD:
+case NEON_3R_VQSUB:
+break;
 case NEON_3R_VHADD:
 GEN_NEON_INTEGER_OP(hadd);
 break;
-- 
2.21.0



[Qemu-devel] [PULL 21/31] tcg: Add support for vector absolute value

2019-05-13 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime.h  |  5 +++
 tcg/aarch64/tcg-target.h |  1 +
 tcg/i386/tcg-target.h|  1 +
 tcg/tcg-op-gvec.h|  2 ++
 tcg/tcg-opc.h|  1 +
 tcg/tcg.h|  1 +
 accel/tcg/tcg-runtime-gvec.c | 48 +++
 tcg/tcg-op-gvec.c| 63 
 tcg/tcg-op-vec.c | 39 ++
 tcg/tcg.c|  2 ++
 tcg/README   |  4 +++
 11 files changed, 167 insertions(+)

diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index ed3ce5fd91..6d73dc2d65 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -225,6 +225,11 @@ DEF_HELPER_FLAGS_3(gvec_neg16, TCG_CALL_NO_RWG, void, ptr, 
ptr, i32)
 DEF_HELPER_FLAGS_3(gvec_neg32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(gvec_neg64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_3(gvec_abs8, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_abs16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_abs32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+DEF_HELPER_FLAGS_3(gvec_abs64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_3(gvec_not, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_and, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_or, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index f5640a229b..21d06d928c 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -132,6 +132,7 @@ typedef enum {
 #define TCG_TARGET_HAS_orc_vec  1
 #define TCG_TARGET_HAS_not_vec  1
 #define TCG_TARGET_HAS_neg_vec  1
+#define TCG_TARGET_HAS_abs_vec  0
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  0
 #define TCG_TARGET_HAS_shv_vec  1
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 618aa520d2..7445f05885 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -182,6 +182,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_orc_vec  0
 #define TCG_TARGET_HAS_not_vec  0
 #define TCG_TARGET_HAS_neg_vec  0
+#define TCG_TARGET_HAS_abs_vec  0
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  1
 #define TCG_TARGET_HAS_shv_vec  have_avx2
diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index 6ee98f3378..52a398c190 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -228,6 +228,8 @@ void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, 
uint32_t aofs,
   uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_neg(unsigned vece, uint32_t dofs, uint32_t aofs,
   uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
+  uint32_t oprsz, uint32_t maxsz);
 
 void tcg_gen_gvec_add(unsigned vece, uint32_t dofs, uint32_t aofs,
   uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 4bf71f261f..4a2dd116eb 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -225,6 +225,7 @@ DEF(add_vec, 1, 2, 0, IMPLVEC)
 DEF(sub_vec, 1, 2, 0, IMPLVEC)
 DEF(mul_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_mul_vec))
 DEF(neg_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_neg_vec))
+DEF(abs_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_abs_vec))
 DEF(ssadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
 DEF(usadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
 DEF(sssub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 2c7315da25..0e01a70d66 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -176,6 +176,7 @@ typedef uint64_t TCGRegSet;
 && !defined(TCG_TARGET_HAS_v128) \
 && !defined(TCG_TARGET_HAS_v256)
 #define TCG_TARGET_MAYBE_vec0
+#define TCG_TARGET_HAS_abs_vec  0
 #define TCG_TARGET_HAS_neg_vec  0
 #define TCG_TARGET_HAS_not_vec  0
 #define TCG_TARGET_HAS_andc_vec 0
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 2152fb6903..0f09e0ef38 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -398,6 +398,54 @@ void HELPER(gvec_neg64)(void *d, void *a, uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
+void HELPER(gvec_abs8)(void *d, void *a, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(int8_t)) {
+int8_t aa = *(int8_t *)(a + i);
+*(int8_t *)(d + i) = aa < 0 ? -aa : aa;
+}
+clear_high(d, oprsz, desc);
+}
+
+void HELPER(gvec_abs16)(void *d, void *a, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(int16_t)) {
+int16_t aa = *(int16_t *)(a + i);

[Qemu-devel] [PULL 22/31] tcg/i386: Support vector absolute value

2019-05-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.h |  2 +-
 tcg/i386/tcg-target.inc.c | 15 +++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 7445f05885..66f16fbe3c 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -182,7 +182,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_orc_vec  0
 #define TCG_TARGET_HAS_not_vec  0
 #define TCG_TARGET_HAS_neg_vec  0
-#define TCG_TARGET_HAS_abs_vec  0
+#define TCG_TARGET_HAS_abs_vec  1
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  1
 #define TCG_TARGET_HAS_shv_vec  have_avx2
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 0ba1587da4..aafd01cb49 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -369,6 +369,9 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_MOVSLQ (0x63 | P_REXW)
 #define OPC_MOVZBL (0xb6 | P_EXT)
 #define OPC_MOVZWL (0xb7 | P_EXT)
+#define OPC_PABSB   (0x1c | P_EXT38 | P_DATA16)
+#define OPC_PABSW   (0x1d | P_EXT38 | P_DATA16)
+#define OPC_PABSD   (0x1e | P_EXT38 | P_DATA16)
 #define OPC_PACKSSDW(0x6b | P_EXT | P_DATA16)
 #define OPC_PACKSSWB(0x63 | P_EXT | P_DATA16)
 #define OPC_PACKUSDW(0x2b | P_EXT38 | P_DATA16)
@@ -2741,6 +2744,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 static int const sars_insn[4] = {
 OPC_UD2, OPC_PSRAW, OPC_PSRAD, OPC_UD2
 };
+static int const abs_insn[4] = {
+/* TODO: AVX512 adds support for MO_64.  */
+OPC_PABSB, OPC_PABSW, OPC_PABSD, OPC_UD2
+};
 
 TCGType type = vecl + TCG_TYPE_V64;
 int insn, sub;
@@ -2829,6 +2836,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 insn = OPC_PUNPCKLDQ;
 goto gen_simd;
 #endif
+case INDEX_op_abs_vec:
+insn = abs_insn[vece];
+a2 = a1;
+a1 = 0;
+goto gen_simd;
 gen_simd:
 tcg_debug_assert(insn != OPC_UD2);
 if (type == TCG_TYPE_V256) {
@@ -3206,6 +3218,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_dup2_vec:
 #endif
 return _x_x;
+case INDEX_op_abs_vec:
 case INDEX_op_dup_vec:
 case INDEX_op_shli_vec:
 case INDEX_op_shri_vec:
@@ -3283,6 +3296,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_umin_vec:
 case INDEX_op_umax_vec:
 return vece <= MO_32 ? 1 : -1;
+case INDEX_op_abs_vec:
+return vece <= MO_32;
 
 default:
 return 0;
-- 
2.17.1




[Qemu-devel] [PULL 15/31] tcg: Add gvec expanders for variable shift

2019-05-13 Thread Richard Henderson
The gvec expanders perform a modulo on the shift count.  If the target
requires alternate behaviour, then it cannot use the generic gvec
expanders anyway, and will have to have its own custom code.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime.h  |  15 +++
 tcg/tcg-op-gvec.h|  11 ++
 tcg/tcg-op.h |   4 +
 accel/tcg/tcg-runtime-gvec.c | 144 ++
 tcg/tcg-op-gvec.c| 195 +++
 tcg/tcg-op-vec.c |  15 +++
 6 files changed, 384 insertions(+)

diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index dfe325625c..ed3ce5fd91 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -254,6 +254,21 @@ DEF_HELPER_FLAGS_3(gvec_sar16i, TCG_CALL_NO_RWG, void, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(gvec_sar32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(gvec_sar64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(gvec_shl8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shl16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shl32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shl64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_shr8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shr16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shr32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_shr64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_sar8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sar16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sar32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sar64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_4(gvec_eq8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_eq16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_eq32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index ac744ff7c9..84a6247b16 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -318,6 +318,17 @@ void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
 
+/*
+ * Perform vector shift by vector element, modulo the element size.
+ * E.g.  D[i] = A[i] << (B[i] % (8 << vece)).
+ */
+void tcg_gen_gvec_shlv(unsigned vece, uint32_t dofs, uint32_t aofs,
+   uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_shrv(unsigned vece, uint32_t dofs, uint32_t aofs,
+   uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_sarv(unsigned vece, uint32_t dofs, uint32_t aofs,
+   uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+
 void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, uint32_t dofs,
   uint32_t aofs, uint32_t bofs,
   uint32_t oprsz, uint32_t maxsz);
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 9fff9864f6..833c6330b5 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -986,6 +986,10 @@ void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec 
a, int64_t i);
 void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
 void tcg_gen_sari_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
 
+void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
+void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
+void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
+
 void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGv_vec r,
  TCGv_vec a, TCGv_vec b);
 
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index e2c6f24262..2152fb6903 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -725,6 +725,150 @@ void HELPER(gvec_sar64i)(void *d, void *a, uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
+void HELPER(gvec_shl8v)(void *d, void *a, void *b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
+uint8_t sh = *(uint8_t *)(b + i) & 7;
+*(uint8_t *)(d + i) = *(uint8_t *)(a + i) << sh;
+}
+clear_high(d, oprsz, desc);
+}
+
+void HELPER(gvec_shl16v)(void *d, void *a, void *b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
+uint8_t sh = *(uint16_t *)(b + i) & 15;
+*(uint16_t *)(d + i) = *(uint16_t *)(a + i) << sh;
+}
+clear_high(d, oprsz, desc);
+}
+
+void HELPER(gvec_shl32v)(void *d, void *a, void *b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+

[Qemu-devel] [PULL 29/31] target/tricore: Use tcg_gen_abs_tl

2019-05-13 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Reviewed-by: Bastian Koppelmann 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20190423102145.14812-3-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/tricore/translate.c | 27 +--
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 8f6416144e..06c4485e55 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -2415,11 +2415,7 @@ gen_msubadr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, 
uint32_t n, uint32_t mode)
 
 static inline void gen_abs(TCGv ret, TCGv r1)
 {
-TCGv temp = tcg_temp_new();
-TCGv t0 = tcg_const_i32(0);
-
-tcg_gen_neg_tl(temp, r1);
-tcg_gen_movcond_tl(TCG_COND_GE, ret, r1, t0, r1, temp);
+tcg_gen_abs_tl(ret, r1);
 /* overflow can only happen, if r1 = 0x8000 */
 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x8000);
 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
@@ -2430,9 +2426,6 @@ static inline void gen_abs(TCGv ret, TCGv r1)
 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
 /* calc SAV bit */
 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
-
-tcg_temp_free(temp);
-tcg_temp_free(t0);
 }
 
 static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
@@ -6617,13 +6610,8 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_gen_movi_tl(cpu_PSW_AV, 0);
 if (!tricore_feature(env, TRICORE_FEATURE_131)) {
 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
-tcg_gen_neg_tl(temp, temp3);
-/* use cpu_PSW_AV to compare against 0 */
-tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
-   temp, temp3);
-tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
-tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
-   temp2, cpu_gpr_d[r2]);
+tcg_gen_abs_tl(temp, temp3);
+tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
 } else {
 /* overflow = (D[b] == 0) */
@@ -6655,13 +6643,8 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_gen_movi_tl(cpu_PSW_AV, 0);
 if (!tricore_feature(env, TRICORE_FEATURE_131)) {
 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
-tcg_gen_neg_tl(temp, temp3);
-/* use cpu_PSW_AV to compare against 0 */
-tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
-   temp, temp3);
-tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
-tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
-   temp2, cpu_gpr_d[r2]);
+tcg_gen_abs_tl(temp, temp3);
+tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
 } else {
 /* overflow = (D[b] == 0) */
-- 
2.17.1




[Qemu-devel] [PULL 05/31] tcg: Assert fixed_reg is read-only

2019-05-13 Thread Richard Henderson
The only fixed_reg is cpu_env, and it should not be modified
during any TB.  Therefore code that tries to special-case moves
into a fixed_reg is dead.  Remove it.

Reviewed-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 87 +--
 1 file changed, 40 insertions(+), 47 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index f7bef51de8..70ca113c26 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3274,11 +3274,8 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp 
*ots,
   tcg_target_ulong val, TCGLifeData arg_life,
   TCGRegSet preferred_regs)
 {
-if (ots->fixed_reg) {
-/* For fixed registers, we do not do any constant propagation.  */
-tcg_out_movi(s, ots->type, ots->reg, val);
-return;
-}
+/* ENV should not be modified.  */
+tcg_debug_assert(!ots->fixed_reg);
 
 /* The movi is not explicitly generated here.  */
 if (ots->val_type == TEMP_VAL_REG) {
@@ -3314,6 +3311,9 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 ots = arg_temp(op->args[0]);
 ts = arg_temp(op->args[1]);
 
+/* ENV should not be modified.  */
+tcg_debug_assert(!ots->fixed_reg);
+
 /* Note that otype != itype for no-op truncation.  */
 otype = ots->type;
 itype = ts->type;
@@ -3338,7 +3338,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 }
 
 tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
-if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
+if (IS_DEAD_ARG(0)) {
 /* mov to a non-saved dead register makes no sense (even with
liveness analysis disabled). */
 tcg_debug_assert(NEED_SYNC_ARG(0));
@@ -3351,7 +3351,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp 
*op)
 }
 temp_dead(s, ots);
 } else {
-if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
+if (IS_DEAD_ARG(1) && !ts->fixed_reg) {
 /* the mov can be suppressed */
 if (ots->val_type == TEMP_VAL_REG) {
 s->reg_to_temp[ots->reg] = NULL;
@@ -3504,6 +3504,10 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 arg = op->args[i];
 arg_ct = >args_ct[i];
 ts = arg_temp(arg);
+
+/* ENV should not be modified.  */
+tcg_debug_assert(!ts->fixed_reg);
+
 if ((arg_ct->ct & TCG_CT_ALIAS)
 && !const_args[arg_ct->alias_index]) {
 reg = new_args[arg_ct->alias_index];
@@ -3512,29 +3516,21 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 i_allocated_regs | o_allocated_regs,
 op->output_pref[k], ts->indirect_base);
 } else {
-/* if fixed register, we try to use it */
-reg = ts->reg;
-if (ts->fixed_reg &&
-tcg_regset_test_reg(arg_ct->u.regs, reg)) {
-goto oarg_end;
-}
 reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
 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 */
-if (!ts->fixed_reg) {
-if (ts->val_type == TEMP_VAL_REG) {
-s->reg_to_temp[ts->reg] = NULL;
-}
-ts->val_type = TEMP_VAL_REG;
-ts->reg = reg;
-/* temp value is modified, so the value kept in memory is
-   potentially not the same */
-ts->mem_coherent = 0;
-s->reg_to_temp[reg] = ts;
+if (ts->val_type == TEMP_VAL_REG) {
+s->reg_to_temp[ts->reg] = NULL;
 }
-oarg_end:
+ts->val_type = TEMP_VAL_REG;
+ts->reg = reg;
+/*
+ * Temp value is modified, so the value kept in memory is
+ * potentially not the same.
+ */
+ts->mem_coherent = 0;
+s->reg_to_temp[reg] = ts;
 new_args[i] = reg;
 }
 }
@@ -3550,10 +3546,10 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
 /* move the outputs in the correct register if needed */
 for(i = 0; i < nb_oargs; i++) {
 ts = arg_temp(op->args[i]);
-reg = new_args[i];
-if (ts->fixed_reg && ts->reg != reg) {
-tcg_out_mov(s, ts->type, ts->reg, reg);
-}
+
+/* ENV should not be modified.  */
+tcg_debug_assert(!ts->fixed_reg);
+
 if (NEED_SYNC_ARG(i)) {
 temp_sync(s, ts, o_allocated_regs, 0, IS_DEAD_ARG(i));
 } else if (IS_DEAD_ARG(i)) {
@@ -3674,26 +3670,23 @@ static void 

[Qemu-devel] [PULL 24/31] target/arm: Use tcg_gen_abs_i64 and tcg_gen_gvec_abs

2019-05-13 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  2 --
 target/arm/neon_helper.c   |  5 -
 target/arm/translate-a64.c | 41 +-
 target/arm/translate.c | 11 +++---
 4 files changed, 8 insertions(+), 51 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 50cb036378..132aa1682e 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -352,8 +352,6 @@ DEF_HELPER_2(neon_ceq_u8, i32, i32, i32)
 DEF_HELPER_2(neon_ceq_u16, i32, i32, i32)
 DEF_HELPER_2(neon_ceq_u32, i32, i32, i32)
 
-DEF_HELPER_1(neon_abs_s8, i32, i32)
-DEF_HELPER_1(neon_abs_s16, i32, i32)
 DEF_HELPER_1(neon_clz_u8, i32, i32)
 DEF_HELPER_1(neon_clz_u16, i32, i32)
 DEF_HELPER_1(neon_cls_s8, i32, i32)
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index ed1c6fc41c..4259056723 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -1228,11 +1228,6 @@ NEON_VOP(ceq_u16, neon_u16, 2)
 NEON_VOP(ceq_u32, neon_u32, 1)
 #undef NEON_FN
 
-#define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
-NEON_VOP1(abs_s8, neon_s8, 4)
-NEON_VOP1(abs_s16, neon_s16, 2)
-#undef NEON_FN
-
 /* Count Leading Sign/Zero Bits.  */
 static inline int do_clz8(uint8_t x)
 {
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 9dcc5ff3a3..b7c5a928b4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -9468,11 +9468,7 @@ static void handle_2misc_64(DisasContext *s, int opcode, 
bool u,
 if (u) {
 tcg_gen_neg_i64(tcg_rd, tcg_rn);
 } else {
-TCGv_i64 tcg_zero = tcg_const_i64(0);
-tcg_gen_neg_i64(tcg_rd, tcg_rn);
-tcg_gen_movcond_i64(TCG_COND_GT, tcg_rd, tcg_rn, tcg_zero,
-tcg_rn, tcg_rd);
-tcg_temp_free_i64(tcg_zero);
+tcg_gen_abs_i64(tcg_rd, tcg_rn);
 }
 break;
 case 0x2f: /* FABS */
@@ -12366,11 +12362,12 @@ static void disas_simd_two_reg_misc(DisasContext *s, 
uint32_t insn)
 }
 break;
 case 0xb:
-if (u) { /* NEG */
+if (u) { /* ABS, NEG */
 gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
-return;
+} else {
+gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size);
 }
-break;
+return;
 }
 
 if (size == 3) {
@@ -12438,17 +12435,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, 
uint32_t insn)
 gen_helper_neon_qabs_s32(tcg_res, cpu_env, tcg_op);
 }
 break;
-case 0xb: /* ABS, NEG */
-if (u) {
-tcg_gen_neg_i32(tcg_res, tcg_op);
-} else {
-TCGv_i32 tcg_zero = tcg_const_i32(0);
-tcg_gen_neg_i32(tcg_res, tcg_op);
-tcg_gen_movcond_i32(TCG_COND_GT, tcg_res, tcg_op,
-tcg_zero, tcg_op, tcg_res);
-tcg_temp_free_i32(tcg_zero);
-}
-break;
 case 0x2f: /* FABS */
 gen_helper_vfp_abss(tcg_res, tcg_op);
 break;
@@ -12561,23 +12547,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_i32(tcg_zero);
 break;
 }
-case 0xb: /* ABS, NEG */
-if (u) {
-TCGv_i32 tcg_zero = tcg_const_i32(0);
-if (size) {
-gen_helper_neon_sub_u16(tcg_res, tcg_zero, tcg_op);
-} else {
-gen_helper_neon_sub_u8(tcg_res, tcg_zero, tcg_op);
-}
-tcg_temp_free_i32(tcg_zero);
-} else {
-if (size) {
-gen_helper_neon_abs_s16(tcg_res, tcg_op);
-} else {
-gen_helper_neon_abs_s8(tcg_res, tcg_op);
-}
-}
-break;
 case 0x4: /* CLS, CLZ */
 if (u) {
 if (size == 0) {
diff --git a/target/arm/translate.c b/target/arm/translate.c
index b25781554f..dd053c80d6 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8120,6 +8120,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 case NEON_2RM_VNEG:
 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
 break;
+case NEON_2RM_VABS:
+tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
+break;
 
 default:
 elementwise:
@@ -8225,14 +8228,6 

[Qemu-devel] [PULL 28/31] target/s390x: Use tcg_gen_abs_i64

2019-05-13 Thread Richard Henderson
Reviewed-by: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
 target/s390x/translate.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index d4951836ad..e8e8a79b7d 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1407,13 +1407,7 @@ static DisasJumpType help_branch(DisasContext *s, 
DisasCompare *c,
 
 static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
 {
-TCGv_i64 z, n;
-z = tcg_const_i64(0);
-n = tcg_temp_new_i64();
-tcg_gen_neg_i64(n, o->in2);
-tcg_gen_movcond_i64(TCG_COND_LT, o->out, o->in2, z, n, o->in2);
-tcg_temp_free_i64(n);
-tcg_temp_free_i64(z);
+tcg_gen_abs_i64(o->out, o->in2);
 return DISAS_NEXT;
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 27/31] target/ppc: Use tcg_gen_abs_tl

2019-05-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/translate.c | 68 +++---
 1 file changed, 24 insertions(+), 44 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 8d08625c33..b5217f632f 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -5075,40 +5075,26 @@ static void gen_ecowx(DisasContext *ctx)
 /* abs - abs. */
 static void gen_abs(DisasContext *ctx)
 {
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
-tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-gen_set_label(l2);
+TCGv d = cpu_gpr[rD(ctx->opcode)];
+TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+tcg_gen_abs_tl(d, a);
 if (unlikely(Rc(ctx->opcode) != 0)) {
-gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+gen_set_Rc0(ctx, d);
 }
 }
 
 /* abso - abso. */
 static void gen_abso(DisasContext *ctx)
 {
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-TCGLabel *l3 = gen_new_label();
-/* Start with XER OV disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ov, 0);
-tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
-tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x8000, l1);
-tcg_gen_movi_tl(cpu_ov, 1);
-tcg_gen_movi_tl(cpu_so, 1);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-tcg_gen_br(l3);
-gen_set_label(l2);
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-gen_set_label(l3);
+TCGv d = cpu_gpr[rD(ctx->opcode)];
+TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_ov, a, 0x8000);
+tcg_gen_abs_tl(d, a);
+tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
 if (unlikely(Rc(ctx->opcode) != 0)) {
-gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+gen_set_Rc0(ctx, d);
 }
 }
 
@@ -5344,34 +5330,28 @@ static void gen_mulo(DisasContext *ctx)
 /* nabs - nabs. */
 static void gen_nabs(DisasContext *ctx)
 {
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-gen_set_label(l2);
+TCGv d = cpu_gpr[rD(ctx->opcode)];
+TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+tcg_gen_abs_tl(d, a);
+tcg_gen_neg_tl(d, d);
 if (unlikely(Rc(ctx->opcode) != 0)) {
-gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+gen_set_Rc0(ctx, d);
 }
 }
 
 /* nabso - nabso. */
 static void gen_nabso(DisasContext *ctx)
 {
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-gen_set_label(l2);
+TCGv d = cpu_gpr[rD(ctx->opcode)];
+TCGv a = cpu_gpr[rA(ctx->opcode)];
+
+tcg_gen_abs_tl(d, a);
+tcg_gen_neg_tl(d, d);
 /* nabs never overflows */
 tcg_gen_movi_tl(cpu_ov, 0);
 if (unlikely(Rc(ctx->opcode) != 0)) {
-gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+gen_set_Rc0(ctx, d);
 }
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 10/31] tcg: Manually expand INDEX_op_dup_vec

2019-05-13 Thread Richard Henderson
This case is similar to INDEX_op_mov_* in that we need to do
different things depending on the current location of the source.

Signed-off-by: Richard Henderson 
---
v3: Added some commentary to the tcg_reg_alloc_* functions.
---
 tcg/aarch64/tcg-target.inc.c |   9 ++-
 tcg/i386/tcg-target.inc.c|   8 +--
 tcg/tcg.c| 111 +++
 3 files changed, 118 insertions(+), 10 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index e443b5df23..3cefdd1e43 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -2108,10 +2108,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
-case INDEX_op_mov_vec:
 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
 case INDEX_op_movi_i64:
-case INDEX_op_dupi_vec:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
 default:
 g_assert_not_reached();
@@ -2208,9 +2206,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_not_vec:
 tcg_out_insn(s, 3617, NOT, is_q, 0, a0, a1);
 break;
-case INDEX_op_dup_vec:
-tcg_out_dup_vec(s, type, vece, a0, a1);
-break;
 case INDEX_op_shli_vec:
 tcg_out_insn(s, 3614, SHL, is_q, a0, a1, a2 + (8 << vece));
 break;
@@ -2254,6 +2249,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 }
 }
 break;
+
+case INDEX_op_mov_vec:  /* Always emitted via tcg_out_mov.  */
+case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi.  */
+case INDEX_op_dup_vec:  /* Always emitted via tcg_out_dup_vec.  */
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 0d621670c7..3c8229d413 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -2603,10 +2603,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 break;
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
-case INDEX_op_mov_vec:
 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
 case INDEX_op_movi_i64:
-case INDEX_op_dupi_vec:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
 default:
 tcg_abort();
@@ -2795,9 +2793,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_st_vec:
 tcg_out_st(s, type, a0, a1, a2);
 break;
-case INDEX_op_dup_vec:
-tcg_out_dup_vec(s, type, vece, a0, a1);
-break;
 
 case INDEX_op_x86_shufps_vec:
 insn = OPC_SHUFPS;
@@ -2839,6 +2834,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 tcg_out8(s, a2);
 break;
 
+case INDEX_op_mov_vec:  /* Always emitted via tcg_out_mov.  */
+case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi.  */
+case INDEX_op_dup_vec:  /* Always emitted via tcg_out_dup_vec.  */
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3ef4d3478d..2b715bf099 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3284,6 +3284,9 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet 
allocated_regs)
 save_globals(s, allocated_regs);
 }
 
+/*
+ * Specialized code generation for INDEX_op_movi_*.
+ */
 static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
   tcg_target_ulong val, TCGLifeData arg_life,
   TCGRegSet preferred_regs)
@@ -3313,6 +3316,9 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp 
*op)
 tcg_reg_alloc_do_movi(s, ots, val, op->life, op->output_pref[0]);
 }
 
+/*
+ * Specialized code generation for INDEX_op_mov_*.
+ */
 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
 {
 const TCGLifeData arg_life = op->life;
@@ -3407,6 +3413,108 @@ static void tcg_reg_alloc_mov(TCGContext *s, const 
TCGOp *op)
 }
 }
 
+/*
+ * Specialized code generation for INDEX_op_dup_vec.
+ */
+static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
+{
+const TCGLifeData arg_life = op->life;
+TCGRegSet dup_out_regs, dup_in_regs;
+TCGTemp *its, *ots;
+TCGType itype, vtype;
+unsigned vece;
+bool ok;
+
+ots = arg_temp(op->args[0]);
+its = arg_temp(op->args[1]);
+
+/* ENV should not be modified.  */
+tcg_debug_assert(!ots->fixed_reg);
+
+itype = its->type;
+vece = TCGOP_VECE(op);
+vtype = TCGOP_VECL(op) + TCG_TYPE_V64;
+
+if (its->val_type == TEMP_VAL_CONST) {
+/* Propagate constant via movi -> dupi.  */
+tcg_target_ulong val = its->val;
+if (IS_DEAD_ARG(1)) {
+temp_dead(s, its);
+}
+tcg_reg_alloc_do_movi(s, ots, val, arg_life, op->output_pref[0]);
+return;
+}
+
+dup_out_regs = 

[Qemu-devel] [PULL 31/31] tcg/aarch64: Do not advertise minmax for MO_64

2019-05-13 Thread Richard Henderson
The min/max instructions are not available for 64-bit elements.

Fixes: 93f332a50371
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 1248dfd04c..40bf35079a 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -2333,16 +2333,16 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_sssub_vec:
 case INDEX_op_usadd_vec:
 case INDEX_op_ussub_vec:
-case INDEX_op_smax_vec:
-case INDEX_op_smin_vec:
-case INDEX_op_umax_vec:
-case INDEX_op_umin_vec:
 case INDEX_op_shlv_vec:
 return 1;
 case INDEX_op_shrv_vec:
 case INDEX_op_sarv_vec:
 return -1;
 case INDEX_op_mul_vec:
+case INDEX_op_smax_vec:
+case INDEX_op_smin_vec:
+case INDEX_op_umax_vec:
+case INDEX_op_umin_vec:
 return vece < MO_64;
 
 default:
-- 
2.17.1




[Qemu-devel] [PULL 09/31] tcg: Promote tcg_out_{dup, dupi}_vec to backend interface

2019-05-13 Thread Richard Henderson
The i386 backend already has these functions, and the aarch64 backend
could easily split out one.  Nothing is done with these functions yet,
but this will aid register allocation of INDEX_op_dup_vec in a later patch.

Adjust the aarch64 tcg_out_dupi_vec signature to match the new interface.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 12 ++--
 tcg/i386/tcg-target.inc.c|  3 ++-
 tcg/tcg.c| 14 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index ee89734318..e443b5df23 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -799,7 +799,7 @@ static void tcg_out_logicali(TCGContext *s, AArch64Insn 
insn, TCGType ext,
 }
 
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
- TCGReg rd, uint64_t v64)
+ TCGReg rd, tcg_target_long v64)
 {
 int op, cmode, imm8;
 
@@ -814,6 +814,14 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 }
 }
 
+static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
+TCGReg rd, TCGReg rs)
+{
+int is_q = type - TCG_TYPE_V64;
+tcg_out_insn(s, 3605, DUP, is_q, rd, rs, 1 << vece, 0);
+return true;
+}
+
 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
  tcg_target_long value)
 {
@@ -2201,7 +2209,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 tcg_out_insn(s, 3617, NOT, is_q, 0, a0, a1);
 break;
 case INDEX_op_dup_vec:
-tcg_out_insn(s, 3605, DUP, is_q, a0, a1, 1 << vece, 0);
+tcg_out_dup_vec(s, type, vece, a0, a1);
 break;
 case INDEX_op_shli_vec:
 tcg_out_insn(s, 3614, SHL, is_q, a0, a1, a2 + (8 << vece));
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 1198c76392..0d621670c7 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -855,7 +855,7 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg 
ret, TCGReg arg)
 return true;
 }
 
-static void tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
+static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
 TCGReg r, TCGReg a)
 {
 if (have_avx2) {
@@ -888,6 +888,7 @@ static void tcg_out_dup_vec(TCGContext *s, TCGType type, 
unsigned vece,
 g_assert_not_reached();
 }
 }
+return true;
 }
 
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 68d86361e2..3ef4d3478d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -109,10 +109,24 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
const int *const_args);
 #if TCG_TARGET_MAYBE_vec
+static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
+TCGReg dst, TCGReg src);
+static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
+ TCGReg dst, tcg_target_long arg);
 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
unsigned vece, const TCGArg *args,
const int *const_args);
 #else
+static inline bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
+   TCGReg dst, TCGReg src)
+{
+g_assert_not_reached();
+}
+static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type,
+TCGReg dst, tcg_target_long arg)
+{
+g_assert_not_reached();
+}
 static inline void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
   unsigned vece, const TCGArg *args,
   const int *const_args)
-- 
2.17.1




[Qemu-devel] [PULL 19/31] tcg/i386: Support vector scalar shift opcodes

2019-05-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.h |  2 +-
 tcg/i386/tcg-target.inc.c | 35 +++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b240633455..618aa520d2 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -183,7 +183,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_not_vec  0
 #define TCG_TARGET_HAS_neg_vec  0
 #define TCG_TARGET_HAS_shi_vec  1
-#define TCG_TARGET_HAS_shs_vec  0
+#define TCG_TARGET_HAS_shs_vec  1
 #define TCG_TARGET_HAS_shv_vec  have_avx2
 #define TCG_TARGET_HAS_cmp_vec  1
 #define TCG_TARGET_HAS_mul_vec  1
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index c9448b6d84..0ba1587da4 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -420,6 +420,14 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_PSHIFTW_Ib  (0x71 | P_EXT | P_DATA16) /* /2 /6 /4 */
 #define OPC_PSHIFTD_Ib  (0x72 | P_EXT | P_DATA16) /* /2 /6 /4 */
 #define OPC_PSHIFTQ_Ib  (0x73 | P_EXT | P_DATA16) /* /2 /6 /4 */
+#define OPC_PSLLW   (0xf1 | P_EXT | P_DATA16)
+#define OPC_PSLLD   (0xf2 | P_EXT | P_DATA16)
+#define OPC_PSLLQ   (0xf3 | P_EXT | P_DATA16)
+#define OPC_PSRAW   (0xe1 | P_EXT | P_DATA16)
+#define OPC_PSRAD   (0xe2 | P_EXT | P_DATA16)
+#define OPC_PSRLW   (0xd1 | P_EXT | P_DATA16)
+#define OPC_PSRLD   (0xd2 | P_EXT | P_DATA16)
+#define OPC_PSRLQ   (0xd3 | P_EXT | P_DATA16)
 #define OPC_PSUBB   (0xf8 | P_EXT | P_DATA16)
 #define OPC_PSUBW   (0xf9 | P_EXT | P_DATA16)
 #define OPC_PSUBD   (0xfa | P_EXT | P_DATA16)
@@ -2724,6 +2732,15 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 /* TODO: AVX512 adds support for MO_16, MO_64.  */
 OPC_UD2, OPC_UD2, OPC_VPSRAVD, OPC_UD2
 };
+static int const shls_insn[4] = {
+OPC_UD2, OPC_PSLLW, OPC_PSLLD, OPC_PSLLQ
+};
+static int const shrs_insn[4] = {
+OPC_UD2, OPC_PSRLW, OPC_PSRLD, OPC_PSRLQ
+};
+static int const sars_insn[4] = {
+OPC_UD2, OPC_PSRAW, OPC_PSRAD, OPC_UD2
+};
 
 TCGType type = vecl + TCG_TYPE_V64;
 int insn, sub;
@@ -2785,6 +2802,15 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_sarv_vec:
 insn = sarv_insn[vece];
 goto gen_simd;
+case INDEX_op_shls_vec:
+insn = shls_insn[vece];
+goto gen_simd;
+case INDEX_op_shrs_vec:
+insn = shrs_insn[vece];
+goto gen_simd;
+case INDEX_op_sars_vec:
+insn = sars_insn[vece];
+goto gen_simd;
 case INDEX_op_x86_punpckl_vec:
 insn = punpckl_insn[vece];
 goto gen_simd;
@@ -3165,6 +3191,9 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_shlv_vec:
 case INDEX_op_shrv_vec:
 case INDEX_op_sarv_vec:
+case INDEX_op_shls_vec:
+case INDEX_op_shrs_vec:
+case INDEX_op_sars_vec:
 case INDEX_op_cmp_vec:
 case INDEX_op_x86_shufps_vec:
 case INDEX_op_x86_blend_vec:
@@ -3222,6 +3251,12 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 }
 return 1;
 
+case INDEX_op_shls_vec:
+case INDEX_op_shrs_vec:
+return vece >= MO_16;
+case INDEX_op_sars_vec:
+return vece >= MO_16 && vece <= MO_32;
+
 case INDEX_op_shlv_vec:
 case INDEX_op_shrv_vec:
 return have_avx2 && vece >= MO_32;
-- 
2.17.1




[Qemu-devel] [PULL 12/31] tcg/i386: Implement tcg_out_dupm_vec

2019-05-13 Thread Richard Henderson
At the same time, improve tcg_out_dupi_vec wrt broadcast
from the constant pool.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.inc.c | 57 +--
 1 file changed, 43 insertions(+), 14 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index f04933bc19..f4bd00e24f 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -358,7 +358,6 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_MOVBE_MyGy  (0xf1 | P_EXT38)
 #define OPC_MOVD_VyEy   (0x6e | P_EXT | P_DATA16)
 #define OPC_MOVD_EyVy   (0x7e | P_EXT | P_DATA16)
-#define OPC_MOVDDUP (0x12 | P_EXT | P_SIMDF2)
 #define OPC_MOVDQA_VxWx (0x6f | P_EXT | P_DATA16)
 #define OPC_MOVDQA_WxVx (0x7f | P_EXT | P_DATA16)
 #define OPC_MOVDQU_VxWx (0x6f | P_EXT | P_SIMDF3)
@@ -458,6 +457,10 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_UD2 (0x0b | P_EXT)
 #define OPC_VPBLENDD(0x02 | P_EXT3A | P_DATA16)
 #define OPC_VPBLENDVB   (0x4c | P_EXT3A | P_DATA16)
+#define OPC_VPINSRB (0x20 | P_EXT3A | P_DATA16)
+#define OPC_VPINSRW (0xc4 | P_EXT | P_DATA16)
+#define OPC_VBROADCASTSS (0x18 | P_EXT38 | P_DATA16)
+#define OPC_VBROADCASTSD (0x19 | P_EXT38 | P_DATA16)
 #define OPC_VPBROADCASTB (0x78 | P_EXT38 | P_DATA16)
 #define OPC_VPBROADCASTW (0x79 | P_EXT38 | P_DATA16)
 #define OPC_VPBROADCASTD (0x58 | P_EXT38 | P_DATA16)
@@ -855,16 +858,17 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, 
TCGReg ret, TCGReg arg)
 return true;
 }
 
+static const int avx2_dup_insn[4] = {
+OPC_VPBROADCASTB, OPC_VPBROADCASTW,
+OPC_VPBROADCASTD, OPC_VPBROADCASTQ,
+};
+
 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
 TCGReg r, TCGReg a)
 {
 if (have_avx2) {
-static const int dup_insn[4] = {
-OPC_VPBROADCASTB, OPC_VPBROADCASTW,
-OPC_VPBROADCASTD, OPC_VPBROADCASTQ,
-};
 int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0);
-tcg_out_vex_modrm(s, dup_insn[vece] + vex_l, r, 0, a);
+tcg_out_vex_modrm(s, avx2_dup_insn[vece] + vex_l, r, 0, a);
 } else {
 switch (vece) {
 case MO_8:
@@ -894,10 +898,35 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, 
unsigned vece,
 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
  TCGReg r, TCGReg base, intptr_t offset)
 {
-return false;
+if (have_avx2) {
+int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0);
+tcg_out_vex_modrm_offset(s, avx2_dup_insn[vece] + vex_l,
+ r, 0, base, offset);
+} else {
+switch (vece) {
+case MO_64:
+tcg_out_vex_modrm_offset(s, OPC_VBROADCASTSD, r, 0, base, offset);
+break;
+case MO_32:
+tcg_out_vex_modrm_offset(s, OPC_VBROADCASTSS, r, 0, base, offset);
+break;
+case MO_16:
+tcg_out_vex_modrm_offset(s, OPC_VPINSRW, r, r, base, offset);
+tcg_out8(s, 0); /* imm8 */
+tcg_out_dup_vec(s, type, vece, r, r);
+break;
+case MO_8:
+tcg_out_vex_modrm_offset(s, OPC_VPINSRB, r, r, base, offset);
+tcg_out8(s, 0); /* imm8 */
+tcg_out_dup_vec(s, type, vece, r, r);
+break;
+default:
+g_assert_not_reached();
+}
+}
+return true;
 }
 
-
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
  TCGReg ret, tcg_target_long arg)
 {
@@ -918,16 +947,16 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 } else if (have_avx2) {
 tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTQ + vex_l, ret);
 } else {
-tcg_out_vex_modrm_pool(s, OPC_MOVDDUP, ret);
+tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSD, ret);
 }
 new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
-} else if (have_avx2) {
-tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
-new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0);
 } else {
-tcg_out_vex_modrm_pool(s, OPC_MOVD_VyEy, ret);
+if (have_avx2) {
+tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSD + vex_l, ret);
+} else {
+tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
+}
 new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0);
-tcg_out_dup_vec(s, type, MO_32, ret, ret);
 }
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 02/31] tcg: Do not recreate INDEX_op_neg_vec unless supported

2019-05-13 Thread Richard Henderson
Use tcg_can_emit_vec_op instead of just TCG_TARGET_HAS_neg_vec,
so that we check the type and vece for the actual operation.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/optimize.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 5150c38a25..24faa06260 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -734,9 +734,13 @@ void tcg_optimize(TCGContext *s)
 } else if (opc == INDEX_op_sub_i64) {
 neg_op = INDEX_op_neg_i64;
 have_neg = TCG_TARGET_HAS_neg_i64;
-} else {
+} else if (TCG_TARGET_HAS_neg_vec) {
+TCGType type = TCGOP_VECL(op) + TCG_TYPE_V64;
+unsigned vece = TCGOP_VECE(op);
 neg_op = INDEX_op_neg_vec;
-have_neg = TCG_TARGET_HAS_neg_vec;
+have_neg = tcg_can_emit_vec_op(neg_op, type, vece) > 0;
+} else {
+break;
 }
 if (!have_neg) {
 break;
-- 
2.17.1




[Qemu-devel] [PULL 13/31] tcg/aarch64: Implement tcg_out_dupm_vec

2019-05-13 Thread Richard Henderson
The LD1R instruction does all the work.  Note that the only
useful addressing mode is a base register with no offset.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 37 ++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 4a3cfa778a..b4585724d3 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -381,6 +381,9 @@ typedef enum {
 I3207_BLR   = 0xd63f,
 I3207_RET   = 0xd65f,
 
+/* AdvSIMD load/store single structure.  */
+I3303_LD1R  = 0x0d40c000,
+
 /* Load literal for loading the address at pc-relative offset */
 I3305_LDR   = 0x5800,
 I3305_LDR_v64   = 0x5c00,
@@ -566,7 +569,14 @@ static inline uint32_t tcg_in32(TCGContext *s)
 #define tcg_out_insn(S, FMT, OP, ...) \
 glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
 
-static void tcg_out_insn_3305(TCGContext *s, AArch64Insn insn, int imm19, 
TCGReg rt)
+static void tcg_out_insn_3303(TCGContext *s, AArch64Insn insn, bool q,
+  TCGReg rt, TCGReg rn, unsigned size)
+{
+tcg_out32(s, insn | (rt & 0x1f) | (rn << 5) | (size << 10) | (q << 30));
+}
+
+static void tcg_out_insn_3305(TCGContext *s, AArch64Insn insn,
+  int imm19, TCGReg rt)
 {
 tcg_out32(s, insn | (imm19 & 0x7) << 5 | rt);
 }
@@ -825,7 +835,30 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, 
unsigned vece,
 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
  TCGReg r, TCGReg base, intptr_t offset)
 {
-return false;
+TCGReg temp = TCG_REG_TMP;
+
+if (offset < -0xff || offset > 0xff) {
+tcg_out_movi(s, TCG_TYPE_PTR, temp, offset);
+tcg_out_insn(s, 3502, ADD, 1, temp, temp, base);
+base = temp;
+} else {
+AArch64Insn add_insn = I3401_ADDI;
+
+if (offset < 0) {
+add_insn = I3401_SUBI;
+offset = -offset;
+}
+if (offset & 0xfff000) {
+tcg_out_insn_3401(s, add_insn, 1, temp, base, offset & 0xfff000);
+base = temp;
+}
+if (offset & 0xfff) {
+tcg_out_insn_3401(s, add_insn, 1, temp, base, offset & 0xfff);
+base = temp;
+}
+}
+tcg_out_insn(s, 3303, LD1R, type == TCG_TYPE_V128, r, base, vece);
+return true;
 }
 
 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
-- 
2.17.1




[Qemu-devel] [PULL 07/31] tcg: Return bool success from tcg_out_mov

2019-05-13 Thread Richard Henderson
This patch merely changes the interface, aborting on all failures,
of which there are currently none.

Reviewed-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: David Gibson 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c |  5 +++--
 tcg/arm/tcg-target.inc.c |  3 ++-
 tcg/i386/tcg-target.inc.c|  5 +++--
 tcg/mips/tcg-target.inc.c|  3 ++-
 tcg/ppc/tcg-target.inc.c |  3 ++-
 tcg/riscv/tcg-target.inc.c   |  5 +++--
 tcg/s390/tcg-target.inc.c|  3 ++-
 tcg/sparc/tcg-target.inc.c   |  3 ++-
 tcg/tcg.c| 14 ++
 tcg/tci/tcg-target.inc.c |  3 ++-
 10 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index eefa929948..ee89734318 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -938,10 +938,10 @@ static void tcg_out_ldst(TCGContext *s, AArch64Insn insn, 
TCGReg rd,
 tcg_out_ldst_r(s, insn, rd, rn, TCG_TYPE_I64, TCG_REG_TMP);
 }
 
-static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 {
 if (ret == arg) {
-return;
+return true;
 }
 switch (type) {
 case TCG_TYPE_I32:
@@ -970,6 +970,7 @@ static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg 
ret, TCGReg arg)
 default:
 g_assert_not_reached();
 }
+return true;
 }
 
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index 130b6bef1e..7316504c9d 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -2264,10 +2264,11 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType 
type, TCGArg val,
 return false;
 }
 
-static inline void tcg_out_mov(TCGContext *s, TCGType type,
+static inline bool tcg_out_mov(TCGContext *s, TCGType type,
TCGReg ret, TCGReg arg)
 {
 tcg_out_mov_reg(s, COND_AL, ret, arg);
+return true;
 }
 
 static inline void tcg_out_movi(TCGContext *s, TCGType type,
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index d5ed9f1ffd..1198c76392 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -809,12 +809,12 @@ static inline void tgen_arithr(TCGContext *s, int subop, 
int dest, int src)
 tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
 }
 
-static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 {
 int rexw = 0;
 
 if (arg == ret) {
-return;
+return true;
 }
 switch (type) {
 case TCG_TYPE_I64:
@@ -852,6 +852,7 @@ static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg 
ret, TCGReg arg)
 default:
 g_assert_not_reached();
 }
+return true;
 }
 
 static void tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c
index 412cacdcb9..7cafd4a790 100644
--- a/tcg/mips/tcg-target.inc.c
+++ b/tcg/mips/tcg-target.inc.c
@@ -558,13 +558,14 @@ static inline void tcg_out_dsra(TCGContext *s, TCGReg rd, 
TCGReg rt, TCGArg sa)
 tcg_out_opc_sa64(s, OPC_DSRA, OPC_DSRA32, rd, rt, sa);
 }
 
-static inline void tcg_out_mov(TCGContext *s, TCGType type,
+static inline bool tcg_out_mov(TCGContext *s, TCGType type,
TCGReg ret, TCGReg arg)
 {
 /* Simple reg-reg move, optimising out the 'do nothing' case */
 if (ret != arg) {
 tcg_out_opc_reg(s, OPC_OR, ret, arg, TCG_REG_ZERO);
 }
+return true;
 }
 
 static void tcg_out_movi(TCGContext *s, TCGType type,
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
index 36b4791707..30c095d3d5 100644
--- a/tcg/ppc/tcg-target.inc.c
+++ b/tcg/ppc/tcg-target.inc.c
@@ -559,12 +559,13 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
  TCGReg base, tcg_target_long offset);
 
-static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 {
 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 if (ret != arg) {
 tcg_out32(s, OR | SAB(arg, ret, arg));
 }
+return true;
 }
 
 static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 2932505094..6497a4dab2 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -515,10 +515,10 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
  * TCG intrinsics
  */
 
-static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+static bool 

Re: [Qemu-devel] [PATCH] cadence_gem: Don't define GEM_INT_Q1_MASK twice

2019-05-13 Thread Alistair Francis
On Mon, May 13, 2019 at 12:57 PM Jonathan Behrens  wrote:
>
> Signed-off-by: Jonathan Behrens 

Good find. Thanks for the patch!

Reviewed-by: Alistair Francis 

Can this go via your tree Jason?

Alistair

> ---
>  hw/net/cadence_gem.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
> index 7f63411430..37cb8a4e5c 100644
> --- a/hw/net/cadence_gem.c
> +++ b/hw/net/cadence_gem.c
> @@ -146,7 +146,6 @@
>  #define GEM_DESCONF7  (0x0298/4)
>
>  #define GEM_INT_Q1_STATUS   (0x0400 / 4)
> -#define GEM_INT_Q1_MASK (0x0640 / 4)
>
>  #define GEM_TRANSMIT_Q1_PTR (0x0440 / 4)
>  #define GEM_TRANSMIT_Q7_PTR (GEM_TRANSMIT_Q1_PTR + 6)
> --
> 2.20.1
>



Re: [Qemu-devel] [PATCH] configure: Disable slirp if --disable-system

2019-05-13 Thread Richard Henderson
On 5/11/19 5:47 AM, Aleksandar Markovic wrote:
> 
> On May 10, 2019 10:36 PM, "Richard Henderson"  > wrote:
>>
>> For linux-user, there is no need to add slirp to the set of
>> git modules checked out, nor build it.
>>
>> This also avoids a makefile bug wrt insufficient dependencies
>> on subdir-slirp.  If slirp/ is not initially present, the
>> dependencies that check it out are associated with softmmu,
>> which then generates a build error on slirp/ not present.
>>
> 
> Hi,
> 
> Does this work if only user mode targets are specified via ˊ--target-listˊ
> switch?

Yes.  There is a bit of code that converts such a target list to the same
result as --disable-system, which is $softmmu = no.

> If no, the patch shoud be amended. If yes, the commit message should be
> extended.

Like what?  I think it's pretty clear as is.


r~



[Qemu-devel] [Bug 1828867] Re: QEmu translation is incorrect when using REX in combination with LAHF/SAHF

2019-05-13 Thread Alex Bennée
** Tags added: tcg testcase x86

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

Title:
  QEmu translation is incorrect when using REX in combination with
  LAHF/SAHF

Status in QEMU:
  New

Bug description:
  When translating code that is using LAHF and SAHF in combination with the REX 
prefix then qemu translates incorrectly.
  These two instructions only ever use the AH register. Contrary to other 
instructions where if you use REX + high bit offsets then it'll pull in rsp and 
a few other registers.
  On hardware the REX prefix doesn't effect behaviour of these instructions at 
all.
  QEMU incorrectly selects RSP as the register of choice here due to this 
combination of REX + AH register usage.

  I've attached a patch that is super terrible just so I can work around
  the issue locally and to sort of show off how it is to be "fixed"

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



Re: [Qemu-devel] [Qemu-block] [PATCH v3 1/3] block: introducing 'bdrv_co_delete_file' interface

2019-05-13 Thread John Snow
It looks like this one has gone un-noticed for a little while.

On 3/26/19 5:17 PM, Daniel Henrique Barboza wrote:
> Adding to Block Drivers the capability of being able to clean up
> its created files can be useful in certain situations. For the
> LUKS driver, for instance, a failure in one of its authentication
> steps can leave files in the host that weren't there before.
> 
> This patch adds the 'bdrv_co_delete_file' interface to block
> drivers and add it to the 'file' driver in file-posix.c. The
> implementation is given by 'raw_co_delete_file'. The helper
> 'bdrv_path_is_regular_file' is being used only in raw_co_delete_file
> at this moment, but it will be used inside LUKS in a later patch.
> Foreseeing this future use, let's put it in block.c and make it
> public.
> 
> Suggested-by: Daniel P. Berrangé 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  block.c   | 11 +++
>  block/file-posix.c| 28 
>  include/block/block.h |  1 +
>  include/block/block_int.h |  6 ++
>  4 files changed, 46 insertions(+)
> 
> diff --git a/block.c b/block.c
> index 0a93ee9ac8..227362b282 100644
> --- a/block.c
> +++ b/block.c
> @@ -621,6 +621,17 @@ int get_tmp_filename(char *filename, int size)
>  #endif
>  }
>  
> +/**
> + * Helper that checks if a given string represents a regular
> + * local file.
> + */
> +bool bdrv_path_is_regular_file(const char *path)
> +{
> +struct stat st;
> +
> +return (stat(path, ) == 0) && S_ISREG(st.st_mode);
> +}
> +
>  /*
>   * Detect host devices. By convention, /dev/cdrom[N] is always
>   * recognized as a host CDROM.
> diff --git a/block/file-posix.c b/block/file-posix.c
> index d102f3b222..09d84bab37 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2342,6 +2342,33 @@ static int coroutine_fn raw_co_create_opts(const char 
> *filename, QemuOpts *opts,
>  return raw_co_create(, errp);
>  }
>  
> +/**
> + * Co-routine function that erases a regular file.
> + */
> +static int coroutine_fn raw_co_delete_file(const char *filename,
> +   Error **errp)

Do we need to mark functions that make no use of coroutines as
coroutine_fn? I guess this way the interface is *allowed* to be a
coroutine if other drivers need to make use of that.

> +{
> +int ret;
> +
> +/* Skip file: protocol prefix */
> +strstart(filename, "file:", );
> +

This sticks out as fragile to me, but I guess that's exactly how create
works, so... OK.

> +if (!bdrv_path_is_regular_file(filename)) {
> +ret = -ENOENT;
> +error_setg_errno(errp, -ret, "%s is not a regular file", filename);
> +goto done;
> +}
> +
> +ret = unlink(filename);
> +if (ret < 0) {
> +ret = -errno;
> +error_setg_errno(errp, -ret, "Error when deleting file %s", 
> filename);
> +}
> +
> +done:
> +return ret;
> +}
> +
>  /*
>   * Find allocation range in @bs around offset @start.
>   * May change underlying file descriptor's file offset.
> @@ -2867,6 +2894,7 @@ BlockDriver bdrv_file = {
>  .bdrv_co_block_status = raw_co_block_status,
>  .bdrv_co_invalidate_cache = raw_co_invalidate_cache,
>  .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
> +.bdrv_co_delete_file = raw_co_delete_file,
>  
>  .bdrv_co_preadv = raw_co_preadv,
>  .bdrv_co_pwritev= raw_co_pwritev,
> diff --git a/include/block/block.h b/include/block/block.h
> index e452988b66..820643f96d 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -363,6 +363,7 @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, 
> BlockDriverState *base,
>Error **errp);
>  void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState 
> *base);
>  
> +bool bdrv_path_is_regular_file(const char *path);
>  
>  typedef struct BdrvCheckResult {
>  int corruptions;
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 01e855a066..74abb78ce7 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -309,6 +309,12 @@ struct BlockDriver {
>   */
>  int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
>  
> +/*
> + * Delete a local created file.
> + */
> +int coroutine_fn (*bdrv_co_delete_file)(const char *filename,
> +Error **errp);
> +
>  /*
>   * Flushes all data that was already written to the OS all the way down 
> to
>   * the disk (for example file-posix.c calls fsync()).
> 

Seems alright at a glance, if we want this interface.

Kevin, do we?

--js



[Qemu-devel] [PATCH] cadence_gem: Don't define GEM_INT_Q1_MASK twice

2019-05-13 Thread Jonathan Behrens
Signed-off-by: Jonathan Behrens 
---
 hw/net/cadence_gem.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 7f63411430..37cb8a4e5c 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -146,7 +146,6 @@
 #define GEM_DESCONF7  (0x0298/4)
 
 #define GEM_INT_Q1_STATUS   (0x0400 / 4)
-#define GEM_INT_Q1_MASK (0x0640 / 4)
 
 #define GEM_TRANSMIT_Q1_PTR (0x0440 / 4)
 #define GEM_TRANSMIT_Q7_PTR (GEM_TRANSMIT_Q1_PTR + 6)
-- 
2.20.1



Re: [Qemu-devel] [PATCH v2] iotests: Filter 175's allocation information

2019-05-13 Thread Nir Soffer
On Mon, May 13, 2019, 18:52 Max Reitz  wrote:

> It is possible for an empty file to take up blocks on a filesystem.
> Make iotest 175 take this into account.
>
> Reported-by: Thomas Huth 
> Signed-off-by: Max Reitz 
> ---
> v2: [Nir]
> - Use a function for filtering
> - s/empty_blocks/extra_blocks/
> ---
>  tests/qemu-iotests/175 | 26 ++
>  tests/qemu-iotests/175.out |  8 
>  2 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
> index d0ffc495c2..b5eb0aa856 100755
> --- a/tests/qemu-iotests/175
> +++ b/tests/qemu-iotests/175
> @@ -28,10 +28,25 @@ status=1# failure is the default!
>
>  _cleanup()
>  {
> -   _cleanup_test_img
> +_cleanup_test_img
> +rm -f "$TEST_DIR/empty"
>  }
>  trap "_cleanup; exit \$status" 0 1 2 3 15
>
> +# Some file systems sometimes allocate extra blocks independently of
> +# the file size.  This function hides the resulting difference in the
> +# stat -c '%b' output.
> +# Parameter 1: Number of blocks an empty file occupies
> +# Parameter 2: Image size in bytes
> +_filter_blocks()
> +{
> +extra_blocks=$1
> +img_size=$2
> +
> +sed -e "s/blocks=$extra_blocks/nothing allocated/" \
> +-e "s/blocks=$((extra_blocks + img_size / 512))/everything
> allocated/"
> +}
> +
>  # get standard environment, filters and checks
>  . ./common.rc
>  . ./common.filter
> @@ -40,18 +55,21 @@ _supported_fmt raw
>  _supported_proto file
>  _supported_os Linux
>
> -size=1m
> +size=$((1 * 1024 * 1024))
> +
> +touch "$TEST_DIR/empty"
> +extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
>
>  echo
>  echo "== creating image with default preallocation =="
>  _make_test_img $size | _filter_imgfmt
> -stat -c "size=%s, blocks=%b" $TEST_IMG
> +stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks
> $size
>
>  for mode in off full falloc; do
>  echo
>  echo "== creating image with preallocation $mode =="
>  IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
> -stat -c "size=%s, blocks=%b" $TEST_IMG
> +stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks
> $size
>  done
>
>  # success, all done
> diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
> index 76c02c6a57..6d9a5ed84e 100644
> --- a/tests/qemu-iotests/175.out
> +++ b/tests/qemu-iotests/175.out
> @@ -2,17 +2,17 @@ QA output created by 175
>
>  == creating image with default preallocation ==
>  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
> -size=1048576, blocks=0
> +size=1048576, nothing allocated
>
>  == creating image with preallocation off ==
>  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off
> -size=1048576, blocks=0
> +size=1048576, nothing allocated
>
>  == creating image with preallocation full ==
>  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full
> -size=1048576, blocks=2048
> +size=1048576, everything allocated
>
>  == creating image with preallocation falloc ==
>  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
> preallocation=falloc
> -size=1048576, blocks=2048
> +size=1048576, everything allocated
>   *** done
> --
> 2.21.0


Reviewed-by: Nir Soffer 

>


Re: [Qemu-devel] [PATCH 00/13] target/arm/kvm: enable SVE in guests

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 11:46:29AM -0700, Richard Henderson wrote:
> On 5/12/19 1:36 AM, Andrew Jones wrote:
> >CPU type | accel | sve-max-vq | sve-vls-map
> >---
> >  1) max | tcg   |  $MAX_VQ   |  $VLS_MAP
> >  2) max | kvm   |  $MAX_VQ   |  $VLS_MAP
> >  3)host | kvm   |  N/A   |  $VLS_MAP
> 
> This doesn't seem right.  Why is -cpu host not whatever the host supports?  It
> certainly has been so far. 

-cpu host can support whatever the host (hardware + KVM ) supports, but if
a user doesn't want to expose all of it to the guest, then the user doesn't
have to. For example, the host cpu may have a PMU, but the guest doesn't
necessarily get one (-cpu host,pmu=off).

> I really don't see how -cpu max makes any sense for
> kvm.
>

It's already supported for kvm. This series just extends that support
to match tcg's sve support. The reason it's supported is that you can
then use '-cpu max' along with '-machine accel=kvm:tcg' in a command
line and it'll just work.
 
> 
> > The QMP query returns a list of valid vq lists. For example, if
> > a guest can use vqs 1, 2, 3, and 4, then the following list will
> > be returned
> > 
> >  [ [ 1 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 2, 3, 4 ] ]
> > 
> > Another example might be 1, 2, 4, as the architecture states 3
> > is optional. In that case the list would be
> > 
> >  [ [ 1 ], [ 1, 2 ], [ 1, 2, 4 ] ]
> > 
> > This may look redundant, but it's necessary to provide a future-
> > proof query, because while KVM currently requires vector sets to
> > be strict truncations of the full valid vector set, that may change
> > at some point.
> 
> How and why would that make sense?
> 
> Real hardware is going to support one set of vector lengths.

The guest's view of the hardware will be a single set. That set can be
different for different guests though, within the constraints of the
architecture and KVM or TCG implementations.

> Whether VQ=3 is
> valid or not is not going to depend on the maximum VQ, surely.

Exactly. That's why we need a way to explicitly state what is supported.
We can't assume anything from the max VQ alone. Additionally, while
strict truncation is required now for KVM, things may be more flexible
later. TCG is already more flexible. For TCG, all sets that at least
include all the power-of-2 lengths up to the maximum VQ are valid, as
the architecture states. Plus, all the sets that can be derived by adding
one ore more optional lengths to those sets are also valid. Listing each
of them allows management software to know what's going to work and what's
not without having to know all the rules itself.

> 
> I'll also note that if we want to support the theoretical
> beyond-current-architecture maximum VQ=512, such that migration works
> seemlessly with current hardware, then we're going to have to change the
> migration format.
> 
> So far I'm supporting only the current architecture maximum VQ=16.  Which
> seemed plenty, given that the first round of hardware only supports VQ=4.
> 

I agree. The changes won't be small to QEMU, but hopefully we can design
a QMP query that won't need to change, saving libvirt some pain.

Thanks,
drew



Re: [Qemu-devel] [Qemu-block] [PATCH] nvme: add Get/Set Feature Timestamp support

2019-05-13 Thread John Snow



On 4/9/19 9:19 AM, Stefan Hajnoczi wrote:
> On Fri, Apr 05, 2019 at 03:41:17PM -0600, Kenneth Heitke wrote:
>> Signed-off-by: Kenneth Heitke 
>> ---
>>  hw/block/nvme.c   | 120 +-
>>  hw/block/nvme.h   |   3 ++
>>  hw/block/trace-events |   2 +
>>  include/block/nvme.h  |   2 +
>>  4 files changed, 125 insertions(+), 2 deletions(-)
> 
> CCing Maxim Levitsky , who is also working on NVMe
> emulation at the moment.
> 

Did this patch stall? Do we still want it? Do we need reviewers?



[Qemu-devel] [Bug 1823458] Update Released

2019-05-13 Thread Corey Bryant
The verification of the Stable Release Update for qemu has completed
successfully and the package has now been released to -updates. In the
event that you encounter a regression using the package from -updates
please report a new bug using ubuntu-bug and tag the bug report
regression-update so we can easily find any regressions.

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

Title:
  race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown
  crashes qemu

Status in Ubuntu Cloud Archive:
  Fix Released
Status in Ubuntu Cloud Archive mitaka series:
  Fix Released
Status in Ubuntu Cloud Archive ocata series:
  Fix Released
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Won't Fix
Status in qemu source package in Xenial:
  Fix Released
Status in qemu source package in Bionic:
  Fix Released
Status in qemu source package in Cosmic:
  Fix Released
Status in qemu source package in Disco:
  Fix Released

Bug description:
  [impact]

  on shutdown of a guest, there is a race condition that results in qemu
  crashing instead of normally shutting down.  The bt looks similar to
  this (depending on the specific version of qemu, of course; this is
  taken from 2.5 version of qemu):

  (gdb) bt
  #0  __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
  #1  0x5636c0bc4389 in qemu_mutex_lock (mutex=mutex@entry=0x0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/util/qemu-thread-posix.c:73
  #2  0x5636c0988130 in qemu_chr_fe_write_all (s=s@entry=0x0, 
buf=buf@entry=0x7ffe65c086a0 "\v", len=len@entry=20) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/qemu-char.c:205
  #3  0x5636c08f3483 in vhost_user_write (msg=msg@entry=0x7ffe65c086a0, 
fds=fds@entry=0x0, fd_num=fd_num@entry=0, dev=0x5636c1bf6b70, 
dev=0x5636c1bf6b70)
  at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:195
  #4  0x5636c08f411c in vhost_user_get_vring_base (dev=0x5636c1bf6b70, 
ring=0x7ffe65c087e0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:364
  #5  0x5636c08efff0 in vhost_virtqueue_stop (dev=dev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338, vq=0x5636c1bf6d00, idx=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:895
  #6  0x5636c08f2944 in vhost_dev_stop (hdev=hdev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:1262
  #7  0x5636c08db2a8 in vhost_net_stop_one (net=0x5636c1bf6b70, 
dev=dev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:293
  #8  0x5636c08dbe5b in vhost_net_stop (dev=dev@entry=0x5636c2853338, 
ncs=0x5636c209d110, total_queues=total_queues@entry=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:371
  #9  0x5636c08d7745 in virtio_net_vhost_status (status=7 '\a', 
n=0x5636c2853338) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:150
  #10 virtio_net_set_status (vdev=, status=) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:162
  #11 0x5636c08ec42c in virtio_set_status (vdev=0x5636c2853338, 
val=) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/virtio.c:624
  #12 0x5636c098fed2 in vm_state_notify (running=running@entry=0, 
state=state@entry=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1605
  #13 0x5636c089172a in do_vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:724
  #14 vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:1407
  #15 0x5636c085d240 in main_loop_should_exit () at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1883
  #16 main_loop () at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1931
  #17 main (argc=, argv=, envp=) 
at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:4683

  [test case]

  unfortunately since this is a race condition, it's very hard to
  arbitrarily reproduce; it depends very much on the overall
  configuration of the guest as well as how exactly it's shut down -
  specifically, its vhost user net must be closed from the host side at
  a specific time during qemu shutdown.

  I have someone with such a setup who has reported to me their setup is
  able to reproduce this reliably, but the config is too complex for me
  to reproduce so I have relied on their reproduction and testing to
  debug and craft the patch for this.

  [regression potential]

  the change adds a flag to prevent repeated calls to vhost_net_stop().
  This also prevents any calls to vhost_net_cleanup() from
  net_vhost_user_event().  Any regression would be seen when stopping
  and/or cleaning up a vhost net.  Regressions might include failure to
  hot-remove a vhost net from a guest, or failure to cleanup (i.e. mem
  leak), or crashes during cleanup or stopping a vhost net.

  [other info]

  this was originally seen in the 2.5 version of qemu - specifically,
  the UCA version in 

[Qemu-devel] [Bug 1823458] Re: race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown crashes qemu

2019-05-13 Thread Corey Bryant
This bug was fixed in the package qemu - 1:2.8+dfsg-3ubuntu2.9~cloud5.1
---

 qemu (1:2.8+dfsg-3ubuntu2.9~cloud5.1) xenial-ocata; urgency=medium
 .
   * d/p/lp1823458/add-VirtIONet-vhost_stopped-flag-to-prevent-multiple.patch,
 d/p/lp1823458/do-not-call-vhost_net_cleanup-on-running-net-from-ch.patch:
 - Prevent crash due to race condition on shutdown;
   this is fixed differently upstream (starting in Bionic), but
   the change is too large to backport into Xenial.  These two very
   small patches work around the problem in an unintrusive way.
   (LP: #1823458)


** Changed in: cloud-archive/ocata
   Status: Fix Committed => Fix Released

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

Title:
  race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown
  crashes qemu

Status in Ubuntu Cloud Archive:
  Fix Released
Status in Ubuntu Cloud Archive mitaka series:
  Fix Released
Status in Ubuntu Cloud Archive ocata series:
  Fix Released
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Won't Fix
Status in qemu source package in Xenial:
  Fix Released
Status in qemu source package in Bionic:
  Fix Released
Status in qemu source package in Cosmic:
  Fix Released
Status in qemu source package in Disco:
  Fix Released

Bug description:
  [impact]

  on shutdown of a guest, there is a race condition that results in qemu
  crashing instead of normally shutting down.  The bt looks similar to
  this (depending on the specific version of qemu, of course; this is
  taken from 2.5 version of qemu):

  (gdb) bt
  #0  __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
  #1  0x5636c0bc4389 in qemu_mutex_lock (mutex=mutex@entry=0x0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/util/qemu-thread-posix.c:73
  #2  0x5636c0988130 in qemu_chr_fe_write_all (s=s@entry=0x0, 
buf=buf@entry=0x7ffe65c086a0 "\v", len=len@entry=20) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/qemu-char.c:205
  #3  0x5636c08f3483 in vhost_user_write (msg=msg@entry=0x7ffe65c086a0, 
fds=fds@entry=0x0, fd_num=fd_num@entry=0, dev=0x5636c1bf6b70, 
dev=0x5636c1bf6b70)
  at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:195
  #4  0x5636c08f411c in vhost_user_get_vring_base (dev=0x5636c1bf6b70, 
ring=0x7ffe65c087e0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:364
  #5  0x5636c08efff0 in vhost_virtqueue_stop (dev=dev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338, vq=0x5636c1bf6d00, idx=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:895
  #6  0x5636c08f2944 in vhost_dev_stop (hdev=hdev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:1262
  #7  0x5636c08db2a8 in vhost_net_stop_one (net=0x5636c1bf6b70, 
dev=dev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:293
  #8  0x5636c08dbe5b in vhost_net_stop (dev=dev@entry=0x5636c2853338, 
ncs=0x5636c209d110, total_queues=total_queues@entry=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:371
  #9  0x5636c08d7745 in virtio_net_vhost_status (status=7 '\a', 
n=0x5636c2853338) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:150
  #10 virtio_net_set_status (vdev=, status=) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:162
  #11 0x5636c08ec42c in virtio_set_status (vdev=0x5636c2853338, 
val=) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/virtio.c:624
  #12 0x5636c098fed2 in vm_state_notify (running=running@entry=0, 
state=state@entry=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1605
  #13 0x5636c089172a in do_vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:724
  #14 vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:1407
  #15 0x5636c085d240 in main_loop_should_exit () at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1883
  #16 main_loop () at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1931
  #17 main (argc=, argv=, envp=) 
at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:4683

  [test case]

  unfortunately since this is a race condition, it's very hard to
  arbitrarily reproduce; it depends very much on the overall
  configuration of the guest as well as how exactly it's shut down -
  specifically, its vhost user net must be closed from the host side at
  a specific time during qemu shutdown.

  I have someone with such a setup who has reported to me their setup is
  able to reproduce this reliably, but the config is too complex for me
  to reproduce so I have relied on their reproduction and testing to
  debug and craft the patch for this.

  [regression potential]

  the change adds a flag to prevent repeated calls to vhost_net_stop().
  This also prevents any calls to vhost_net_cleanup() from
  net_vhost_user_event().  

[Qemu-devel] [Bug 1823458] Re: race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown crashes qemu

2019-05-13 Thread Corey Bryant
This bug was fixed in the package qemu - 1:2.5+dfsg-5ubuntu10.37~cloud0
---

 qemu (1:2.5+dfsg-5ubuntu10.37~cloud0) trusty-mitaka; urgency=medium
 .
   * New update for the Ubuntu Cloud Archive.
 .
 qemu (1:2.5+dfsg-5ubuntu10.37) xenial; urgency=medium
 .
   * d/p/lp1823458/add-VirtIONet-vhost_stopped-flag-to-prevent-multiple.patch,
 d/p/lp1823458/do-not-call-vhost_net_cleanup-on-running-net-from-ch.patch:
 - Prevent crash due to race condition on shutdown;
   this is fixed differently upstream (starting in Bionic), but
   the change is too large to backport into Xenial.  These two very
   small patches work around the problem in an unintrusive way.
   (LP: #1823458)


** Changed in: cloud-archive/mitaka
   Status: Fix Committed => Fix Released

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

Title:
  race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown
  crashes qemu

Status in Ubuntu Cloud Archive:
  Fix Released
Status in Ubuntu Cloud Archive mitaka series:
  Fix Released
Status in Ubuntu Cloud Archive ocata series:
  Fix Released
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Won't Fix
Status in qemu source package in Xenial:
  Fix Released
Status in qemu source package in Bionic:
  Fix Released
Status in qemu source package in Cosmic:
  Fix Released
Status in qemu source package in Disco:
  Fix Released

Bug description:
  [impact]

  on shutdown of a guest, there is a race condition that results in qemu
  crashing instead of normally shutting down.  The bt looks similar to
  this (depending on the specific version of qemu, of course; this is
  taken from 2.5 version of qemu):

  (gdb) bt
  #0  __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
  #1  0x5636c0bc4389 in qemu_mutex_lock (mutex=mutex@entry=0x0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/util/qemu-thread-posix.c:73
  #2  0x5636c0988130 in qemu_chr_fe_write_all (s=s@entry=0x0, 
buf=buf@entry=0x7ffe65c086a0 "\v", len=len@entry=20) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/qemu-char.c:205
  #3  0x5636c08f3483 in vhost_user_write (msg=msg@entry=0x7ffe65c086a0, 
fds=fds@entry=0x0, fd_num=fd_num@entry=0, dev=0x5636c1bf6b70, 
dev=0x5636c1bf6b70)
  at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:195
  #4  0x5636c08f411c in vhost_user_get_vring_base (dev=0x5636c1bf6b70, 
ring=0x7ffe65c087e0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:364
  #5  0x5636c08efff0 in vhost_virtqueue_stop (dev=dev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338, vq=0x5636c1bf6d00, idx=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:895
  #6  0x5636c08f2944 in vhost_dev_stop (hdev=hdev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:1262
  #7  0x5636c08db2a8 in vhost_net_stop_one (net=0x5636c1bf6b70, 
dev=dev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:293
  #8  0x5636c08dbe5b in vhost_net_stop (dev=dev@entry=0x5636c2853338, 
ncs=0x5636c209d110, total_queues=total_queues@entry=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:371
  #9  0x5636c08d7745 in virtio_net_vhost_status (status=7 '\a', 
n=0x5636c2853338) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:150
  #10 virtio_net_set_status (vdev=, status=) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:162
  #11 0x5636c08ec42c in virtio_set_status (vdev=0x5636c2853338, 
val=) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/virtio.c:624
  #12 0x5636c098fed2 in vm_state_notify (running=running@entry=0, 
state=state@entry=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1605
  #13 0x5636c089172a in do_vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:724
  #14 vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:1407
  #15 0x5636c085d240 in main_loop_should_exit () at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1883
  #16 main_loop () at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1931
  #17 main (argc=, argv=, envp=) 
at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:4683

  [test case]

  unfortunately since this is a race condition, it's very hard to
  arbitrarily reproduce; it depends very much on the overall
  configuration of the guest as well as how exactly it's shut down -
  specifically, its vhost user net must be closed from the host side at
  a specific time during qemu shutdown.

  I have someone with such a setup who has reported to me their setup is
  able to reproduce this reliably, but the config is too complex for me
  to reproduce so I have relied on their reproduction and testing to
  debug and craft the patch for this.

  [regression potential]

  the change adds a flag to prevent repeated calls 

[Qemu-devel] [Bug 1823458] Update Released

2019-05-13 Thread Corey Bryant
The verification of the Stable Release Update for qemu has completed
successfully and the package has now been released to -updates. In the
event that you encounter a regression using the package from -updates
please report a new bug using ubuntu-bug and tag the bug report
regression-update so we can easily find any regressions.

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

Title:
  race condition between vhost_net_stop and CHR_EVENT_CLOSED on shutdown
  crashes qemu

Status in Ubuntu Cloud Archive:
  Fix Released
Status in Ubuntu Cloud Archive mitaka series:
  Fix Released
Status in Ubuntu Cloud Archive ocata series:
  Fix Released
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Won't Fix
Status in qemu source package in Xenial:
  Fix Released
Status in qemu source package in Bionic:
  Fix Released
Status in qemu source package in Cosmic:
  Fix Released
Status in qemu source package in Disco:
  Fix Released

Bug description:
  [impact]

  on shutdown of a guest, there is a race condition that results in qemu
  crashing instead of normally shutting down.  The bt looks similar to
  this (depending on the specific version of qemu, of course; this is
  taken from 2.5 version of qemu):

  (gdb) bt
  #0  __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
  #1  0x5636c0bc4389 in qemu_mutex_lock (mutex=mutex@entry=0x0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/util/qemu-thread-posix.c:73
  #2  0x5636c0988130 in qemu_chr_fe_write_all (s=s@entry=0x0, 
buf=buf@entry=0x7ffe65c086a0 "\v", len=len@entry=20) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/qemu-char.c:205
  #3  0x5636c08f3483 in vhost_user_write (msg=msg@entry=0x7ffe65c086a0, 
fds=fds@entry=0x0, fd_num=fd_num@entry=0, dev=0x5636c1bf6b70, 
dev=0x5636c1bf6b70)
  at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:195
  #4  0x5636c08f411c in vhost_user_get_vring_base (dev=0x5636c1bf6b70, 
ring=0x7ffe65c087e0) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost-user.c:364
  #5  0x5636c08efff0 in vhost_virtqueue_stop (dev=dev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338, vq=0x5636c1bf6d00, idx=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:895
  #6  0x5636c08f2944 in vhost_dev_stop (hdev=hdev@entry=0x5636c1bf6b70, 
vdev=vdev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/vhost.c:1262
  #7  0x5636c08db2a8 in vhost_net_stop_one (net=0x5636c1bf6b70, 
dev=dev@entry=0x5636c2853338) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:293
  #8  0x5636c08dbe5b in vhost_net_stop (dev=dev@entry=0x5636c2853338, 
ncs=0x5636c209d110, total_queues=total_queues@entry=1) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/vhost_net.c:371
  #9  0x5636c08d7745 in virtio_net_vhost_status (status=7 '\a', 
n=0x5636c2853338) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:150
  #10 virtio_net_set_status (vdev=, status=) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/hw/net/virtio-net.c:162
  #11 0x5636c08ec42c in virtio_set_status (vdev=0x5636c2853338, 
val=) at /build/qemu-7I4i1R/qemu-2.5+dfsg/hw/virtio/virtio.c:624
  #12 0x5636c098fed2 in vm_state_notify (running=running@entry=0, 
state=state@entry=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1605
  #13 0x5636c089172a in do_vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:724
  #14 vm_stop (state=RUN_STATE_SHUTDOWN) at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/cpus.c:1407
  #15 0x5636c085d240 in main_loop_should_exit () at 
/build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1883
  #16 main_loop () at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:1931
  #17 main (argc=, argv=, envp=) 
at /build/qemu-7I4i1R/qemu-2.5+dfsg/vl.c:4683

  [test case]

  unfortunately since this is a race condition, it's very hard to
  arbitrarily reproduce; it depends very much on the overall
  configuration of the guest as well as how exactly it's shut down -
  specifically, its vhost user net must be closed from the host side at
  a specific time during qemu shutdown.

  I have someone with such a setup who has reported to me their setup is
  able to reproduce this reliably, but the config is too complex for me
  to reproduce so I have relied on their reproduction and testing to
  debug and craft the patch for this.

  [regression potential]

  the change adds a flag to prevent repeated calls to vhost_net_stop().
  This also prevents any calls to vhost_net_cleanup() from
  net_vhost_user_event().  Any regression would be seen when stopping
  and/or cleaning up a vhost net.  Regressions might include failure to
  hot-remove a vhost net from a guest, or failure to cleanup (i.e. mem
  leak), or crashes during cleanup or stopping a vhost net.

  [other info]

  this was originally seen in the 2.5 version of qemu - specifically,
  the UCA version in 

[Qemu-devel] [PATCH v7 8/8] hw/display: add vhost-user-vga & gpu-pci

2019-05-13 Thread Marc-André Lureau
Add new virtio-gpu devices with a "vhost-user" property. The
associated vhost-user backend is used to handle the virtio rings and
provide rendering results thanks to the vhost-user-gpu protocol.

Example usage:
-object vhost-user-backend,id=vug,cmd="./vhost-user-gpu"
-device vhost-user-vga,vhost-user=vug

Signed-off-by: Marc-André Lureau 
---
 hw/display/virtio-vga.h|   2 +-
 include/hw/virtio/virtio-gpu-pci.h |  40 ++
 include/hw/virtio/virtio-gpu.h |  19 +-
 hw/display/vhost-user-gpu-pci.c|  51 +++
 hw/display/vhost-user-gpu.c| 607 +
 hw/display/vhost-user-vga.c|  52 +++
 hw/display/virtio-gpu-pci.c|  17 +-
 vl.c   |   1 +
 hw/display/Kconfig |  10 +
 hw/display/Makefile.objs   |   3 +
 10 files changed, 779 insertions(+), 23 deletions(-)
 create mode 100644 include/hw/virtio/virtio-gpu-pci.h
 create mode 100644 hw/display/vhost-user-gpu-pci.c
 create mode 100644 hw/display/vhost-user-gpu.c
 create mode 100644 hw/display/vhost-user-vga.c

diff --git a/hw/display/virtio-vga.h b/hw/display/virtio-vga.h
index f03e1ba619..c10bf390aa 100644
--- a/hw/display/virtio-vga.h
+++ b/hw/display/virtio-vga.h
@@ -1,7 +1,7 @@
 #ifndef VIRTIO_VGA_H_
 #define VIRTIO_VGA_H_
 
-#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-gpu-pci.h"
 #include "vga_int.h"
 
 /*
diff --git a/include/hw/virtio/virtio-gpu-pci.h 
b/include/hw/virtio/virtio-gpu-pci.h
new file mode 100644
index 00..2f69b5a9cc
--- /dev/null
+++ b/include/hw/virtio/virtio-gpu-pci.h
@@ -0,0 +1,40 @@
+/*
+ * Virtio GPU PCI Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ * Dave Airlie 
+ * Gerd Hoffmann 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_VIRTIO_GPU_PCI_H
+#define HW_VIRTIO_GPU_PCI_H
+
+#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-gpu.h"
+
+typedef struct VirtIOGPUPCIBase VirtIOGPUPCIBase;
+
+/*
+ * virtio-gpu-pci-base: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_GPU_PCI_BASE "virtio-gpu-pci-base"
+#define VIRTIO_GPU_PCI_BASE(obj)\
+OBJECT_CHECK(VirtIOGPUPCIBase, (obj), TYPE_VIRTIO_GPU_PCI_BASE)
+
+struct VirtIOGPUPCIBase {
+VirtIOPCIProxy parent_obj;
+VirtIOGPUBase *vgpu;
+};
+
+/* to share between PCI and VGA */
+#define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state)\
+DEFINE_PROP_BIT("ioeventfd", _state, flags, \
+VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),  \
+DEFINE_PROP_UINT32("vectors", _state, nvectors, 3)
+
+#endif /* HW_VIRTIO_GPU_PCI_H */
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index d0d8d7b246..8ecac1987a 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -19,6 +19,7 @@
 #include "ui/console.h"
 #include "hw/virtio/virtio.h"
 #include "qemu/log.h"
+#include "sysemu/vhost-user-backend.h"
 
 #include "standard-headers/linux/virtio_gpu.h"
 
@@ -34,6 +35,8 @@
 #define VIRTIO_GPU(obj)\
 OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU)
 
+#define TYPE_VHOST_USER_GPU "vhost-user-gpu"
+
 #define VIRTIO_ID_GPU 16
 
 struct virtio_gpu_simple_resource {
@@ -157,13 +160,17 @@ typedef struct VirtIOGPU {
 } stats;
 } VirtIOGPU;
 
-extern const GraphicHwOps virtio_gpu_ops;
+typedef struct VhostUserGPU {
+VirtIOGPUBase parent_obj;
 
-/* to share between PCI and VGA */
-#define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state)   \
-DEFINE_PROP_BIT("ioeventfd", _state, flags,\
-VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), \
-DEFINE_PROP_UINT32("vectors", _state, nvectors, 3)
+VhostUserBackend *vhost;
+int vhost_gpu_fd; /* closed by the chardev */
+CharBackend vhost_chr;
+QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
+bool backend_blocked;
+} VhostUserGPU;
+
+extern const GraphicHwOps virtio_gpu_ops;
 
 #define VIRTIO_GPU_FILL_CMD(out) do {   \
 size_t s;   \
diff --git a/hw/display/vhost-user-gpu-pci.c b/hw/display/vhost-user-gpu-pci.c
new file mode 100644
index 00..7d9b1f5a8c
--- /dev/null
+++ b/hw/display/vhost-user-gpu-pci.c
@@ -0,0 +1,51 @@
+/*
+ * vhost-user GPU PCI device
+ *
+ * Copyright Red Hat, Inc. 2018
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/virtio/virtio-gpu-pci.h"
+
+#define TYPE_VHOST_USER_GPU_PCI "vhost-user-gpu-pci"
+#define VHOST_USER_GPU_PCI(obj) \
+OBJECT_CHECK(VhostUserGPUPCI, (obj), TYPE_VHOST_USER_GPU_PCI)
+
+typedef struct VhostUserGPUPCI {
+

[Qemu-devel] [PATCH v7 5/8] contrib: add vhost-user-gpu

2019-05-13 Thread Marc-André Lureau
Add a vhost-user gpu backend, based on virtio-gpu/3d device. It is to
be associated with a vhost-user-gpu device.

Various TODO and nice to have items:
- multi-head support
- crash & resume handling
- accelerated rendering/display that avoids the waiting round trips
- edid support

Signed-off-by: Marc-André Lureau 
---
 configure  |   17 +
 contrib/vhost-user-gpu/virgl.h |   25 +
 contrib/vhost-user-gpu/vugbm.h |   67 ++
 contrib/vhost-user-gpu/vugpu.h |  177 +++
 contrib/vhost-user-gpu/main.c  | 1185 
 contrib/vhost-user-gpu/virgl.c |  579 ++
 contrib/vhost-user-gpu/vugbm.c |  331 ++
 MAINTAINERS|2 +
 Makefile   |   24 +-
 Makefile.objs  |1 +
 contrib/vhost-user-gpu/50-qemu-gpu.json.in |5 +
 contrib/vhost-user-gpu/Makefile.objs   |   10 +
 rules.mak  |9 +-
 13 files changed, 2430 insertions(+), 2 deletions(-)
 create mode 100644 contrib/vhost-user-gpu/virgl.h
 create mode 100644 contrib/vhost-user-gpu/vugbm.h
 create mode 100644 contrib/vhost-user-gpu/vugpu.h
 create mode 100644 contrib/vhost-user-gpu/main.c
 create mode 100644 contrib/vhost-user-gpu/virgl.c
 create mode 100644 contrib/vhost-user-gpu/vugbm.c
 create mode 100644 contrib/vhost-user-gpu/50-qemu-gpu.json.in
 create mode 100644 contrib/vhost-user-gpu/Makefile.objs

diff --git a/configure b/configure
index 8999698bc2..8d0f3edf84 100755
--- a/configure
+++ b/configure
@@ -4086,6 +4086,13 @@ libs_softmmu="$libs_softmmu $fdt_libs"
 ##
 # opengl probe (for sdl2, gtk, milkymist-tmu2)
 
+gbm="no"
+if $pkg_config gbm; then
+gbm_cflags="$($pkg_config --cflags gbm)"
+gbm_libs="$($pkg_config --libs gbm)"
+gbm="yes"
+fi
+
 if test "$opengl" != "no" ; then
   opengl_pkgs="epoxy gbm"
   if $pkg_config $opengl_pkgs; then
@@ -6935,6 +6942,13 @@ if test "$opengl" = "yes" ; then
   fi
 fi
 
+if test "$gbm" = "yes" ; then
+echo "CONFIG_GBM=y" >> $config_host_mak
+echo "GBM_LIBS=$gbm_libs" >> $config_host_mak
+echo "GBM_CFLAGS=$gbm_cflags" >> $config_host_mak
+fi
+
+
 if test "$malloc_trim" = "yes" ; then
   echo "CONFIG_MALLOC_TRIM=y" >> $config_host_mak
 fi
@@ -7828,6 +7842,9 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
 
 done # for target in $targets
 
+echo "PIXMAN_CFLAGS=$pixman_cflags" >> $config_host_mak
+echo "PIXMAN_LIBS=$pixman_libs" >> $config_host_mak
+
 if test -n "$enabled_cross_compilers"; then
 echo
 echo "NOTE: cross-compilers enabled: $enabled_cross_compilers"
diff --git a/contrib/vhost-user-gpu/virgl.h b/contrib/vhost-user-gpu/virgl.h
new file mode 100644
index 00..f952bc9d4f
--- /dev/null
+++ b/contrib/vhost-user-gpu/virgl.h
@@ -0,0 +1,25 @@
+/*
+ * Virtio vhost-user GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2018
+ *
+ * Authors:
+ * Dave Airlie 
+ * Gerd Hoffmann 
+ * Marc-André Lureau 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef VUGPU_VIRGL_H_
+#define VUGPU_VIRGL_H_
+
+#include "vugpu.h"
+
+bool vg_virgl_init(VuGpu *g);
+uint32_t vg_virgl_get_num_capsets(void);
+void vg_virgl_process_cmd(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
+void vg_virgl_update_cursor_data(VuGpu *g, uint32_t resource_id,
+ gpointer data);
+
+#endif
diff --git a/contrib/vhost-user-gpu/vugbm.h b/contrib/vhost-user-gpu/vugbm.h
new file mode 100644
index 00..c0bf27af9b
--- /dev/null
+++ b/contrib/vhost-user-gpu/vugbm.h
@@ -0,0 +1,67 @@
+/*
+ * Virtio vhost-user GPU Device
+ *
+ * GBM helpers
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef VHOST_USER_GPU_GBM_H
+#define VHOST_USER_GPU_GBM_H
+
+#include "qemu/osdep.h"
+
+#ifdef CONFIG_MEMFD
+#include 
+#include 
+#endif
+
+#ifdef CONFIG_GBM
+#include 
+#endif
+
+struct vugbm_buffer;
+
+struct vugbm_device {
+bool inited;
+int fd;
+#ifdef CONFIG_GBM
+struct gbm_device *dev;
+#endif
+
+bool (*alloc_bo)(struct vugbm_buffer *buf);
+void (*free_bo)(struct vugbm_buffer *buf);
+bool (*get_fd)(struct vugbm_buffer *buf, int *fd);
+bool (*map_bo)(struct vugbm_buffer *buf);
+void (*unmap_bo)(struct vugbm_buffer *buf);
+void (*device_destroy)(struct vugbm_device *dev);
+};
+
+struct vugbm_buffer {
+struct vugbm_device *dev;
+
+#ifdef CONFIG_MEMFD
+int memfd;
+#endif
+#ifdef CONFIG_GBM
+struct gbm_bo *bo;
+void *mmap_data;
+#endif
+
+uint8_t *mmap;
+uint32_t width;
+uint32_t height;
+uint32_t stride;
+uint32_t format;
+};
+
+bool vugbm_device_init(struct vugbm_device *dev, int fd);
+void vugbm_device_destroy(struct vugbm_device *dev);
+

Re: [Qemu-devel] [PATCH 00/13] target/arm/kvm: enable SVE in guests

2019-05-13 Thread Richard Henderson
On 5/12/19 1:36 AM, Andrew Jones wrote:
>CPU type | accel | sve-max-vq | sve-vls-map
>---
>  1) max | tcg   |  $MAX_VQ   |  $VLS_MAP
>  2) max | kvm   |  $MAX_VQ   |  $VLS_MAP
>  3)host | kvm   |  N/A   |  $VLS_MAP

This doesn't seem right.  Why is -cpu host not whatever the host supports?  It
certainly has been so far.  I really don't see how -cpu max makes any sense for
kvm.


> The QMP query returns a list of valid vq lists. For example, if
> a guest can use vqs 1, 2, 3, and 4, then the following list will
> be returned
> 
>  [ [ 1 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 2, 3, 4 ] ]
> 
> Another example might be 1, 2, 4, as the architecture states 3
> is optional. In that case the list would be
> 
>  [ [ 1 ], [ 1, 2 ], [ 1, 2, 4 ] ]
> 
> This may look redundant, but it's necessary to provide a future-
> proof query, because while KVM currently requires vector sets to
> be strict truncations of the full valid vector set, that may change
> at some point.

How and why would that make sense?

Real hardware is going to support one set of vector lengths.  Whether VQ=3 is
valid or not is not going to depend on the maximum VQ, surely.

I'll also note that if we want to support the theoretical
beyond-current-architecture maximum VQ=512, such that migration works
seemlessly with current hardware, then we're going to have to change the
migration format.

So far I'm supporting only the current architecture maximum VQ=16.  Which
seemed plenty, given that the first round of hardware only supports VQ=4.



r~



[Qemu-devel] [PATCH v7 7/8] virtio-gpu: split virtio-gpu-pci & virtio-vga

2019-05-13 Thread Marc-André Lureau
Add base classes that are common to vhost-user-gpu-pci and
vhost-user-vga.

Signed-off-by: Marc-André Lureau 
---
 hw/display/virtio-vga.h |  32 +
 hw/display/virtio-gpu-pci.c |  52 +-
 hw/display/virtio-vga.c | 135 ++--
 MAINTAINERS |   2 +-
 4 files changed, 137 insertions(+), 84 deletions(-)
 create mode 100644 hw/display/virtio-vga.h

diff --git a/hw/display/virtio-vga.h b/hw/display/virtio-vga.h
new file mode 100644
index 00..f03e1ba619
--- /dev/null
+++ b/hw/display/virtio-vga.h
@@ -0,0 +1,32 @@
+#ifndef VIRTIO_VGA_H_
+#define VIRTIO_VGA_H_
+
+#include "hw/virtio/virtio-pci.h"
+#include "vga_int.h"
+
+/*
+ * virtio-vga-base: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_VGA_BASE "virtio-vga-base"
+#define VIRTIO_VGA_BASE(obj)\
+OBJECT_CHECK(VirtIOVGABase, (obj), TYPE_VIRTIO_VGA_BASE)
+#define VIRTIO_VGA_BASE_GET_CLASS(obj)  \
+OBJECT_GET_CLASS(VirtIOVGABaseClass, obj, TYPE_VIRTIO_VGA_BASE)
+#define VIRTIO_VGA_BASE_CLASS(klass)\
+OBJECT_CLASS_CHECK(VirtIOVGABaseClass, klass, TYPE_VIRTIO_VGA_BASE)
+
+typedef struct VirtIOVGABase {
+VirtIOPCIProxy parent_obj;
+
+VirtIOGPUBase *vgpu;
+VGACommonState vga;
+MemoryRegion vga_mrs[3];
+} VirtIOVGABase;
+
+typedef struct VirtIOVGABaseClass {
+VirtioPCIClass parent_class;
+
+DeviceReset parent_reset;
+} VirtIOVGABaseClass;
+
+#endif /* VIRTIO_VGA_H_ */
diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index 305ea5fff3..3b88bf4d1f 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -19,30 +19,30 @@
 #include "hw/virtio/virtio-pci.h"
 #include "hw/virtio/virtio-gpu.h"
 
-typedef struct VirtIOGPUPCI VirtIOGPUPCI;
+typedef struct VirtIOGPUPCIBase VirtIOGPUPCIBase;
 
 /*
- * virtio-gpu-pci: This extends VirtioPCIProxy.
+ * virtio-gpu-pci-base: This extends VirtioPCIProxy.
  */
-#define TYPE_VIRTIO_GPU_PCI "virtio-gpu-pci"
-#define VIRTIO_GPU_PCI(obj) \
-OBJECT_CHECK(VirtIOGPUPCI, (obj), TYPE_VIRTIO_GPU_PCI)
+#define TYPE_VIRTIO_GPU_PCI_BASE "virtio-gpu-pci-base"
+#define VIRTIO_GPU_PCI_BASE(obj) \
+OBJECT_CHECK(VirtIOGPUPCIBase, (obj), TYPE_VIRTIO_GPU_PCI_BASE)
 
-struct VirtIOGPUPCI {
+struct VirtIOGPUPCIBase {
 VirtIOPCIProxy parent_obj;
-VirtIOGPU vdev;
+VirtIOGPUBase *vgpu;
 };
 
-static Property virtio_gpu_pci_properties[] = {
+static Property virtio_gpu_pci_base_properties[] = {
 DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+static void virtio_gpu_pci_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 {
-VirtIOGPUPCI *vgpu = VIRTIO_GPU_PCI(vpci_dev);
-VirtIOGPUBase *g = VIRTIO_GPU_BASE(>vdev);
-DeviceState *vdev = DEVICE(>vdev);
+VirtIOGPUPCIBase *vgpu = VIRTIO_GPU_PCI_BASE(vpci_dev);
+VirtIOGPUBase *g = vgpu->vgpu;
+DeviceState *vdev = DEVICE(g);
 int i;
 Error *local_error = NULL;
 
@@ -62,36 +62,56 @@ static void virtio_gpu_pci_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 }
 }
 
-static void virtio_gpu_pci_class_init(ObjectClass *klass, void *data)
+static void virtio_gpu_pci_base_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
 PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
 
 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
-dc->props = virtio_gpu_pci_properties;
+dc->props = virtio_gpu_pci_base_properties;
 dc->hotpluggable = false;
-k->realize = virtio_gpu_pci_realize;
+k->realize = virtio_gpu_pci_base_realize;
 pcidev_k->class_id = PCI_CLASS_DISPLAY_OTHER;
 }
 
+static const TypeInfo virtio_gpu_pci_base_info = {
+.name = TYPE_VIRTIO_GPU_PCI_BASE,
+.parent = TYPE_VIRTIO_PCI,
+.instance_size = sizeof(VirtIOGPUPCIBase),
+.class_init = virtio_gpu_pci_base_class_init,
+.abstract = true
+};
+
+#define TYPE_VIRTIO_GPU_PCI "virtio-gpu-pci"
+#define VIRTIO_GPU_PCI(obj) \
+OBJECT_CHECK(VirtIOGPUPCI, (obj), TYPE_VIRTIO_GPU_PCI)
+
+typedef struct VirtIOGPUPCI {
+VirtIOGPUPCIBase parent_obj;
+VirtIOGPU vdev;
+} VirtIOGPUPCI;
+
 static void virtio_gpu_initfn(Object *obj)
 {
 VirtIOGPUPCI *dev = VIRTIO_GPU_PCI(obj);
 
 virtio_instance_init_common(obj, >vdev, sizeof(dev->vdev),
 TYPE_VIRTIO_GPU);
+VIRTIO_GPU_PCI_BASE(obj)->vgpu = VIRTIO_GPU_BASE(>vdev);
 }
 
 static const VirtioPCIDeviceTypeInfo virtio_gpu_pci_info = {
 .generic_name = TYPE_VIRTIO_GPU_PCI,
+.parent = TYPE_VIRTIO_GPU_PCI_BASE,
 .instance_size = sizeof(VirtIOGPUPCI),
 .instance_init = virtio_gpu_initfn,
-.class_init = virtio_gpu_pci_class_init,
 };
 
 static void virtio_gpu_pci_register_types(void)
 {
+

[Qemu-devel] [PATCH v7 3/8] virtio-gpu: add a pixman helper header

2019-05-13 Thread Marc-André Lureau
This will allow to share the format conversion function with
vhost-user-gpu.

Signed-off-by: Marc-André Lureau 
---
 include/hw/virtio/virtio-gpu-pixman.h | 45 +++
 hw/display/virtio-gpu.c   | 29 ++---
 2 files changed, 48 insertions(+), 26 deletions(-)
 create mode 100644 include/hw/virtio/virtio-gpu-pixman.h

diff --git a/include/hw/virtio/virtio-gpu-pixman.h 
b/include/hw/virtio/virtio-gpu-pixman.h
new file mode 100644
index 00..4dba782758
--- /dev/null
+++ b/include/hw/virtio/virtio-gpu-pixman.h
@@ -0,0 +1,45 @@
+/*
+ * Virtio GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ * Dave Airlie 
+ * Gerd Hoffmann 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_VIRTIO_GPU_PIXMAN_H
+#define HW_VIRTIO_GPU_PIXMAN_H
+
+#include "ui/qemu-pixman.h"
+#include "standard-headers/linux/virtio_gpu.h"
+
+static inline pixman_format_code_t
+virtio_gpu_get_pixman_format(uint32_t virtio_gpu_format)
+{
+switch (virtio_gpu_format) {
+case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
+return PIXMAN_BE_b8g8r8x8;
+case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
+return PIXMAN_BE_b8g8r8a8;
+case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
+return PIXMAN_BE_x8r8g8b8;
+case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
+return PIXMAN_BE_a8r8g8b8;
+case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
+return PIXMAN_BE_r8g8b8x8;
+case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
+return PIXMAN_BE_r8g8b8a8;
+case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
+return PIXMAN_BE_x8b8g8r8;
+case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
+return PIXMAN_BE_a8b8g8r8;
+default:
+return 0;
+}
+}
+
+#endif
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index c35025b6fb..3262f7f1f1 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -21,6 +21,7 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
 #include "hw/virtio/virtio-gpu-bswap.h"
+#include "hw/virtio/virtio-gpu-pixman.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/display/edid.h"
 #include "migration/blocker.h"
@@ -298,30 +299,6 @@ void virtio_gpu_get_edid(VirtIOGPU *g,
 virtio_gpu_ctrl_response(g, cmd, , sizeof(edid));
 }
 
-static pixman_format_code_t get_pixman_format(uint32_t virtio_gpu_format)
-{
-switch (virtio_gpu_format) {
-case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
-return PIXMAN_BE_b8g8r8x8;
-case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
-return PIXMAN_BE_b8g8r8a8;
-case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
-return PIXMAN_BE_x8r8g8b8;
-case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
-return PIXMAN_BE_a8r8g8b8;
-case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
-return PIXMAN_BE_r8g8b8x8;
-case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
-return PIXMAN_BE_r8g8b8a8;
-case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
-return PIXMAN_BE_x8b8g8r8;
-case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
-return PIXMAN_BE_a8b8g8r8;
-default:
-return 0;
-}
-}
-
 static uint32_t calc_image_hostmem(pixman_format_code_t pformat,
uint32_t width, uint32_t height)
 {
@@ -368,7 +345,7 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
 res->format = c2d.format;
 res->resource_id = c2d.resource_id;
 
-pformat = get_pixman_format(c2d.format);
+pformat = virtio_gpu_get_pixman_format(c2d.format);
 if (!pformat) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: host couldn't handle guest format %d\n",
@@ -1142,7 +1119,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, 
size_t size,
 res->iov_cnt = qemu_get_be32(f);
 
 /* allocate */
-pformat = get_pixman_format(res->format);
+pformat = virtio_gpu_get_pixman_format(res->format);
 if (!pformat) {
 g_free(res);
 return -EINVAL;
-- 
2.21.0.777.g83232e3864




[Qemu-devel] [PATCH v7 6/8] virtio-gpu: split virtio-gpu, introduce virtio-gpu-base

2019-05-13 Thread Marc-André Lureau
Add a base class that is common to virtio-gpu and vhost-user-gpu
devices.

The VirtIOGPUBase base class provides common functionalities necessary
for both virtio-gpu and vhost-user-gpu:
- common configuration (max-outputs, initial resolution, flags)
- virtio device initialization, including queue setup
- device pre-conditions checks (iommu)
- migration blocker
- virtio device callbacks
- hooking up to qemu display subsystem
- a few common helper functions to reset the device, retrieve display
informations
- a class callback to unblock the rendering (for GL updates)

What is left to the virtio-gpu subdevice to take care of, in short,
are all the virtio queues handling, command processing and migration.

Signed-off-by: Marc-André Lureau 
---
 include/hw/virtio/virtio-gpu.h |  73 +--
 hw/display/virtio-gpu-3d.c |  49 +++--
 hw/display/virtio-gpu-base.c   | 268 
 hw/display/virtio-gpu-pci.c|   2 +-
 hw/display/virtio-gpu.c| 372 +
 hw/display/virtio-vga.c|  11 +-
 hw/display/Makefile.objs   |   2 +-
 7 files changed, 458 insertions(+), 319 deletions(-)
 create mode 100644 hw/display/virtio-gpu-base.c

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 60425c5d58..d0d8d7b246 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -22,6 +22,14 @@
 
 #include "standard-headers/linux/virtio_gpu.h"
 
+#define TYPE_VIRTIO_GPU_BASE "virtio-gpu-base"
+#define VIRTIO_GPU_BASE(obj)\
+OBJECT_CHECK(VirtIOGPUBase, (obj), TYPE_VIRTIO_GPU_BASE)
+#define VIRTIO_GPU_BASE_GET_CLASS(obj)  \
+OBJECT_GET_CLASS(VirtIOGPUBaseClass, obj, TYPE_VIRTIO_GPU_BASE)
+#define VIRTIO_GPU_BASE_CLASS(klass)\
+OBJECT_CLASS_CHECK(VirtIOGPUBaseClass, klass, TYPE_VIRTIO_GPU_BASE)
+
 #define TYPE_VIRTIO_GPU "virtio-gpu-device"
 #define VIRTIO_GPU(obj)\
 OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU)
@@ -58,7 +66,7 @@ struct virtio_gpu_requested_state {
 int x, y;
 };
 
-enum virtio_gpu_conf_flags {
+enum virtio_gpu_base_conf_flags {
 VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1,
 VIRTIO_GPU_FLAG_STATS_ENABLED,
 VIRTIO_GPU_FLAG_EDID_ENABLED,
@@ -71,8 +79,7 @@ enum virtio_gpu_conf_flags {
 #define virtio_gpu_edid_enabled(_cfg) \
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
 
-struct virtio_gpu_conf {
-uint64_t max_hostmem;
+struct virtio_gpu_base_conf {
 uint32_t max_outputs;
 uint32_t flags;
 uint32_t xres;
@@ -88,31 +95,55 @@ struct virtio_gpu_ctrl_command {
 QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
 };
 
-typedef struct VirtIOGPU {
+typedef struct VirtIOGPUBase {
 VirtIODevice parent_obj;
 
-QEMUBH *ctrl_bh;
-QEMUBH *cursor_bh;
+Error *migration_blocker;
+
+struct virtio_gpu_base_conf conf;
+struct virtio_gpu_config virtio_config;
+
+bool use_virgl_renderer;
+int renderer_blocked;
+int enable;
+
+struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
+
+int enabled_output_bitmask;
+struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
+} VirtIOGPUBase;
+
+typedef struct VirtIOGPUBaseClass {
+VirtioDeviceClass parent;
+
+void (*gl_unblock)(VirtIOGPUBase *g);
+} VirtIOGPUBaseClass;
+
+#define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf)   \
+DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1),\
+DEFINE_PROP_BIT("edid", _state, _conf.flags, \
+VIRTIO_GPU_FLAG_EDID_ENABLED, false), \
+DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
+DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
+
+typedef struct VirtIOGPU {
+VirtIOGPUBase parent_obj;
+
+uint64_t conf_max_hostmem;
+
 VirtQueue *ctrl_vq;
 VirtQueue *cursor_vq;
 
-int enable;
+QEMUBH *ctrl_bh;
+QEMUBH *cursor_bh;
 
 QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
 QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq;
 QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
 
-struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
-struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
-
-struct virtio_gpu_conf conf;
 uint64_t hostmem;
-int enabled_output_bitmask;
-struct virtio_gpu_config virtio_config;
 
-bool use_virgl_renderer;
 bool renderer_inited;
-int renderer_blocked;
 bool renderer_reset;
 QEMUTimer *fence_poll;
 QEMUTimer *print_stats;
@@ -124,8 +155,6 @@ typedef struct VirtIOGPU {
 uint32_t req_3d;
 uint32_t bytes_3d;
 } stats;
-
-Error *migration_blocker;
 } VirtIOGPU;
 
 extern const GraphicHwOps virtio_gpu_ops;
@@ -148,6 +177,15 @@ extern const GraphicHwOps virtio_gpu_ops;
 }   \
 } 

[Qemu-devel] [PATCH v7 4/8] util: compile drm.o on Linux

2019-05-13 Thread Marc-André Lureau
OpenGL isn't required to use DRM rendernodes. The following patches
uses it for 2d resources for ex.

Signed-off-by: Marc-André Lureau 
---
 util/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/Makefile.objs b/util/Makefile.objs
index 9206878dec..657d59df3f 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -53,6 +53,6 @@ util-obj-y += systemd.o
 util-obj-y += iova-tree.o
 util-obj-$(CONFIG_INOTIFY1) += filemonitor-inotify.o
 util-obj-$(CONFIG_LINUX) += vfio-helpers.o
-util-obj-$(CONFIG_OPENGL) += drm.o
+util-obj-$(CONFIG_LINUX) += drm.o
 
 stub-obj-y += filemonitor-stub.o
-- 
2.21.0.777.g83232e3864




[Qemu-devel] [PATCH v7 1/8] vhost-user: add vhost_user_gpu_set_socket()

2019-05-13 Thread Marc-André Lureau
Add a new vhost-user message to give a unix socket to a vhost-user
backend for GPU display updates.

Back when I started that work, I added a new GPU channel because the
vhost-user protocol wasn't bidirectional. Since then, there is a
vhost-user-slave channel for the slave to send requests to the master.
We could extend it with GPU messages. However, the GPU protocol is
quite orthogonal to vhost-user, thus I chose to have a new dedicated
channel.

See vhost-user-gpu.rst for the protocol details.

Signed-off-by: Marc-André Lureau 
---
 contrib/libvhost-user/libvhost-user.h |   1 +
 include/hw/virtio/vhost-backend.h |   2 +
 contrib/libvhost-user/libvhost-user.c |   1 +
 hw/virtio/vhost-user.c|  11 ++
 MAINTAINERS   |   6 +
 docs/interop/index.rst|   2 +-
 docs/interop/vhost-user-gpu.rst   | 243 ++
 docs/interop/vhost-user.txt   |   9 +
 8 files changed, 274 insertions(+), 1 deletion(-)
 create mode 100644 docs/interop/vhost-user-gpu.rst

diff --git a/contrib/libvhost-user/libvhost-user.h 
b/contrib/libvhost-user/libvhost-user.h
index 78b33306e8..3b888ff0a5 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -94,6 +94,7 @@ typedef enum VhostUserRequest {
 VHOST_USER_POSTCOPY_END = 30,
 VHOST_USER_GET_INFLIGHT_FD = 31,
 VHOST_USER_SET_INFLIGHT_FD = 32,
+VHOST_USER_GPU_SET_SOCKET = 33,
 VHOST_USER_MAX
 } VhostUserRequest;
 
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index d6632a18e6..6f6670783f 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -170,4 +170,6 @@ int vhost_backend_invalidate_device_iotlb(struct vhost_dev 
*dev,
 int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
   struct vhost_iotlb_msg *imsg);
 
+int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
+
 #endif /* VHOST_BACKEND_H */
diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index b56325f485..386a3be677 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -130,6 +130,7 @@ vu_request_to_string(unsigned int req)
 REQ(VHOST_USER_POSTCOPY_END),
 REQ(VHOST_USER_GET_INFLIGHT_FD),
 REQ(VHOST_USER_SET_INFLIGHT_FD),
+REQ(VHOST_USER_GPU_SET_SOCKET),
 REQ(VHOST_USER_MAX),
 };
 #undef REQ
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 553319c7ac..4ca5b2551e 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -96,6 +96,7 @@ typedef enum VhostUserRequest {
 VHOST_USER_POSTCOPY_END = 30,
 VHOST_USER_GET_INFLIGHT_FD = 31,
 VHOST_USER_SET_INFLIGHT_FD = 32,
+VHOST_USER_GPU_SET_SOCKET = 33,
 VHOST_USER_MAX
 } VhostUserRequest;
 
@@ -353,6 +354,16 @@ static int vhost_user_write(struct vhost_dev *dev, 
VhostUserMsg *msg,
 return 0;
 }
 
+int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd)
+{
+VhostUserMsg msg = {
+.hdr.request = VHOST_USER_GPU_SET_SOCKET,
+.hdr.flags = VHOST_USER_VERSION,
+};
+
+return vhost_user_write(dev, , , 1);
+}
+
 static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
struct vhost_log *log)
 {
diff --git a/MAINTAINERS b/MAINTAINERS
index 8a87bc176d..655004d430 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1675,6 +1675,12 @@ F: hw/display/virtio-gpu*
 F: hw/display/virtio-vga.c
 F: include/hw/virtio/virtio-gpu.h
 
+vhost-user-gpu
+M: Marc-André Lureau 
+M: Gerd Hoffmann 
+S: Maintained
+F: docs/interop/vhost-user-gpu.rst
+
 Cirrus VGA
 M: Gerd Hoffmann 
 S: Odd Fixes
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
index 2df977dd52..28ead07466 100644
--- a/docs/interop/index.rst
+++ b/docs/interop/index.rst
@@ -15,4 +15,4 @@ Contents:
bitmaps
live-block-operations
pr-helper
-
+   vhost-user-gpu
diff --git a/docs/interop/vhost-user-gpu.rst b/docs/interop/vhost-user-gpu.rst
new file mode 100644
index 00..28ffefe930
--- /dev/null
+++ b/docs/interop/vhost-user-gpu.rst
@@ -0,0 +1,243 @@
+===
+Vhost-user-gpu Protocol
+===
+
+:Licence: This work is licensed under the terms of the GNU GPL,
+  version 2 or later. See the COPYING file in the top-level
+  directory.
+
+.. contents:: Table of Contents
+
+Introduction
+
+
+The vhost-user-gpu protocol is aiming at sharing the rendering result
+of a virtio-gpu, done from a vhost-user slave process to a vhost-user
+master process (such as QEMU). It bears a resemblance to a display
+server protocol, if you consider QEMU as the display server and the
+slave as the client, but in a very limited way. Typically, it will
+work by setting a scanout/display configuration, before sending flush
+events for the display updates. It will 

[Qemu-devel] [PATCH v7 2/8] virtio-gpu: add bswap helpers header

2019-05-13 Thread Marc-André Lureau
The helper functions are useful to build the vhost-user-gpu backend.

Signed-off-by: Marc-André Lureau 
---
 include/hw/virtio/virtio-gpu-bswap.h | 61 
 hw/display/virtio-gpu.c  | 43 +---
 2 files changed, 62 insertions(+), 42 deletions(-)
 create mode 100644 include/hw/virtio/virtio-gpu-bswap.h

diff --git a/include/hw/virtio/virtio-gpu-bswap.h 
b/include/hw/virtio/virtio-gpu-bswap.h
new file mode 100644
index 00..38d12160f6
--- /dev/null
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -0,0 +1,61 @@
+/*
+ * Virtio GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ * Dave Airlie 
+ * Gerd Hoffmann 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_VIRTIO_GPU_BSWAP_H
+#define HW_VIRTIO_GPU_BSWAP_H
+
+#include "qemu/bswap.h"
+
+static inline void
+virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr)
+{
+le32_to_cpus(>type);
+le32_to_cpus(>flags);
+le64_to_cpus(>fence_id);
+le32_to_cpus(>ctx_id);
+le32_to_cpus(>padding);
+}
+
+static inline void
+virtio_gpu_bswap_32(void *ptr, size_t size)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+
+size_t i;
+struct virtio_gpu_ctrl_hdr *hdr = (struct virtio_gpu_ctrl_hdr *) ptr;
+
+virtio_gpu_ctrl_hdr_bswap(hdr);
+
+i = sizeof(struct virtio_gpu_ctrl_hdr);
+while (i < size) {
+le32_to_cpus((uint32_t *)(ptr + i));
+i = i + sizeof(uint32_t);
+}
+
+#endif
+}
+
+static inline void
+virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d)
+{
+virtio_gpu_ctrl_hdr_bswap(>hdr);
+le32_to_cpus(>r.x);
+le32_to_cpus(>r.y);
+le32_to_cpus(>r.width);
+le32_to_cpus(>r.height);
+le64_to_cpus(>offset);
+le32_to_cpus(>resource_id);
+le32_to_cpus(>padding);
+}
+
+#endif
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 9e37e0ac96..c35025b6fb 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -20,6 +20,7 @@
 #include "sysemu/dma.h"
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-bswap.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/display/edid.h"
 #include "migration/blocker.h"
@@ -34,48 +35,6 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
struct virtio_gpu_simple_resource *res);
 
-static void
-virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr)
-{
-le32_to_cpus(>type);
-le32_to_cpus(>flags);
-le64_to_cpus(>fence_id);
-le32_to_cpus(>ctx_id);
-le32_to_cpus(>padding);
-}
-
-static void virtio_gpu_bswap_32(void *ptr,
-size_t size)
-{
-#ifdef HOST_WORDS_BIGENDIAN
-
-size_t i;
-struct virtio_gpu_ctrl_hdr *hdr = (struct virtio_gpu_ctrl_hdr *) ptr;
-
-virtio_gpu_ctrl_hdr_bswap(hdr);
-
-i = sizeof(struct virtio_gpu_ctrl_hdr);
-while (i < size) {
-le32_to_cpus((uint32_t *)(ptr + i));
-i = i + sizeof(uint32_t);
-}
-
-#endif
-}
-
-static void
-virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d)
-{
-virtio_gpu_ctrl_hdr_bswap(>hdr);
-le32_to_cpus(>r.x);
-le32_to_cpus(>r.y);
-le32_to_cpus(>r.width);
-le32_to_cpus(>r.height);
-le64_to_cpus(>offset);
-le32_to_cpus(>resource_id);
-le32_to_cpus(>padding);
-}
-
 #ifdef CONFIG_VIRGL
 #include 
 #define VIRGL(_g, _virgl, _simple, ...) \
-- 
2.21.0.777.g83232e3864




[Qemu-devel] [PATCH v7 0/8] Add vhost-user-gpu

2019-05-13 Thread Marc-André Lureau
Hi,

vhost-user allows to drive a virtio device in a seperate
process. After vhost-user-net, we have seen
vhost-user-{scsi,blk,crypto,input} added more recently.

This series, initially proposed ~3 years ago, time flies
(https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg01905.html)
contributes with vhost-user-gpu.

You may start a vhost-user-gpu with virgl rendering in a separate
process like this:

$ ./vhost-user-gpu --virgl -s vgpu.sock &
$ qemu...
  -chardev socket,id=chr,path=vgpu.sock
  -device vhost-user-vga,chardev=chr

Based-on: <20190513183325.8596-1-marcandre.lur...@redhat.com>

v7:
 - add "framed" replies to the vhost-user-gpu protocol
 - use GBM library instead of drm-vendor APIs
 - added "virtio-gpu: add a pixman helper header"

v6:
 - do not install vhost-user-input
 - install vhost-user-gpu and json file following the spec
 - fix the build when drm-intel-devel missing
 - rebase (& resend without already applied patches)

v5:
 - remove user-creatable version of vhost-user-backend
 - remove optinal management of sub-process in vhost-user-backend
 - removed daemonize/pid code
 - drop introduction of new input & gpu messages for PCI config space
   handling, instead use VHOST_USER_PROTOCOL_F_CONFIG
 - plain mem & udmabuf fallback for 2d rendering
 - rebased, kconfig-ify, rst-ify

Marc-André Lureau (8):
  vhost-user: add vhost_user_gpu_set_socket()
  virtio-gpu: add bswap helpers header
  virtio-gpu: add a pixman helper header
  util: compile drm.o on Linux
  contrib: add vhost-user-gpu
  virtio-gpu: split virtio-gpu, introduce virtio-gpu-base
  virtio-gpu: split virtio-gpu-pci & virtio-vga
  hw/display: add vhost-user-vga & gpu-pci

 configure  |   17 +
 contrib/libvhost-user/libvhost-user.h  |1 +
 contrib/vhost-user-gpu/virgl.h |   25 +
 contrib/vhost-user-gpu/vugbm.h |   67 ++
 contrib/vhost-user-gpu/vugpu.h |  177 +++
 hw/display/virtio-vga.h|   32 +
 include/hw/virtio/vhost-backend.h  |2 +
 include/hw/virtio/virtio-gpu-bswap.h   |   61 +
 include/hw/virtio/virtio-gpu-pci.h |   40 +
 include/hw/virtio/virtio-gpu-pixman.h  |   45 +
 include/hw/virtio/virtio-gpu.h |   92 +-
 contrib/libvhost-user/libvhost-user.c  |1 +
 contrib/vhost-user-gpu/main.c  | 1185 
 contrib/vhost-user-gpu/virgl.c |  579 ++
 contrib/vhost-user-gpu/vugbm.c |  331 ++
 hw/display/vhost-user-gpu-pci.c|   51 +
 hw/display/vhost-user-gpu.c|  607 ++
 hw/display/vhost-user-vga.c|   52 +
 hw/display/virtio-gpu-3d.c |   49 +-
 hw/display/virtio-gpu-base.c   |  268 +
 hw/display/virtio-gpu-pci.c|   55 +-
 hw/display/virtio-gpu.c|  444 ++--
 hw/display/virtio-vga.c|  138 +--
 hw/virtio/vhost-user.c |   11 +
 vl.c   |1 +
 MAINTAINERS|   10 +-
 Makefile   |   24 +-
 Makefile.objs  |1 +
 contrib/vhost-user-gpu/50-qemu-gpu.json.in |5 +
 contrib/vhost-user-gpu/Makefile.objs   |   10 +
 docs/interop/index.rst |2 +-
 docs/interop/vhost-user-gpu.rst|  243 
 docs/interop/vhost-user.txt|9 +
 hw/display/Kconfig |   10 +
 hw/display/Makefile.objs   |5 +-
 rules.mak  |9 +-
 util/Makefile.objs |2 +-
 37 files changed, 4176 insertions(+), 485 deletions(-)
 create mode 100644 contrib/vhost-user-gpu/virgl.h
 create mode 100644 contrib/vhost-user-gpu/vugbm.h
 create mode 100644 contrib/vhost-user-gpu/vugpu.h
 create mode 100644 hw/display/virtio-vga.h
 create mode 100644 include/hw/virtio/virtio-gpu-bswap.h
 create mode 100644 include/hw/virtio/virtio-gpu-pci.h
 create mode 100644 include/hw/virtio/virtio-gpu-pixman.h
 create mode 100644 contrib/vhost-user-gpu/main.c
 create mode 100644 contrib/vhost-user-gpu/virgl.c
 create mode 100644 contrib/vhost-user-gpu/vugbm.c
 create mode 100644 hw/display/vhost-user-gpu-pci.c
 create mode 100644 hw/display/vhost-user-gpu.c
 create mode 100644 hw/display/vhost-user-vga.c
 create mode 100644 hw/display/virtio-gpu-base.c
 create mode 100644 contrib/vhost-user-gpu/50-qemu-gpu.json.in
 create mode 100644 contrib/vhost-user-gpu/Makefile.objs
 create mode 100644 docs/interop/vhost-user-gpu.rst

-- 
2.21.0.777.g83232e3864




Re: [Qemu-devel] How do we do user input bitmap properties?

2019-05-13 Thread Andrew Jones
On Thu, Apr 18, 2019 at 07:48:09PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé  writes:
> 
> > On Thu, Apr 18, 2019 at 11:28:41AM +0200, Andrew Jones wrote:
> >> Hi all,
> >> 
> >> First some background:
> >> 
> >> For the userspace side of AArch64 guest SVE support we need to
> >> expose KVM's allowed vector lengths bitmap to the user and allow
> >> the user to choose a subset of that bitmap. Since bitmaps are a
> >> bit awkward to work with then we'll likely want to expose it as
> >> an array of vector lengths instead. Also, assuming we want to
> >> expose the lengths as number-of-quadwords (quadword == 128 bits
> >> for AArch64 and vector lengths must be multiples of quadwords)
> >> rather than number-of-bits, then an example array (which will
> >> always be a sequence) might be
> >> 
> >>  [ 8, 16, 32 ]
> >> 
> >> The user may choose a subsequence, but only through truncation,
> >> i.e. [ 8, 32 ] is not valid, but [ 8, 16 ] is.
> >> 
> >> Furthermore, different hosts may support different sequences
> >> which have the same maximum. For example, if the above sequence
> >> is for Host_A, then Host_B could be
> >> 
> >>  [ 8, 16, 24, 32 ]
> >> 
> >> The host must support all lengths in the sequence, which means
> >> that while Host_A supports 32, since it doesn't support 24 and
> >> we can only truncate sequences, we must use either [ 8 ] or
> >> [ 8, 16 ] for a compatible sequence if we intend to migrate
> >> between the hosts.
> >> 
> >> Now to the $SUBJECT question:
> >> 
> >> My feeling is that we should require the sequence to be
> >> provided on the command line as a cpu property. Something
> >> like
> >> 
> >>   -cpu host,sve-vl-list=8:16
> >> 
> >> (I chose ':' for the delimiter because ',' can't work, but
> >> if there's a better choice, then that's fine by me.)
> >> 
> >> Afaict a property list like this will require a new parser,
> 
> We had 20+ of those when I last counted.  Among the more annoying
> reasons CLI QAPIfication is hard[1].
> 
> >> which feels a bit funny since it seems we should already
> >> have support for this type of thing somewhere in QEMU. So,
> >> the question is: do we? I see we have array properties, but
> >> I don't believe that works with the command line. Should we
> >> only use QMP for this? We already want some QMP in order to
> >> query the supported vector lengths. Maybe we should use QMP
> >> to set the selection too? But then what about command line
> >> support for developers? And if the property is on the command
> >> line then we don't have to add it to the migration stream.
> >
> > You should be able to use arrays from the CLI with QemuOpts by repeating
> > the same option name many times, though I can't say it is a very
> > nice approach if you have many values to list as it gets very repetative.
> 
> Yes, this is one of the ways the current CLI does lists.  It's also one
> of the more annoying reasons CLI QAPIfication is hard[2].
> 
> QemuOpts let the last param=value win the stupidest way that could
> possibly work (I respect that): add to the front of the list, search it
> front to back.
> 
> Then somebody discovered that if you search the list manually, you can
> see them all, and abuse that to get a list-valued param.  I'm sure that
> felt clever at the time.
> 
> Another way to do lists the funky list feature of string input and opts
> visitor.  Yet another annoying reason CLI QAPIfication is hard[3].
> 
> We use the opts visitor's list feature for -numa node,cpus=...  Hmm,
> looks like we even combine it with the "multiple param=value build up a
> list" technique: -smp node,cpus=0-1,cpus=4-5 denotes [0,1,4,5].
> 
> > That's the curse of not having a good CLI syntax for non-scalar data in
> > QemuOpts & why Markus believes we should switch to JSON for the CLI too
> >
> >  -cpu host,sve-vl=8,sve-vl=16
> 
> We actually have CLI syntax for non-scalar data: dotted keys.  Dotted
> keys are syntactic sugar for JSON.  It looks friendlier than JSON for
> simple cases, then gets uglier as things get more complex, and then it
> falls apart: it can't quite express all of JSON.
> 
> Example: sve-vl.0=8,sve-vl.1=16
> gets desugared into {"sve": [8, 16]}
> if the QAPI schema has 'sve': ['int'].
> 
> The comment at the beginning of util/keyval.c explains it in more
> detail.
> 
> It powers -blockdev and -display.  Both options accept either JSON or
> dotted keys.  If the option argument starts with '{', it's JSON.
> Management applications should stick to JSON.
> 
> 
> [1] Towards a more expressive and introspectable QEMU command line
> https://www.linux-kvm.org/images/f/f2/Armbru-qapi-cmdline_1.pdf
> Slide 34 "Backward compatibility" item 1
> 
> [2] ibid, item 4
> 
> [3] ibid, item 3
>

Sorry I forgot to follow up to this earlier. I looked at the examples
provided and saw they were all for independent command line options,
rather than command line options like '-cpu' that then accepts additional
properties. I couldn't see how I could use ',' 

[Qemu-devel] [PATCH v3 1/3] libvhost-user: fix cast warnings on 32 bits

2019-05-13 Thread Marc-André Lureau
Fixes warnings:
 warning: cast to pointer from integer of different size
 [-Wint-to-pointer-cast]

Signed-off-by: Marc-André Lureau 
---
 contrib/libvhost-user/libvhost-user.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index 74d42177c5..40443a3daa 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -621,7 +621,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg 
*vmsg)
  * data that's already arrived in the shared process.
  * TODO: How to do hugepage
  */
-ret = madvise((void *)dev_region->mmap_addr,
+ret = madvise((void *)(uintptr_t)dev_region->mmap_addr,
   dev_region->size + dev_region->mmap_offset,
   MADV_DONTNEED);
 if (ret) {
@@ -633,7 +633,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg 
*vmsg)
  * in neighbouring pages.
  * TODO: Turn this backon later.
  */
-ret = madvise((void *)dev_region->mmap_addr,
+ret = madvise((void *)(uintptr_t)dev_region->mmap_addr,
   dev_region->size + dev_region->mmap_offset,
   MADV_NOHUGEPAGE);
 if (ret) {
@@ -666,7 +666,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg 
*vmsg)
 DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
 __func__, i, reg_struct.range.start, reg_struct.range.len);
 /* Now it's registered we can let the client at it */
-if (mprotect((void *)dev_region->mmap_addr,
+if (mprotect((void *)(uintptr_t)dev_region->mmap_addr,
  dev_region->size + dev_region->mmap_offset,
  PROT_READ | PROT_WRITE)) {
 vu_panic(dev, "failed to mprotect region %d for postcopy (%s)",
-- 
2.21.0.777.g83232e3864




[Qemu-devel] [PATCH v3 3/3] contrib: add vhost-user-input

2019-05-13 Thread Marc-André Lureau
Add a vhost-user input backend example, based on virtio-input-host
device. It takes an evdev path as argument, and can be associated with
a vhost-user-input device via a UNIX socket:

$ vhost-user-input -p /dev/input/eventX -s /tmp/vui.sock

$ qemu ... -chardev socket,id=vuic,path=/tmp/vui.sock
  -device vhost-user-input-pci,chardev=vuic

This example is intentionally not included in $TOOLS, and not
installed by default.

Signed-off-by: Marc-André Lureau 
---
 contrib/vhost-user-input/main.c| 393 +
 MAINTAINERS|   1 +
 Makefile   |  11 +
 Makefile.objs  |   1 +
 contrib/vhost-user-input/Makefile.objs |   1 +
 5 files changed, 407 insertions(+)
 create mode 100644 contrib/vhost-user-input/main.c
 create mode 100644 contrib/vhost-user-input/Makefile.objs

diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c
new file mode 100644
index 00..8d493f598e
--- /dev/null
+++ b/contrib/vhost-user-input/main.c
@@ -0,0 +1,393 @@
+/*
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include 
+#include 
+
+#include "qemu/iov.h"
+#include "qemu/bswap.h"
+#include "qemu/sockets.h"
+#include "contrib/libvhost-user/libvhost-user.h"
+#include "contrib/libvhost-user/libvhost-user-glib.h"
+#include "standard-headers/linux/virtio_input.h"
+#include "qapi/error.h"
+
+typedef struct virtio_input_event virtio_input_event;
+typedef struct virtio_input_config virtio_input_config;
+
+typedef struct VuInput {
+VugDev dev;
+GSource *evsrc;
+int evdevfd;
+GArray *config;
+virtio_input_config *sel_config;
+struct {
+virtio_input_event event;
+VuVirtqElement *elem;
+} *queue;
+uint32_t qindex, qsize;
+} VuInput;
+
+static void vi_input_send(VuInput *vi, struct virtio_input_event *event)
+{
+VuDev *dev = >dev.parent;
+VuVirtq *vq = vu_get_queue(dev, 0);
+VuVirtqElement *elem;
+int i, len;
+
+/* queue up events ... */
+if (vi->qindex == vi->qsize) {
+vi->qsize++;
+vi->queue = g_realloc_n(vi->queue, vi->qsize, sizeof(vi->queue[0]));
+}
+vi->queue[vi->qindex++].event = *event;
+
+/* ... until we see a report sync ... */
+if (event->type != htole16(EV_SYN) ||
+event->code != htole16(SYN_REPORT)) {
+return;
+}
+
+/* ... then check available space ... */
+for (i = 0; i < vi->qindex; i++) {
+elem = vu_queue_pop(dev, vq, sizeof(VuVirtqElement));
+if (!elem) {
+while (--i >= 0) {
+vu_queue_unpop(dev, vq, vi->queue[i].elem, 0);
+}
+vi->qindex = 0;
+g_warning("virtio-input queue full");
+return;
+}
+vi->queue[i].elem = elem;
+}
+
+/* ... and finally pass them to the guest */
+for (i = 0; i < vi->qindex; i++) {
+elem = vi->queue[i].elem;
+len = iov_from_buf(elem->in_sg, elem->in_num,
+   0, >queue[i].event, sizeof(virtio_input_event));
+vu_queue_push(dev, vq, elem, len);
+g_free(elem);
+}
+
+vu_queue_notify(>dev.parent, vq);
+vi->qindex = 0;
+}
+
+static void
+vi_evdev_watch(VuDev *dev, int condition, void *data)
+{
+VuInput *vi = data;
+int fd = vi->evdevfd;
+
+g_debug("Got evdev condition %x", condition);
+
+struct virtio_input_event virtio;
+struct input_event evdev;
+int rc;
+
+for (;;) {
+rc = read(fd, , sizeof(evdev));
+if (rc != sizeof(evdev)) {
+break;
+}
+
+g_debug("input %d %d %d", evdev.type, evdev.code, evdev.value);
+
+virtio.type  = htole16(evdev.type);
+virtio.code  = htole16(evdev.code);
+virtio.value = htole32(evdev.value);
+vi_input_send(vi, );
+}
+}
+
+
+static void vi_handle_status(VuInput *vi, virtio_input_event *event)
+{
+struct input_event evdev;
+int rc;
+
+if (gettimeofday(, NULL)) {
+perror("vi_handle_status: gettimeofday");
+return;
+}
+
+evdev.type = le16toh(event->type);
+evdev.code = le16toh(event->code);
+evdev.value = le32toh(event->value);
+
+rc = write(vi->evdevfd, , sizeof(evdev));
+if (rc == -1) {
+perror("vi_host_handle_status: write");
+}
+}
+
+static void vi_handle_sts(VuDev *dev, int qidx)
+{
+VuInput *vi = container_of(dev, VuInput, dev.parent);
+VuVirtq *vq = vu_get_queue(dev, qidx);
+virtio_input_event event;
+VuVirtqElement *elem;
+int len;
+
+g_debug("%s", G_STRFUNC);
+
+for (;;) {
+elem = vu_queue_pop(dev, vq, sizeof(VuVirtqElement));
+if (!elem) {
+break;
+}
+
+memset(, 0, sizeof(event));
+len = iov_to_buf(elem->out_sg, elem->out_num,
+  

[Qemu-devel] [PATCH v3 0/3] Add vhost-user-input

2019-05-13 Thread Marc-André Lureau
Hi,

v3:
- rebased, fixing some warnings found during merge

v2:
- build fixes

v1: (changes since original v6 series)
- add "libvhost-user: fix -Waddress-of-packed-member" & "util: simplify 
unix_listen()"
- use unix_listen()
- build vhost-user-input by default (when applicable)

Marc-André Lureau (3):
  libvhost-user: fix cast warnings on 32 bits
  libvhost-user: fix -Werror=format= on ppc64
  contrib: add vhost-user-input

 contrib/libvhost-user/libvhost-user.c  |  11 +-
 contrib/vhost-user-input/main.c| 393 +
 MAINTAINERS|   1 +
 Makefile   |  11 +
 Makefile.objs  |   1 +
 contrib/vhost-user-input/Makefile.objs |   1 +
 6 files changed, 413 insertions(+), 5 deletions(-)
 create mode 100644 contrib/vhost-user-input/main.c
 create mode 100644 contrib/vhost-user-input/Makefile.objs

-- 
2.21.0.777.g83232e3864




[Qemu-devel] [PATCH v3 2/3] libvhost-user: fix -Werror=format= on ppc64

2019-05-13 Thread Marc-André Lureau
That should fix the following warning:

/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c: In function
‘vu_set_mem_table_exec_postcopy’:
/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c:666:9: error:
format ‘%llx’ expects argument of type ‘long long unsigned int’, but
argument 5 has type ‘__u64’ [-Werror=format=]
 DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
 ^
/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c:666:9: error:
format ‘%llx’ expects argument of type ‘long long unsigned int’, but
argument 6 has type ‘__u64’ [-Werror=format=]
cc1: all warnings being treated as errors

Signed-off-by: Marc-André Lureau 
---
 contrib/libvhost-user/libvhost-user.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index 40443a3daa..b56325f485 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -663,8 +663,9 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg 
*vmsg)
  __func__, i);
 return false;
 }
-DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
-__func__, i, reg_struct.range.start, reg_struct.range.len);
+DPRINT("%s: region %d: Registered userfault for %"
+   PRIu64 " + %" PRIu64 "\n",
+   __func__, i, reg_struct.range.start, reg_struct.range.len);
 /* Now it's registered we can let the client at it */
 if (mprotect((void *)(uintptr_t)dev_region->mmap_addr,
  dev_region->size + dev_region->mmap_offset,
-- 
2.21.0.777.g83232e3864




Re: [Qemu-devel] [PATCH 13/13] target/arm/kvm: host cpu: Add support for sve-vls-map

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 05:37:09PM +0200, Markus Armbruster wrote:
> Andrew Jones  writes:
> 
> > Allow the host cpu type to enable SVE in guests with the sve-vls-map
> > cpu property.
> >
> > Signed-off-by: Andrew Jones 
> > ---
> >  target/arm/cpu.c   |  1 +
> >  target/arm/cpu.h   |  2 ++
> >  target/arm/cpu64.c | 12 +---
> >  3 files changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index ea0e24bba8b6..a5c01ff42c78 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -,6 +,7 @@ static void arm_host_initfn(Object *obj)
> >  ARMCPU *cpu = ARM_CPU(obj);
> >  
> >  kvm_arm_set_cpu_features_from_host(cpu);
> > +aarch64_add_sve_vls_map_property(obj);
> >  arm_cpu_post_init(obj);
> >  }
> >  
> > diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> > index f0d0ce759ba8..13731ccb39f3 100644
> > --- a/target/arm/cpu.h
> > +++ b/target/arm/cpu.h
> > @@ -976,11 +976,13 @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, 
> > uint8_t *buf, int reg);
> >  void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
> >  void aarch64_sve_change_el(CPUARMState *env, int old_el,
> > int new_el, bool el0_a64);
> > +void aarch64_add_sve_vls_map_property(Object *obj);
> >  #else
> >  static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
> >  static inline void aarch64_sve_change_el(CPUARMState *env, int o,
> >   int n, bool a)
> >  { }
> > +void aarch64_add_sve_vls_map_property(Object *obj) { }
> 
> qemu/target/arm/cpu.h:985:6: error: no previous prototype for 
> ‘aarch64_add_sve_vls_map_property’ [-Werror=missing-prototypes]
>  void aarch64_add_sve_vls_map_property(Object *obj) { }
>   ^~~~
> 
> Did you forget static inline?

I sure did. Thanks for finding this!

drew

> 
> >  #endif
> >  
> >  target_ulong do_arm_semihosting(CPUARMState *env);
> [...]



Re: [Qemu-devel] [PATCH 05/13] target/arm/kvm: Add kvm_arch_get/put_sve

2019-05-13 Thread Richard Henderson
On 5/13/19 11:14 AM, Andrew Jones wrote:
>> Indeed, to me this seems to be the wrong kind of swabbing here.  Exactly what
>> format is KVM expecting?  Surely it should be the one used by the 
>> unpredicated
>> LDR/STR instructions.  Anything else would seem to be working against the
>> architecture.
>>
>> If so, the format is, architecturally, a stream of bytes in index order, 
>> which
>> corresponds to a little-endian stream of words.  So the loop I'd expect to 
>> see
>> here is
>>
>> for (i = 0, n = cpu->sve_max_vq; i < n; ++i) {
>> d[i] = bswap64(q[i]);
>> }
> 
> That's the opposite of what we do for fpsimd registers though. I'm
> fine with doing whatever KVM/TCG needs, but so far I was just following
> the same pattern we already have.

The behaviour of the hardware is different for LDR of fpsimd registers.

FP LDR operates on datasize (8, 16, 32, 64, 128 bits).
SVE LDR always operates on bytes.


r~



Re: [Qemu-devel] [PATCH 11/13] target/arm/cpu64: max cpu: Introduce sve-vls-map

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 05:25:23PM +0200, Markus Armbruster wrote:
> Andrew Jones  writes:
> 
> > Introduce another cpu property to control SVE vector lengths,
> > sve-vls-map, which allows the user to explicitly select the
> > set of vector lengths the guest can use. The map must conform
> > to QEMU's limits and architectural constraints, checked when
> > the property is set. Inconsistencies with sve-max-vq are also
> > checked. The bit number of a set bit in the map represents the
> > allowed vector length in number of quadwords.
> >
> > Note, as the map is implemented with a single 64-bit word we
> > currently only support up to 8192-bit vectors. As QEMU and
> > KVM only support up to 2048-bit vectors then this sufficient
> > now, and probably for some time. Extending the bitmap beyond
> > a single word will likely require changing the property to
> > a string and adding yet another parser to QEMU.
> >
> > Signed-off-by: Andrew Jones 
> 
> Please add an example of how the new property should be used on the
> command line to your commit message.  I'd ask for a documentation update
> as well if we had any to update.

Will do.

Thanks,
drew



Re: [Qemu-devel] [PATCH 08/13] target/arm/monitor: Add query-sve-vector-lengths

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 06:12:38PM +0200, Markus Armbruster wrote:
> Andrew Jones  writes:
> 
> > Provide a QMP interface to query the supported SVE vector lengths.
> > A migratable guest will need to explicitly specify a valid set of
> > lengths on the command line and that set can be obtained from the
> > list returned with this QMP command.
> >
> > This patch only introduces the QMP command with the TCG implementation.
> > The result may not yet be correct for KVM. Following patches ensure
> > the KVM result is correct.
> >
> > Signed-off-by: Andrew Jones 
> > ---
> >  qapi/target.json | 34 
> >  target/arm/monitor.c | 62 
> >  tests/qmp-cmd-test.c |  1 +
> >  3 files changed, 97 insertions(+)
> >
> > diff --git a/qapi/target.json b/qapi/target.json
> > index 1d4d54b6002e..ca1e85254780 100644
> > --- a/qapi/target.json
> > +++ b/qapi/target.json
> > @@ -397,6 +397,40 @@
> >  { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
> >'if': 'defined(TARGET_ARM)' }
> >  
> > +##
> > +# @SVEVectorLengths:
> > +#
> > +# The struct contains a list of integers where each integer is a valid
> 
> Suggest to s/The struct contains/Contains/.

OK

> 
> > +# SVE vector length for a KVM guest on this host. The vector lengths
> > +# are in quadword (128-bit) units, e.g. '4' means 512 bits (64 bytes).
> 
> Any particular reason for counting quad-words instead of bytes, or
> perhaps bits?

It can be considered just bits here, but when set in sve-vls-map those
bits are chosen to mean quadwords as that allows us to get up to 8192-bit
vectors with a single 64-bit word. Maybe I should write more of that here
to clarify.

> 
> > +#
> > +# @vls:  list of vector lengths in quadwords.
> > +#
> > +# Since: 4.1
> > +##
> > +{ 'struct': 'SVEVectorLengths',
> > +  'data': { 'vls': ['int'] },
> > +  'if': 'defined(TARGET_ARM)' }
> > +
> > +##
> > +# @query-sve-vector-lengths:
> > +#
> > +# This command is ARM-only. It will return a list of SVEVectorLengths
> 
> No other target-specific command documents its target-specificness like
> this.  Suggest

Well, it's pretty similar to query-gic-capabilities, which is what I used
as a template, but I'm happy to change it to whatever you suggest :)

> 
># Query valid SVE vector length sets.
> 
> > +# objects. The list describes all valid SVE vector length sets.
> > +#
> > +# Returns: a list of SVEVectorLengths objects
> > +#
> > +# Since: 4.1
> > +#
> > +# -> { "execute": "query-sve-vector-lengths" }
> > +# <- { "return": [ { "vls": [ 1 ] },
> > +#  { "vls": [ 1, 2 ] },
> > +#  { "vls": [ 1, 2, 4 ] } ] }
> > +#
> > +##
> > +{ 'command': 'query-sve-vector-lengths', 'returns': ['SVEVectorLengths'],
> > +  'if': 'defined(TARGET_ARM)' }
> > +

Yup, will do

> >  ##
> >  # @CpuModelExpansionInfo:
> >  #
> > diff --git a/target/arm/monitor.c b/target/arm/monitor.c
> > index 41b32b94b258..8b2afa255c92 100644
> > --- a/target/arm/monitor.c
> > +++ b/target/arm/monitor.c
> > @@ -24,6 +24,7 @@
> >  #include "hw/boards.h"
> >  #include "kvm_arm.h"
> >  #include "qapi/qapi-commands-target.h"
> > +#include "monitor/hmp-target.h"
> 
> Uh, hmp-target.h when the patch is supposedly about QMP only...
> 
> >  
> >  static GICCapability *gic_cap_new(int version)
> >  {
> > @@ -82,3 +83,64 @@ GICCapabilityList *qmp_query_gic_capabilities(Error 
> > **errp)
> >  
> >  return head;
> >  }
> > +
> > +static SVEVectorLengths *qmp_sve_vls_get(void)
> > +{
> > +CPUArchState *env = mon_get_cpu_env();
> 
> Aha, you need it for mon_get_cpu_env().
> 
> mon_get_cpu_env() returns the current monitor's current CPU.  This is an
> HMP thing, QMP commands should never access it.
> 
> Looks like you use it to find one of the CPUs, so you can access its
> ->sve_max_vq.
> 
> "One of the CPUs" smells odd: what if they aren't all the same?  Perhaps
> that can't happen.  I don't know, you tell me :)
> 
> If any CPU will do, what about simply using first_cpu?

first_cpu will work. We currently only allow the same vector length set
for all cpus. I'll change it and drop the HMP things.

> 
> > +ARMCPU *cpu = arm_env_get_cpu(env);
> > +SVEVectorLengths *vls = g_new(SVEVectorLengths, 1);
> > +intList **v = >vls;
> > +int i;
> > +
> > +if (cpu->sve_max_vq == 0) {
> > +*v = g_new0(intList, 1); /* one vl of 0 means none supported */
> > +return vls;
> > +}
> > +
> > +for (i = 1; i <= cpu->sve_max_vq; ++i) {
> > +*v = g_new0(intList, 1);
> > +(*v)->value = i;
> > +v = &(*v)->next;
> > +}
> 
> What this loop does is not immediately obvious.  I think you could use a
> function comment.

OK

> 
> > +
> > +return vls;
> > +}
> > +
> > +static SVEVectorLengths *qmp_sve_vls_dup_and_truncate(SVEVectorLengths 
> > *vls)
> > +{
> > +SVEVectorLengths *trunc_vls;
> > +intList **v, *p = vls->vls;
> > +
> > +if (!p->next) {
> > +

[Qemu-devel] [Bug 1828867] Re: QEmu translation is incorrect when using REX in combination with LAHF/SAHF

2019-05-13 Thread sonicadvan...@gmail.com
Here's also a basic test that can be run on hardware and have rflags and
rsp inspected after each instruction just to see how hardware doesn't
effect it.

** Attachment added: "a.cpp"
   https://bugs.launchpad.net/qemu/+bug/1828867/+attachment/5263495/+files/a.cpp

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

Title:
  QEmu translation is incorrect when using REX in combination with
  LAHF/SAHF

Status in QEMU:
  New

Bug description:
  When translating code that is using LAHF and SAHF in combination with the REX 
prefix then qemu translates incorrectly.
  These two instructions only ever use the AH register. Contrary to other 
instructions where if you use REX + high bit offsets then it'll pull in rsp and 
a few other registers.
  On hardware the REX prefix doesn't effect behaviour of these instructions at 
all.
  QEMU incorrectly selects RSP as the register of choice here due to this 
combination of REX + AH register usage.

  I've attached a patch that is super terrible just so I can work around
  the issue locally and to sort of show off how it is to be "fixed"

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



[Qemu-devel] [Bug 1828867] [NEW] QEmu translation is incorrect when using REX in combination with LAHF/SAHF

2019-05-13 Thread sonicadvan...@gmail.com
Public bug reported:

When translating code that is using LAHF and SAHF in combination with the REX 
prefix then qemu translates incorrectly.
These two instructions only ever use the AH register. Contrary to other 
instructions where if you use REX + high bit offsets then it'll pull in rsp and 
a few other registers.
On hardware the REX prefix doesn't effect behaviour of these instructions at 
all.
QEMU incorrectly selects RSP as the register of choice here due to this 
combination of REX + AH register usage.

I've attached a patch that is super terrible just so I can work around
the issue locally and to sort of show off how it is to be "fixed"

** Affects: qemu
 Importance: Undecided
 Status: New

** Patch added: "Terrible terrible patch"
   
https://bugs.launchpad.net/bugs/1828867/+attachment/5263494/+files/lahf_sahf.diff

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

Title:
  QEmu translation is incorrect when using REX in combination with
  LAHF/SAHF

Status in QEMU:
  New

Bug description:
  When translating code that is using LAHF and SAHF in combination with the REX 
prefix then qemu translates incorrectly.
  These two instructions only ever use the AH register. Contrary to other 
instructions where if you use REX + high bit offsets then it'll pull in rsp and 
a few other registers.
  On hardware the REX prefix doesn't effect behaviour of these instructions at 
all.
  QEMU incorrectly selects RSP as the register of choice here due to this 
combination of REX + AH register usage.

  I've attached a patch that is super terrible just so I can work around
  the issue locally and to sort of show off how it is to be "fixed"

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



Re: [Qemu-devel] [PATCH 05/13] target/arm/kvm: Add kvm_arch_get/put_sve

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 09:40:29AM -0700, Richard Henderson wrote:
> On 5/13/19 5:31 AM, Dave Martin wrote:
> > On Sun, May 12, 2019 at 09:36:16AM +0100, Andrew Jones wrote:
> >> These are the SVE equivalents to kvm_arch_get/put_fpsimd.
> >>
> >> Signed-off-by: Andrew Jones 
> >> ---
> >>  target/arm/kvm64.c | 127 +++--
> >>  1 file changed, 123 insertions(+), 4 deletions(-)
> > 
> > [...]
> > 
> >> +static int kvm_arch_put_sve(CPUState *cs)
> >> +{
> >> +ARMCPU *cpu = ARM_CPU(cs);
> >> +CPUARMState *env = >env;
> >> +struct kvm_one_reg reg;
> >> +int n, ret;
> >> +
> >> +for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; n++) {
> >> +uint64_t *q = aa64_vfp_qreg(env, n);
> >> +#ifdef HOST_WORDS_BIGENDIAN
> >> +uint64_t d[ARM_MAX_VQ * 2];
> >> +int i;
> >> +for (i = 0; i < cpu->sve_max_vq * 2; i++) {
> >> +d[i] = q[cpu->sve_max_vq * 2 - 1 - i];
> >> +}
> > 
> > Out of interest, why do all this swabbing?  It seems expensive.
> 
> Indeed, to me this seems to be the wrong kind of swabbing here.  Exactly what
> format is KVM expecting?  Surely it should be the one used by the unpredicated
> LDR/STR instructions.  Anything else would seem to be working against the
> architecture.
> 
> If so, the format is, architecturally, a stream of bytes in index order, which
> corresponds to a little-endian stream of words.  So the loop I'd expect to see
> here is
> 
> for (i = 0, n = cpu->sve_max_vq; i < n; ++i) {
> d[i] = bswap64(q[i]);
> }

That's the opposite of what we do for fpsimd registers though. I'm
fine with doing whatever KVM/TCG needs, but so far I was just following
the same pattern we already have.

Thanks,
drew



Re: [Qemu-devel] [PATCH 07/13] target/arm/kvm: max cpu: Allow sve max vector length setting

2019-05-13 Thread Andrew Jones
On Mon, May 13, 2019 at 10:19:25AM -0700, Richard Henderson wrote:
> On 5/12/19 1:36 AM, Andrew Jones wrote:
> > @@ -292,7 +292,7 @@ static void aarch64_max_initfn(Object *obj)
> >  
> >  if (kvm_enabled()) {
> >  kvm_arm_set_cpu_features_from_host(cpu);
> > -cpu->sve_max_vq = ARM_MAX_VQ;
> > +cpu->sve_max_vq = -1; /* set in kvm_arch_init_vcpu() */
> 
> Perhaps a better comment is "unspecified, to be finalized in ..."

OK

> 
> > +object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
> > +cpu_max_set_sve_vq, NULL, NULL, _fatal);
> 
> as one can set it here, via the command-line.
> 
> > @@ -644,6 +702,24 @@ int kvm_arch_init_vcpu(CPUState *cs)
> >  }
> >  
> >  if (cpu->sve_max_vq) {
> > +uint64_t sve_vls[KVM_ARM64_SVE_VLS_WORDS];
> > +ret = kvm_arm_get_sve_vls(cs, sve_vls);
> > +if (ret < 0) {
> > +return ret;
> > +}
> > +if (cpu->sve_max_vq == -1) {
> > +cpu->sve_max_vq = ret;
> 
> You still cannot set a value larger than ARM_MAX_VQ, as that is the fixed
> amount of space allocated within the cpu structure.
>

Good point. I should check against ARM_MAX_VQ here.

Thanks,
drew 



Re: [Qemu-devel] [PATCH v8 3/6] libnvdimm: add dax_dev sync flag

2019-05-13 Thread Dan Williams
On Mon, May 13, 2019 at 10:32 AM Pankaj Gupta  wrote:
>
>
> Hi Dan,
>
> While testing device mapper with DAX, I faced a bug with the commit:
>
> commit ad428cdb525a97d15c0349fdc80f3d58befb50df
> Author: Dan Williams 
> Date:   Wed Feb 20 21:12:50 2019 -0800
>
> When I reverted the condition to old code[1] it worked for me. I
> am thinking when we map two different devices (e.g with device mapper), will
> start & end pfn still point to same pgmap? Or there is something else which
> I am missing here.
>
> Note: I tested only EXT4.
>
> [1]
>
> -   if (pgmap && pgmap->type == MEMORY_DEVICE_FS_DAX)
> +   end_pgmap = get_dev_pagemap(pfn_t_to_pfn(end_pfn), NULL);
> +   if (pgmap && pgmap == end_pgmap && pgmap->type == 
> MEMORY_DEVICE_FS_DAX
> +   && pfn_t_to_page(pfn)->pgmap == pgmap
> +   && pfn_t_to_page(end_pfn)->pgmap == pgmap
> +   && pfn_t_to_pfn(pfn) == PHYS_PFN(__pa(kaddr))
> +   && pfn_t_to_pfn(end_pfn) == 
> PHYS_PFN(__pa(end_kaddr)))

Ugh, yes, device-mapper continues to be an awkward fit for dax (or
vice versa). We would either need a way to have a multi-level pfn to
pagemap lookup for composite devices, or a way to discern that even
though the pagemap is different that the result is still valid / not
an indication that we have leaked into an unassociated address range.
Perhaps a per-daxdev callback for ->dax_supported() so that
device-mapper internals can be used for this validation.

We need to get that fixed up, but I don't see it as a blocker /
pre-requisite for virtio-pmem.



Re: [Qemu-devel] [PATCH v8 3/6] libnvdimm: add dax_dev sync flag

2019-05-13 Thread Pankaj Gupta


Hi Dan,

While testing device mapper with DAX, I faced a bug with the commit:

commit ad428cdb525a97d15c0349fdc80f3d58befb50df
Author: Dan Williams 
Date:   Wed Feb 20 21:12:50 2019 -0800

When I reverted the condition to old code[1] it worked for me. I 
am thinking when we map two different devices (e.g with device mapper), will 
start & end pfn still point to same pgmap? Or there is something else which
I am missing here. 

Note: I tested only EXT4.

[1]

-   if (pgmap && pgmap->type == MEMORY_DEVICE_FS_DAX)
+   end_pgmap = get_dev_pagemap(pfn_t_to_pfn(end_pfn), NULL);
+   if (pgmap && pgmap == end_pgmap && pgmap->type == 
MEMORY_DEVICE_FS_DAX
+   && pfn_t_to_page(pfn)->pgmap == pgmap
+   && pfn_t_to_page(end_pfn)->pgmap == pgmap
+   && pfn_t_to_pfn(pfn) == PHYS_PFN(__pa(kaddr))
+   && pfn_t_to_pfn(end_pfn) == 
PHYS_PFN(__pa(end_kaddr)))
dax_enabled = true;
put_dev_pagemap(pgmap);

Thanks,
Pankaj







Re: [Qemu-devel] [PATCH v2] rng-builtin: add an RNG backend that uses qemu_guest_getrandom()

2019-05-13 Thread Amit Shah
On (Fri) 10 May 2019 [17:19:12], Markus Armbruster wrote:
> Laurent Vivier  writes:
> 
> > On 10/05/2019 14:27, Markus Armbruster wrote:
> >> Laurent Vivier  writes:
> >>
> >>> Add a new RNG backend using QEMU builtin getrandom function.
> >>>
> >>> It can be created and used with something like:
> >>>
> >>>  ... -object rng-builtin,id=rng0 -device virtio-rng,rng=rng0 ...
> >>>
> >>> Reviewed-by: Richard Henderson 
> >>> Signed-off-by: Laurent Vivier 
> >>> ---
> >>>
> >>> Notes:
> >>>  This patch applies on top of
> >>>  "[PATCH v5 00/24] Add qemu_getrandom and ARMv8.5-RNG etc"
> >>>  Based-on: 20190510012458.22706-1-richard.hender...@linaro.org
> >>>   v2: Update qemu-options.hx
> >>>  describe the new backend and specify virtio-rng uses the
> >>>  rng-random by default (do we want to change this?)
> >>>
> >>>   backends/Makefile.objs |  2 +-
> >>>   backends/rng-builtin.c | 56 ++
> >>>   qemu-options.hx| 10 +++-
> >>>   3 files changed, 66 insertions(+), 2 deletions(-)
> >>>   create mode 100644 backends/rng-builtin.c
> >>>
> >>> diff --git a/backends/Makefile.objs b/backends/Makefile.objs
> >>> index ff619d31b461..8da4a508d97b 100644
> >>> --- a/backends/Makefile.objs
> >>> +++ b/backends/Makefile.objs
> >>> @@ -1,4 +1,4 @@
> >>> -common-obj-y += rng.o rng-egd.o
> >>> +common-obj-y += rng.o rng-egd.o rng-builtin.o
> >>>   common-obj-$(CONFIG_POSIX) += rng-random.o
> >>> common-obj-$(CONFIG_TPM) += tpm.o
> >>> diff --git a/backends/rng-builtin.c b/backends/rng-builtin.c
> >>> new file mode 100644
> >>> index ..b1264b745407
> >>> --- /dev/null
> >>> +++ b/backends/rng-builtin.c
> >>> @@ -0,0 +1,56 @@
> >>> +/*
> >>> + * QEMU Builtin Random Number Generator Backend
> >>> + *
> >>> + * This work is licensed under the terms of the GNU GPL, version 2 or 
> >>> later.
> >>> + * See the COPYING file in the top-level directory.
> >>> + */
> >>> +
> >>> +#include "qemu/osdep.h"
> >>> +#include "sysemu/rng.h"
> >>> +#include "qapi/error.h"
> >>> +#include "qapi/qmp/qerror.h"
> >>> +#include "qemu/main-loop.h"
> >>> +#include "qemu/guest-random.h"
> >>> +
> >>> +#define TYPE_RNG_BUILTIN "rng-builtin"
> >>> +#define RNG_BUILTIN(obj) OBJECT_CHECK(RngBuiltin, (obj), 
> >>> TYPE_RNG_BUILTIN)
> >>> +
> >>> +typedef struct RngBuiltin {
> >>> +RngBackend parent;
> >>> +} RngBuiltin;
> >>> +
> >>> +static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req)
> >>> +{
> >>> +RngBuiltin *s = RNG_BUILTIN(b);
> >>> +
> >>> +while (!QSIMPLEQ_EMPTY(>parent.requests)) {
> >>> +RngRequest *req = QSIMPLEQ_FIRST(>parent.requests);
> >>> +
> >>> +qemu_guest_getrandom_nofail(req->data, req->size);
> >>> +
> >>> +req->receive_entropy(req->opaque, req->data, req->size);
> >>> +
> >>> +rng_backend_finalize_request(>parent, req);
> >>> +}
> >>> +}
> >>> +
> >>> +static void rng_builtin_class_init(ObjectClass *klass, void *data)
> >>> +{
> >>> +RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
> >>> +
> >>> +rbc->request_entropy = rng_builtin_request_entropy;
> >>> +}
> >>> +
> >>> +static const TypeInfo rng_builtin_info = {
> >>> +.name = TYPE_RNG_BUILTIN,
> >>> +.parent = TYPE_RNG_BACKEND,
> >>> +.instance_size = sizeof(RngBuiltin),
> >>> +.class_init = rng_builtin_class_init,
> >>> +};
> >>> +
> >>> +static void register_types(void)
> >>> +{
> >>> +type_register_static(_builtin_info);
> >>> +}
> >>> +
> >>> +type_init(register_types);
> >>> diff --git a/qemu-options.hx b/qemu-options.hx
> >>> index 0191ef8b1eb7..3e2a51c691b0 100644
> >>> --- a/qemu-options.hx
> >>> +++ b/qemu-options.hx
> >>> @@ -4280,13 +4280,21 @@ other options.
> >>> The @option{share} boolean option is @var{on} by default with
> >>> memfd.
> >>>   +@item -object rng-builtin,id=@var{id}
> >>> +
> >>> +Creates a random number generator backend which obtains entropy from
> >>> +QEMU builtin functions. The @option{id} parameter is a unique ID that
> >>> +will be used to reference this entropy backend from the 
> >>> @option{virtio-rng}
> >>> +device.
> >>> +
> >>>   @item -object rng-random,id=@var{id},filename=@var{/dev/random}
> >>> Creates a random number generator backend which obtains entropy
> >>> from
> >>>   a device on the host. The @option{id} parameter is a unique ID that
> >>>   will be used to reference this entropy backend from the 
> >>> @option{virtio-rng}
> >>>   device.
> >>
> >> There's also the "spapr-rng" device, I think.
> >
> > spapr-rng doesn't have default. You must specify one to be able to use it:
> >qemu-system-ppc64: -device spapr-rng: spapr-rng needs an RNG backend!
> 
> You're right.
> 
> >>>   The @option{filename} parameter specifies which file to obtain
> >>> -entropy from and if omitted defaults to @option{/dev/random}.
> >>> +entropy from and if omitted defaults to @option{/dev/random}. By default,
> >>> +the 

Re: [Qemu-devel] [PATCH v11 00/12] Add RX archtecture support

2019-05-13 Thread Philippe Mathieu-Daudé
Hi Yoshinori,

On 5/13/19 7:25 AM, Yoshinori Sato wrote:
> Hello.
> This patch series is added Renesas RX target emulation.
> 
> Fixed build errors and cleaned up the code.
> 
> My git repository is bellow.
> git://git.pf.osdn.net/gitroot/y/ys/ysato/qemu.git tags/rx-20190513

This tag isn't exactly the same as the series you posted, some patches
are ordered differently, leading to this failure at commit fc564da941a
(Add rx-softmmu) of your tag:

((fc564da941a...))$ make -C rx-softmmu hw/intc/rx_icu.o
  CC  hw/intc/rx_icu.o
hw/intc/rx_icu.c:35:9: error: expected ‘)’ before numeric constant
 REG8(IR, 0)
 ^~
 )
...
hw/intc/rx_icu.c: In function ‘icu_read’:
hw/intc/rx_icu.c:174:18: error: ‘A_FIR’ undeclared (first use in this
function); did you mean ‘A_FPSW’?
 if ((addr != A_FIR && size != 1) ||
  ^
  A_FPSW
hw/intc/rx_icu.c:174:18: note: each undeclared identifier is reported
only once for each function it appears in
hw/intc/rx_icu.c:181:10: error: ‘A_IR’ undeclared (first use in this
function); did you mean ‘DIR’?
 case A_IR ... A_IR + 0xff:
  ^~~~
  DIR
...
hw/intc/rx_icu.c:199:44: error: ‘R_IRQCR_IRQMD_SHIFT’ undeclared (first
use in this function); did you mean ‘R_IRQCR_IRQMD_MASK’?
 return icu->src[64 + reg].sense << R_IRQCR_IRQMD_SHIFT;
^~~
R_IRQCR_IRQMD_MASK

This is because the commit "hw/registerfields.h" is added after.
I see this series seems ordered correctly, so I'll keep testing.

> 
> Testing binaries bellow.
> u-boot
> Download - https://osdn.net/users/ysato/pf/qemu/dl/u-boot.bin.gz
> 
> starting
> $ gzip -d u-boot.bin.gz
> $ qemu-system-rx -bios u-boot.bin
> 
> linux and pico-root (only sash)
> Download - https://osdn.net/users/ysato/pf/qemu/dl/zImage (kernel)
>https://osdn.net/users/ysato/pf/qemu/dl/rx-qemu.dtb (DeviceTree)
> 
> starting
> $ qemu-system-rx -kernel zImage -dtb rx-qemu.dtb -append "earlycon"
> 
> Changes for v10.
> - Fix build error for 32bit system.
> - Use "object_initialize_child" in create device instance.
> - Remove unused headers.
> - Avoid some magic number.
> - Clean up Kconfig symbols.
> 
> Yoshinori Sato (12):
>   target/rx: TCG translation
>   target/rx: TCG helper
>   target/rx: CPU definition
>   target/rx: RX disassembler
>   hw/intc: RX62N interrupt controller (ICUa)
>   hw/timer: RX62N internal timer modules
>   hw/char: RX62N serial communication interface (SCI)
>   hw/rx: RX Target hardware definition
>   hw/registerfields.h: Add 8bit and 16bit register macros.
>   qemu/bitops.h: Add extract8 and extract16
>   Add rx-softmmu
>   MAINTAINERS: Add RX
> 
>  MAINTAINERS|   19 +
>  arch_init.c|2 +
>  configure  |8 +
>  default-configs/rx-softmmu.mak |3 +
>  hw/Kconfig |1 +
>  hw/char/Kconfig|3 +
>  hw/char/Makefile.objs  |1 +
>  hw/char/renesas_sci.c  |  340 ++
>  hw/intc/Kconfig|3 +
>  hw/intc/Makefile.objs  |1 +
>  hw/intc/rx_icu.c   |  376 +++
>  hw/rx/Kconfig  |   14 +
>  hw/rx/Makefile.objs|2 +
>  hw/rx/rx-virt.c|  105 ++
>  hw/rx/rx62n.c  |  238 
>  hw/timer/Kconfig   |6 +
>  hw/timer/Makefile.objs |3 +
>  hw/timer/renesas_cmt.c |  275 +
>  hw/timer/renesas_tmr.c |  455 
>  include/disas/dis-asm.h|5 +
>  include/hw/char/renesas_sci.h  |   45 +
>  include/hw/intc/rx_icu.h   |   57 +
>  include/hw/registerfields.h|   32 +-
>  include/hw/rx/rx.h |7 +
>  include/hw/rx/rx62n.h  |   94 ++
>  include/hw/timer/renesas_cmt.h |   38 +
>  include/hw/timer/renesas_tmr.h |   50 +
>  include/qemu/bitops.h  |   38 +
>  include/sysemu/arch_init.h |1 +
>  target/rx/Makefile.objs|   12 +
>  target/rx/cpu.c|  222 
>  target/rx/cpu.h|  227 
>  target/rx/disas.c  | 1480 
>  target/rx/gdbstub.c|  112 ++
>  target/rx/helper.c |  148 +++
>  target/rx/helper.h |   31 +
>  target/rx/insns.decode |  621 ++
>  target/rx/monitor.c|   38 +
>  target/rx/op_helper.c  |  481 
>  target/rx/translate.c  | 2432 
> 
>  40 files changed, 8025 insertions(+), 1 deletion(-)
>  create mode 100644 default-configs/rx-softmmu.

Re: [Qemu-devel] [PATCH 07/13] target/arm/kvm: max cpu: Allow sve max vector length setting

2019-05-13 Thread Richard Henderson
On 5/12/19 1:36 AM, Andrew Jones wrote:
> @@ -292,7 +292,7 @@ static void aarch64_max_initfn(Object *obj)
>  
>  if (kvm_enabled()) {
>  kvm_arm_set_cpu_features_from_host(cpu);
> -cpu->sve_max_vq = ARM_MAX_VQ;
> +cpu->sve_max_vq = -1; /* set in kvm_arch_init_vcpu() */

Perhaps a better comment is "unspecified, to be finalized in ..."

> +object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
> +cpu_max_set_sve_vq, NULL, NULL, _fatal);

as one can set it here, via the command-line.

> @@ -644,6 +702,24 @@ int kvm_arch_init_vcpu(CPUState *cs)
>  }
>  
>  if (cpu->sve_max_vq) {
> +uint64_t sve_vls[KVM_ARM64_SVE_VLS_WORDS];
> +ret = kvm_arm_get_sve_vls(cs, sve_vls);
> +if (ret < 0) {
> +return ret;
> +}
> +if (cpu->sve_max_vq == -1) {
> +cpu->sve_max_vq = ret;

You still cannot set a value larger than ARM_MAX_VQ, as that is the fixed
amount of space allocated within the cpu structure.


r~



Re: [Qemu-devel] [PATCH v4 3/8] hw/acpi: Add ACPI Generic Event Device Support

2019-05-13 Thread Shameerali Kolothum Thodi
> -Original Message-
> From: Igor Mammedov [mailto:imamm...@redhat.com]
> Sent: 13 May 2019 17:25
> To: Shameerali Kolothum Thodi 
> Subject: Re: [PATCH v4 3/8] hw/acpi: Add ACPI Generic Event Device Support
> 
> On Mon, 13 May 2019 11:53:38 +
> Shameerali Kolothum Thodi  wrote:
> 
> > Hi Igor,
> >
> > > -Original Message-
> > > From: Shameerali Kolothum Thodi
> > > Sent: 03 May 2019 13:46
> > > To: 'Igor Mammedov' 
> > > Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org;
> > > eric.au...@redhat.com; peter.mayd...@linaro.org;
> > > shannon.zha...@gmail.com; sa...@linux.intel.com;
> > > sebastien.bo...@intel.com; xuwei (O) ;
> > > ler...@redhat.com; ard.biesheu...@linaro.org; Linuxarm
> > > 
> > > Subject: RE: [PATCH v4 3/8] hw/acpi: Add ACPI Generic Event Device
> Support
> > >
> > > Hi Igor,
> > >
> > > > -Original Message-
> > > > From: Igor Mammedov [mailto:imamm...@redhat.com]
> > > > Sent: 02 May 2019 17:13
> > > > To: Shameerali Kolothum Thodi
> 
> > > > Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org;
> > > > eric.au...@redhat.com; peter.mayd...@linaro.org;
> > > > shannon.zha...@gmail.com; sa...@linux.intel.com;
> > > > sebastien.bo...@intel.com; xuwei (O) ;
> > > > ler...@redhat.com; ard.biesheu...@linaro.org; Linuxarm
> > > > 
> > > > Subject: Re: [PATCH v4 3/8] hw/acpi: Add ACPI Generic Event Device
> Support
> > > >
> >
> > [...]
> >
> > > > > +}
> > > > > +
> > > > > +static Property acpi_ged_properties[] = {
> > > > > +/*
> > > > > + * Memory hotplug base address is a property of GED here,
> > > > > + * because GED handles memory hotplug event and
> > > > MEMORY_HOTPLUG_DEVICE
> > > > > + * gets initialized when GED device is realized.
> > > > > + */
> > > > > +DEFINE_PROP_UINT64("memhp-base", AcpiGedState,
> memhp_base,
> > > > 0),
> > > > > +DEFINE_PROP_BOOL("memory-hotplug-support", AcpiGedState,
> > > > > + memhp_state.is_enabled, true),
> > > > > +DEFINE_PROP_PTR("gsi", AcpiGedState, gsi),
> > > >
> > > > PTR shouldn't be used in new code, look at object_property_add_link() &
> co
> > >
> > > Ok. I will take a look at that.
> >
> > I attempted to remove _PROP_PTR for "ged-events" and use _PROP_LINK
> and
> > _set_link(),
> >
> >
> > diff --git a/hw/acpi/generic_event_device.c
> b/hw/acpi/generic_event_device.c
> > index 856ca04c01..978c8e088e 100644
> > --- a/hw/acpi/generic_event_device.c
> > +++ b/hw/acpi/generic_event_device.c
> > @@ -268,7 +268,8 @@ static Property acpi_ged_properties[] = {
> >  DEFINE_PROP_PTR("gsi", AcpiGedState, gsi),
> >  DEFINE_PROP_UINT64("ged-base", AcpiGedState, ged_base, 0),
> >  DEFINE_PROP_UINT32("ged-irq", AcpiGedState, ged_irq, 0),
> > -DEFINE_PROP_PTR("ged-events", AcpiGedState, ged_events),
> > +DEFINE_PROP_LINK("ged-events", AcpiGedState, ged_events,
> TYPE_ACPI_GED,
> > + GedEvent *),
> >  DEFINE_PROP_UINT32("ged-events-size", AcpiGedState,
> ged_events_size, 0),
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index 8179b3e511..c89b7b7120 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -537,7 +537,8 @@ static inline DeviceState
> *create_acpi_ged(VirtMachineState *vms)
> >  qdev_prop_set_ptr(dev, "gsi", vms->gsi);
> >  qdev_prop_set_uint64(dev, "ged-base",
> vms->memmap[VIRT_ACPI_GED].base);
> >  qdev_prop_set_uint32(dev, "ged-irq", vms->irqmap[VIRT_ACPI_GED]);
> > -qdev_prop_set_ptr(dev, "ged-events", ged_events);
> > +object_property_set_link(OBJECT(dev), OBJECT(ged_events),
> "ged-events",
> > + _abort);
> >  qdev_prop_set_uint32(dev, "ged-events-size",
> ARRAY_SIZE(ged_events));
> >
> >  object_property_add_child(qdev_get_machine(), "acpi-ged",
> > diff --git a/include/hw/acpi/generic_event_device.h
> b/include/hw/acpi/generic_event_device.h
> > index 9c840d8064..588f4ecfba 100644
> > --- a/include/hw/acpi/generic_event_device.h
> > +++ b/include/hw/acpi/generic_event_device.h
> > @@ -111,7 +111,7 @@ typedef struct AcpiGedState {
> >  hwaddr ged_base;
> >  GEDState ged_state;
> >  uint32_t ged_irq;
> > -void *ged_events;
> > +GedEvent *ged_events;
> >  uint32_t ged_events_size;
> >  } AcpiGedState;
> >
> >
> > And with this I get,
> >
> > Segmentation fault  (core dumped) ./qemu-system-aarch64-ged-v5
> > -machine virt, -cpu cortex-a57 -machine type=virt -nographic -smp 1 -m
> > 4G,maxmem=8G,slots=10 -drive if=none,file=ubuntu-est-5.0,id=fs -device
> > virtio-blk-device,drive=fs -kernel Image_memhp_remove -bios
> > QEMU_EFI_Release.fd -object memory-backend-ram,id=mem1,size=1G
> -device
> > pc-dimm,id=dimm1,memdev=mem1 -numa node,nodeid=0 -append
> > "console=ttyAMA0 root=/dev/vda rw acpi=force movable_node"
> >
> > It looks like struct pointer cannot be used directly and has to make a QOM
> object
> > for DEFINE_PROP_LINK use. Not sure there is an easy way for setting ptr
> property
> 

Re: [Qemu-devel] [PULL 4/9] linux-user/nios2 linux-user/riscv: Clean up header guards

2019-05-13 Thread Peter Maydell
On Mon, 13 May 2019 at 17:56, Palmer Dabbelt  wrote:
>
> On Mon, 13 May 2019 01:18:39 PDT (-0700), arm...@redhat.com wrote:
> > Reuse of the same guard symbol in multiple headers is okay as long as
> > they cannot be included together.  scripts/clean-header-guards.pl
> > can't tell, so it warns.
> >
> > Since we can avoid guard symbol reuse easily, do so: use guard symbol
> > ${target^^}_${fname^^} for linux-user/$target/$fname, just like we did
> > in commit a9c94277f0..3500385697.
> >
> > Signed-off-by: Markus Armbruster 
> > Message-Id: <20190315145123.28030-4-arm...@redhat.com>
> > Reviewed-by: Philippe Mathieu-Daudé 

> Reviewed-by: Palmer Dabbelt 
>
> I'm assuming this is going in through someone else's tree, so I'm not going to
> pick it up into mine.

The subject line says "PULL" rather than "PATCH", so it is
already going into master (indeed I just applied it).
In general there's not much point in commenting on
patches in pull requests on the lists except for "this
has a problem, please don't apply it" feedback. (In that
case you should reply to the cover letter, because I won't
necessarily see replies to individual patches in the pull
before I apply the pull.)

thanks
-- PMM



Re: [Qemu-devel] [PATCH 05/13] target/arm/kvm: Add kvm_arch_get/put_sve

2019-05-13 Thread Richard Henderson
On 5/13/19 7:39 AM, Dave Martin wrote:
> On that point, could TCG easily be made to expose a larger vector length
> to the kernel?  I'd be interested to see what happened.

It would be easy enough to extend the maximum vector length within TCG.

Increase ARM_MAX_VQ.  Alter the couple of places where we manipulate ZCR.LEN to
extend the current 4-bit mask.

How large do you need the max to be, for testing?


r~



Re: [Qemu-devel] [PULL 4/9] linux-user/nios2 linux-user/riscv: Clean up header guards

2019-05-13 Thread Palmer Dabbelt

On Mon, 13 May 2019 01:18:39 PDT (-0700), arm...@redhat.com wrote:

Reuse of the same guard symbol in multiple headers is okay as long as
they cannot be included together.  scripts/clean-header-guards.pl
can't tell, so it warns.

Since we can avoid guard symbol reuse easily, do so: use guard symbol
${target^^}_${fname^^} for linux-user/$target/$fname, just like we did
in commit a9c94277f0..3500385697.

Signed-off-by: Markus Armbruster 
Message-Id: <20190315145123.28030-4-arm...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
---
 linux-user/nios2/target_cpu.h | 4 ++--
 linux-user/nios2/target_signal.h  | 6 +++---
 linux-user/nios2/target_structs.h | 4 ++--
 linux-user/nios2/target_syscall.h | 6 +++---
 linux-user/riscv/target_cpu.h | 4 ++--
 linux-user/riscv/target_signal.h  | 6 +++---
 linux-user/riscv/target_structs.h | 4 ++--
 7 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
index 14f63338fa..5596c05c9c 100644
--- a/linux-user/nios2/target_cpu.h
+++ b/linux-user/nios2/target_cpu.h
@@ -17,8 +17,8 @@
  * License along with this library; if not, see .
  */
 
-#ifndef TARGET_CPU_H

-#define TARGET_CPU_H
+#ifndef NIOS2_TARGET_CPU_H
+#define NIOS2_TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUNios2State *env, target_ulong newsp)

 {
diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h
index 7776bcdbfd..fe48721b3d 100644
--- a/linux-user/nios2/target_signal.h
+++ b/linux-user/nios2/target_signal.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SIGNAL_H
-#define TARGET_SIGNAL_H
+#ifndef NIOS2_TARGET_SIGNAL_H
+#define NIOS2_TARGET_SIGNAL_H
 
 /* this struct defines a stack used during syscall handling */
 
@@ -18,4 +18,4 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
-#endif /* TARGET_SIGNAL_H */

+#endif /* NIOS2_TARGET_SIGNAL_H */
diff --git a/linux-user/nios2/target_structs.h 
b/linux-user/nios2/target_structs.h
index 8713772089..7145251706 100644
--- a/linux-user/nios2/target_structs.h
+++ b/linux-user/nios2/target_structs.h
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see .
  */
-#ifndef TARGET_STRUCTS_H
-#define TARGET_STRUCTS_H
+#ifndef NIOS2_TARGET_STRUCTS_H
+#define NIOS2_TARGET_STRUCTS_H
 
 struct target_ipc_perm {

 abi_int __key;  /* Key.  */
diff --git a/linux-user/nios2/target_syscall.h 
b/linux-user/nios2/target_syscall.h
index ca6b7e69f6..f3b2a500f4 100644
--- a/linux-user/nios2/target_syscall.h
+++ b/linux-user/nios2/target_syscall.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SYSCALL_H
-#define TARGET_SYSCALL_H
+#ifndef NIOS2_TARGET_SYSCALL_H
+#define NIOS2_TARGET_SYSCALL_H
 
 #define UNAME_MACHINE "nios2"

 #define UNAME_MINIMUM_RELEASE "3.19.0"
@@ -34,4 +34,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif  /* TARGET_SYSCALL_H */

+#endif /* NIOS2_TARGET_SYSCALL_H */
diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h
index 7e090f376a..90f9a4171e 100644
--- a/linux-user/riscv/target_cpu.h
+++ b/linux-user/riscv/target_cpu.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_CPU_H
-#define TARGET_CPU_H
+#ifndef RISCV_TARGET_CPU_H
+#define RISCV_TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPURISCVState *env, target_ulong newsp)

 {
diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
index c8b1455800..f113ba9a55 100644
--- a/linux-user/riscv/target_signal.h
+++ b/linux-user/riscv/target_signal.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SIGNAL_H
-#define TARGET_SIGNAL_H
+#ifndef RISCV_TARGET_SIGNAL_H
+#define RISCV_TARGET_SIGNAL_H
 
 typedef struct target_sigaltstack {

 abi_ulong ss_sp;
@@ -15,4 +15,4 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
-#endif /* TARGET_SIGNAL_H */

+#endif /* RISCV_TARGET_SIGNAL_H */
diff --git a/linux-user/riscv/target_structs.h 
b/linux-user/riscv/target_structs.h
index 4f0462c497..ea3e5ed17e 100644
--- a/linux-user/riscv/target_structs.h
+++ b/linux-user/riscv/target_structs.h
@@ -4,8 +4,8 @@
  * This is a copy of ../aarch64/target_structs.h atm.
  *
  */
-#ifndef TARGET_STRUCTS_H
-#define TARGET_STRUCTS_H
+#ifndef RISCV_TARGET_STRUCTS_H
+#define RISCV_TARGET_STRUCTS_H
 
 struct target_ipc_perm {

 abi_int __key;  /* Key.  */
--
2.17.2


Reviewed-by: Palmer Dabbelt 

I'm assuming this is going in through someone else's tree, so I'm not going to
pick it up into mine.



Re: [Qemu-devel] [PULL v3 00/29] Kconfig for Arm

2019-05-13 Thread Peter Maydell
On Mon, 13 May 2019 at 09:29, Thomas Huth  wrote:
>
>  Hi Peter,
>
> the following changes since commit efb4f3b62c69383a7308d7b739a3193e7c0ccae8:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' 
> into staging (2019-05-10 14:49:36 +0100)
>
> are available in the Git repository at:
>
>   https://gitlab.com/huth/qemu.git tags/pull-request-2019-05-13
>
> for you to fetch changes up to 704d9892561d3b7ac4728296240a1b3ccfa2045a:
>
>   hw/arm: Remove hard-enablement of the remaining PCI devices (2019-05-13 
> 09:36:32 +0200)
>
> 
> Kconfig settings for the Arm machines
> (v3: Added the config-devices.mak.d patch to fix the dependencies)


Applied, thanks.

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

-- PMM



Re: [Qemu-devel] [PATCH 05/13] target/arm/kvm: Add kvm_arch_get/put_sve

2019-05-13 Thread Richard Henderson
On 5/13/19 5:31 AM, Dave Martin wrote:
> On Sun, May 12, 2019 at 09:36:16AM +0100, Andrew Jones wrote:
>> These are the SVE equivalents to kvm_arch_get/put_fpsimd.
>>
>> Signed-off-by: Andrew Jones 
>> ---
>>  target/arm/kvm64.c | 127 +++--
>>  1 file changed, 123 insertions(+), 4 deletions(-)
> 
> [...]
> 
>> +static int kvm_arch_put_sve(CPUState *cs)
>> +{
>> +ARMCPU *cpu = ARM_CPU(cs);
>> +CPUARMState *env = >env;
>> +struct kvm_one_reg reg;
>> +int n, ret;
>> +
>> +for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; n++) {
>> +uint64_t *q = aa64_vfp_qreg(env, n);
>> +#ifdef HOST_WORDS_BIGENDIAN
>> +uint64_t d[ARM_MAX_VQ * 2];
>> +int i;
>> +for (i = 0; i < cpu->sve_max_vq * 2; i++) {
>> +d[i] = q[cpu->sve_max_vq * 2 - 1 - i];
>> +}
> 
> Out of interest, why do all this swabbing?  It seems expensive.

Indeed, to me this seems to be the wrong kind of swabbing here.  Exactly what
format is KVM expecting?  Surely it should be the one used by the unpredicated
LDR/STR instructions.  Anything else would seem to be working against the
architecture.

If so, the format is, architecturally, a stream of bytes in index order, which
corresponds to a little-endian stream of words.  So the loop I'd expect to see
here is

for (i = 0, n = cpu->sve_max_vq; i < n; ++i) {
d[i] = bswap64(q[i]);
}


r~



Re: [Qemu-devel] [PATCH v2] iotests: Filter 175's allocation information

2019-05-13 Thread Eric Blake
On 5/13/19 10:52 AM, Max Reitz wrote:
> It is possible for an empty file to take up blocks on a filesystem.
> Make iotest 175 take this into account.
> 
> Reported-by: Thomas Huth 
> Signed-off-by: Max Reitz 
> ---
> v2: [Nir]
> - Use a function for filtering
> - s/empty_blocks/extra_blocks/
> ---

> +# Some file systems sometimes allocate extra blocks independently of
> +# the file size.  This function hides the resulting difference in the
> +# stat -c '%b' output.
> +# Parameter 1: Number of blocks an empty file occupies
> +# Parameter 2: Image size in bytes
> +_filter_blocks()
> +{
> +extra_blocks=$1
> +img_size=$2
> +
> +sed -e "s/blocks=$extra_blocks/nothing allocated/" \
> +-e "s/blocks=$((extra_blocks + img_size / 512))/everything 
> allocated/"
> +}

That turned out nicely.

Reviewed-by: Eric Blake 

> -size=1m
> +size=$((1 * 1024 * 1024))

Had to change since bash doesn't understand '1m' inside $(()).

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] tests/libqtest: Fix description of qtest_vinitf() and qtest_initf()

2019-05-13 Thread Eric Blake
On 5/13/19 10:47 AM, Thomas Huth wrote:
> These functions are convenience wrappers of qtest_init() and not of
> qtest_start().
> 
> Signed-off-by: Thomas Huth 
> ---
>  tests/libqtest.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 08/13] target/arm/monitor: Add query-sve-vector-lengths

2019-05-13 Thread Markus Armbruster
Andrew Jones  writes:

> Provide a QMP interface to query the supported SVE vector lengths.
> A migratable guest will need to explicitly specify a valid set of
> lengths on the command line and that set can be obtained from the
> list returned with this QMP command.
>
> This patch only introduces the QMP command with the TCG implementation.
> The result may not yet be correct for KVM. Following patches ensure
> the KVM result is correct.
>
> Signed-off-by: Andrew Jones 
> ---
>  qapi/target.json | 34 
>  target/arm/monitor.c | 62 
>  tests/qmp-cmd-test.c |  1 +
>  3 files changed, 97 insertions(+)
>
> diff --git a/qapi/target.json b/qapi/target.json
> index 1d4d54b6002e..ca1e85254780 100644
> --- a/qapi/target.json
> +++ b/qapi/target.json
> @@ -397,6 +397,40 @@
>  { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
>'if': 'defined(TARGET_ARM)' }
>  
> +##
> +# @SVEVectorLengths:
> +#
> +# The struct contains a list of integers where each integer is a valid

Suggest to s/The struct contains/Contains/.

> +# SVE vector length for a KVM guest on this host. The vector lengths
> +# are in quadword (128-bit) units, e.g. '4' means 512 bits (64 bytes).

Any particular reason for counting quad-words instead of bytes, or
perhaps bits?

> +#
> +# @vls:  list of vector lengths in quadwords.
> +#
> +# Since: 4.1
> +##
> +{ 'struct': 'SVEVectorLengths',
> +  'data': { 'vls': ['int'] },
> +  'if': 'defined(TARGET_ARM)' }
> +
> +##
> +# @query-sve-vector-lengths:
> +#
> +# This command is ARM-only. It will return a list of SVEVectorLengths

No other target-specific command documents its target-specificness like
this.  Suggest

   # Query valid SVE vector length sets.

> +# objects. The list describes all valid SVE vector length sets.
> +#
> +# Returns: a list of SVEVectorLengths objects
> +#
> +# Since: 4.1
> +#
> +# -> { "execute": "query-sve-vector-lengths" }
> +# <- { "return": [ { "vls": [ 1 ] },
> +#  { "vls": [ 1, 2 ] },
> +#  { "vls": [ 1, 2, 4 ] } ] }
> +#
> +##
> +{ 'command': 'query-sve-vector-lengths', 'returns': ['SVEVectorLengths'],
> +  'if': 'defined(TARGET_ARM)' }
> +
>  ##
>  # @CpuModelExpansionInfo:
>  #
> diff --git a/target/arm/monitor.c b/target/arm/monitor.c
> index 41b32b94b258..8b2afa255c92 100644
> --- a/target/arm/monitor.c
> +++ b/target/arm/monitor.c
> @@ -24,6 +24,7 @@
>  #include "hw/boards.h"
>  #include "kvm_arm.h"
>  #include "qapi/qapi-commands-target.h"
> +#include "monitor/hmp-target.h"

Uh, hmp-target.h when the patch is supposedly about QMP only...

>  
>  static GICCapability *gic_cap_new(int version)
>  {
> @@ -82,3 +83,64 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
>  
>  return head;
>  }
> +
> +static SVEVectorLengths *qmp_sve_vls_get(void)
> +{
> +CPUArchState *env = mon_get_cpu_env();

Aha, you need it for mon_get_cpu_env().

mon_get_cpu_env() returns the current monitor's current CPU.  This is an
HMP thing, QMP commands should never access it.

Looks like you use it to find one of the CPUs, so you can access its
->sve_max_vq.

"One of the CPUs" smells odd: what if they aren't all the same?  Perhaps
that can't happen.  I don't know, you tell me :)

If any CPU will do, what about simply using first_cpu?

> +ARMCPU *cpu = arm_env_get_cpu(env);
> +SVEVectorLengths *vls = g_new(SVEVectorLengths, 1);
> +intList **v = >vls;
> +int i;
> +
> +if (cpu->sve_max_vq == 0) {
> +*v = g_new0(intList, 1); /* one vl of 0 means none supported */
> +return vls;
> +}
> +
> +for (i = 1; i <= cpu->sve_max_vq; ++i) {
> +*v = g_new0(intList, 1);
> +(*v)->value = i;
> +v = &(*v)->next;
> +}

What this loop does is not immediately obvious.  I think you could use a
function comment.

> +
> +return vls;
> +}
> +
> +static SVEVectorLengths *qmp_sve_vls_dup_and_truncate(SVEVectorLengths *vls)
> +{
> +SVEVectorLengths *trunc_vls;
> +intList **v, *p = vls->vls;
> +
> +if (!p->next) {
> +return NULL;
> +}
> +
> +trunc_vls = g_new(SVEVectorLengths, 1);
> +v = _vls->vls;
> +
> +for (; p->next; p = p->next) {
> +*v = g_new0(intList, 1);
> +(*v)->value = p->value;
> +v = &(*v)->next;
> +}
> +
> +return trunc_vls;
> +}

More so.

> +
> +SVEVectorLengthsList *qmp_query_sve_vector_lengths(Error **errp)
> +{
> +SVEVectorLengthsList *vls_list = g_new0(SVEVectorLengthsList, 1);
> +SVEVectorLengths *vls = qmp_sve_vls_get();
> +
> +while (vls) {
> +vls_list->value = vls;
> +vls = qmp_sve_vls_dup_and_truncate(vls);
> +if (vls) {
> +SVEVectorLengthsList *next = vls_list;
> +vls_list = g_new0(SVEVectorLengthsList, 1);
> +vls_list->next = next;
> +}
> +}
> +
> +return vls_list;
> +}
> diff --git a/tests/qmp-cmd-test.c b/tests/qmp-cmd-test.c
> 

  1   2   3   4   >