Re: [Qemu-devel] [PATCH v6 4/6] include/elf: Add defines related to notes for GNU systems

2019-06-05 Thread Aleksandar Markovic
On Jun 5, 2019 11:03 PM, "Richard Henderson" 
wrote:
>
> This is a collection of related

Related to what?

> defines for notes, copied
> from glibc's .  We're not going to use all of these
> right away, but it seemed foolish

I don't think this an appropriate word for a commit message.

> to cherry-pick only the
> ones we need now.
>
> Signed-off-by: Richard Henderson 
> ---
>  include/elf.h | 48 
>  1 file changed, 48 insertions(+)
>
> diff --git a/include/elf.h b/include/elf.h
> index ea7708a4ea..6f3eada36f 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -1650,6 +1650,54 @@ typedef struct elf64_shdr {
>  #define NT_ARM_HW_WATCH 0x403   /* ARM hardware watchpoint
registers */
>  #define NT_ARM_SYSTEM_CALL  0x404   /* ARM system call number */
>
> +/* Defined note types for GNU systems.  */
> +
> +#define NT_GNU_ABI_TAG  1   /* ABI information */
> +#define NT_GNU_HWCAP2   /* Synthetic hwcap information */
> +#define NT_GNU_BUILD_ID 3   /* Build ID */
> +#define NT_GNU_GOLD_VERSION 4   /* Version of ld.gold */
> +#define NT_GNU_PROPERTY_TYPE_0  5   /* Program property */
> +
> +/* Values used in GNU .note.gnu.property notes
(NT_GNU_PROPERTY_TYPE_0).  */
> +
> +#define GNU_PROPERTY_STACK_SIZE 1
> +#define GNU_PROPERTY_NO_COPY_ON_PROTECTED   2
> +
> +#define GNU_PROPERTY_LOPROC 0xc000
> +#define GNU_PROPERTY_HIPROC 0xdfff
> +#define GNU_PROPERTY_LOUSER 0xe000
> +#define GNU_PROPERTY_HIUSER 0x
> +
> +#define GNU_PROPERTY_X86_ISA_1_USED 0xc000
> +#define GNU_PROPERTY_X86_ISA_1_NEEDED   0xc001
> +
> +#define GNU_PROPERTY_X86_ISA_1_486  (1U << 0)
> +#define GNU_PROPERTY_X86_ISA_1_586  (1U << 1)
> +#define GNU_PROPERTY_X86_ISA_1_686  (1U << 2)
> +#define GNU_PROPERTY_X86_ISA_1_SSE  (1U << 3)
> +#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4)
> +#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5)
> +#define GNU_PROPERTY_X86_ISA_1_SSSE3(1U << 6)
> +#define GNU_PROPERTY_X86_ISA_1_SSE4_1   (1U << 7)
> +#define GNU_PROPERTY_X86_ISA_1_SSE4_2   (1U << 8)
> +#define GNU_PROPERTY_X86_ISA_1_AVX  (1U << 9)
> +#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512F  (1U << 11)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17)
> +
> +#define GNU_PROPERTY_X86_FEATURE_1_AND  0xc002
> +#define GNU_PROPERTY_X86_FEATURE_1_IBT  (1U << 0)
> +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK(1U << 1)
> +
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND  0xc000
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI  (1u << 0)
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC  (1u << 1)
> +
>  /*
>   * Physical entry point into the kernel.
>   *
> --
> 2.17.1
>
>


Re: [Qemu-devel] Qemu baseline requirements/portability?

2019-06-05 Thread Markus Armbruster
"H. Peter Anvin"  writes:

> On 6/5/19 12:55 PM, H. Peter Anvin wrote:
>> Hi,
>> 
>> I am writing some code I'm hoping will be able to make it into Qemu, but I
>> can't seem to find what the baseline portability requirements are.  I'm
>> specifically wondering about newer POSIX features like openat(), which seems
>> to be used in the 9p filesystem and nowhere else, and what version of glib 
>> one
>> can rely on?
>> 
>
> Specifically, I'm trying to satisfy a 10-year-old request by me and others to
> support composite initrd during Linux boot.

Please peruse qemu-doc.texi @appendix Supported build platforms.  If it
doesn't fully answer your question, ask for clarification here.



Re: [Qemu-devel] [Qemu-devel PATCH v2 2/2] util/main-loop: Fix incorrect assertion

2019-06-05 Thread Markus Armbruster
You neglected to cc: the file's maintainer.  I'm doing that for you now.
In the future, use scripts/get_maintainer.pl to find maintainers you
might want to cc:.

Lidong Chen  writes:

> The check for poll_fds in g_assert() was incorrect. The correct assertion
> should check "n_poll_fds + w->num <= ARRAY_SIZE(poll_fds)" because the
> subsequent for-loop is doing access to poll_fds[n_poll_fds + i] where i
> is in [0, w->num).
>
> Signed-off-by: Lidong Chen 
> Suggested-by: Peter Maydell 
> Suggested-by: Liam Merwick 
> Reviewed-by: Liran Alon 
> Reviewed-by: Darren Kenny 
> Reviewed-by: Li Qiang 
> ---
>  util/main-loop.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/util/main-loop.c b/util/main-loop.c
> index e1e349c..a9f4e8d 100644
> --- a/util/main-loop.c
> +++ b/util/main-loop.c
> @@ -422,7 +422,7 @@ static int os_host_main_loop_wait(int64_t timeout)
>  g_main_context_prepare(context, _priority);
>  n_poll_fds = g_main_context_query(context, max_priority, _timeout,
>poll_fds, ARRAY_SIZE(poll_fds));
> -g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
> +g_assert(n_poll_fds + w->num <= ARRAY_SIZE(poll_fds));
>  
>  for (i = 0; i < w->num; i++) {
>  poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];



Re: [Qemu-devel] [Qemu-ppc] [PATCH v9 1/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-06-05 Thread Aravinda Prasad



On Thursday 06 June 2019 07:04 AM, David Gibson wrote:
> On Wed, May 29, 2019 at 11:10:14AM +0530, Aravinda Prasad wrote:
>> This patch adds support in QEMU to handle "ibm,nmi-register"
>> and "ibm,nmi-interlock" RTAS calls.
>>
>> The machine check notification address is saved when the
>> OS issues "ibm,nmi-register" RTAS call.
>>
>> This patch also handles the case when multiple processors
>> experience machine check at or about the same time by
>> handling "ibm,nmi-interlock" call. In such cases, as per
>> PAPR, subsequent processors serialize waiting for the first
>> processor to issue the "ibm,nmi-interlock" call. The second
>> processor that also received a machine check error waits
>> till the first processor is done reading the error log.
>> The first processor issues "ibm,nmi-interlock" call
>> when the error log is consumed. This patch implements the
>> releasing part of the error-log while subsequent patch
>> (which builds error log) handles the locking part.
>>
>> Signed-off-by: Aravinda Prasad 
>> Reviewed-by: David Gibson 
>> ---
>>  hw/ppc/spapr.c |7 +
>>  hw/ppc/spapr_rtas.c|   65 
>> 
>>  include/hw/ppc/spapr.h |9 ++-
>>  3 files changed, 80 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index e2b33e5..fae28a9 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1808,6 +1808,11 @@ static void spapr_machine_reset(void)
>>  first_ppc_cpu->env.gpr[5] = 0;
>>  
>>  spapr->cas_reboot = false;
>> +
>> +spapr->guest_machine_check_addr = -1;
>> +
>> +/* Signal all vCPUs waiting on this condition */
>> +qemu_cond_broadcast(>mc_delivery_cond);
>>  }
>>  
>>  static void spapr_create_nvram(SpaprMachineState *spapr)
>> @@ -3072,6 +3077,8 @@ static void spapr_machine_init(MachineState *machine)
>>  
>>  kvmppc_spapr_enable_inkernel_multitce();
>>  }
>> +
>> +qemu_cond_init(>mc_delivery_cond);
>>  }
>>  
>>  static int spapr_kvm_type(MachineState *machine, const char *vm_type)
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index 5bc1a93..e7509cf 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -352,6 +352,38 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
>> SpaprMachineState *spapr,
>>  rtas_st(rets, 1, 100);
>>  }
>>  
>> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>> +  SpaprMachineState *spapr,
>> +  uint32_t token, uint32_t nargs,
>> +  target_ulong args,
>> +  uint32_t nret, target_ulong rets)
>> +{
>> +hwaddr rtas_addr = spapr_get_rtas_addr();
>> +
>> +if (!rtas_addr) {
>> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
>> +return;
>> +}
>> +
>> +spapr->guest_machine_check_addr = rtas_ld(args, 1);
>> +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +
>> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>> +   SpaprMachineState *spapr,
>> +   uint32_t token, uint32_t nargs,
>> +   target_ulong args,
>> +   uint32_t nret, target_ulong rets)
>> +{
>> +if (spapr->guest_machine_check_addr == -1) {
>> +/* NMI register not called */
>> +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
>> +} else {
>> +qemu_cond_signal(>mc_delivery_cond);
>> +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>> +}
>> +}
>> +
>>  static struct rtas_call {
>>  const char *name;
>>  spapr_rtas_fn fn;
>> @@ -470,6 +502,35 @@ void spapr_load_rtas(SpaprMachineState *spapr, void 
>> *fdt, hwaddr addr)
>>  }
>>  }
>>  
>> +hwaddr spapr_get_rtas_addr(void)
>> +{
>> +SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
>> +int rtas_node;
>> +const struct fdt_property *rtas_addr_prop;
>> +void *fdt = spapr->fdt_blob;
>> +uint32_t rtas_addr;
>> +
>> +/* fetch rtas addr from fdt */
>> +rtas_node = fdt_path_offset(fdt, "/rtas");
>> +if (rtas_node == 0) {
>> +return 0;
> 
> This is incorrect, a return code < 0 indicates an error which you
> should check for.  A return code of 0 indicates the root node, which
> could only happen if libfdt was badly buggy.

ok

> 
>> +}
>> +
>> +rtas_addr_prop = fdt_get_property(fdt, rtas_node, "linux,rtas-base", 
>> NULL);
> 
> fdt_get_property is generally only needed for certain edge cases.
> fdt_getprop() is a better option.

ok

> 
>> +if (!rtas_addr_prop) {
>> +return 0;
>> +}
>> +
>> +/*
>> + * We assume that the OS called RTAS instantiate-rtas, but some other
>> + * OS might call RTAS instantiate-rtas-64 instead. This fine as of now
>> + * as SLOF only supports 32-bit variant.
>> + */
>> +rtas_addr = fdt32_to_cpu(*(uint32_t *)rtas_addr_prop->data);
>> +return 

Re: [Qemu-devel] Deprecation policy and build dependencies

2019-06-05 Thread Markus Armbruster
Eric Blake  writes:

> On 6/5/19 3:13 PM, Eduardo Habkost wrote:
>
>>> IOW, I don't think RHEL-7 support as a build platform blocks us from
>>> dropping py2. We merely need to tweak our build platforms doc to clarify
>>> our intent wrt add-on yum repos.
>> 
>> If we clarify the docs in QEMU 4.1, is there anything that
>> prevents us from removing Python 2 support in QEMU 4.1 too?
>
> My take (but not definitive): if we have any CI setups that are testing
> RHEL 7 without software collections and/or EPEL, then save Python 2
> removal for 4.2 to give us time to update CI setups. But if all of our
> CI setups are already fine, and we clarify the docs, then I'm all for
> getting rid of Python 2 support in 4.1.

There's still time to update CI setups without undue haste.  But I agree
we don't want to lose CI even temporarily just to expedite getting rid
of Python 2.

> Similarly, if we are going to outlaw in-tree builds, let's get that done
> in 4.1 instead of waiting yet another release.

For that we need patches.



Re: [Qemu-devel] [Qemu-ppc] [PATCH v9 1/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-06-05 Thread Aravinda Prasad



On Tuesday 04 June 2019 08:20 PM, Greg Kurz wrote:
> On Tue, 4 Jun 2019 11:38:31 +0530
> Aravinda Prasad  wrote:
> 
>> On Monday 03 June 2019 04:47 PM, Greg Kurz wrote:
>>> On Mon, 3 Jun 2019 12:12:43 +0200
>>> Greg Kurz  wrote:
>>>   
 On Wed, 29 May 2019 11:10:14 +0530
 Aravinda Prasad  wrote:
  
> This patch adds support in QEMU to handle "ibm,nmi-register"
> and "ibm,nmi-interlock" RTAS calls.
>
> The machine check notification address is saved when the
> OS issues "ibm,nmi-register" RTAS call.
>
> This patch also handles the case when multiple processors
> experience machine check at or about the same time by
> handling "ibm,nmi-interlock" call. In such cases, as per
> PAPR, subsequent processors serialize waiting for the first
> processor to issue the "ibm,nmi-interlock" call. The second
> processor that also received a machine check error waits
> till the first processor is done reading the error log.
> The first processor issues "ibm,nmi-interlock" call
> when the error log is consumed. This patch implements the
> releasing part of the error-log while subsequent patch
> (which builds error log) handles the locking part.
>
> Signed-off-by: Aravinda Prasad 
> Reviewed-by: David Gibson 
> ---

 The code looks okay but it still seems wrong to advertise the RTAS
 calls to the guest that early in the series. The linux kernel in
 the guest will assume FWNMI is functional, which isn't true until
 patch 6 (yes, migration is part of the feature, it should be
 supported upfront, not fixed afterwards).

 It doesn't help much to introduce the RTAS calls early and to
 modify them in the other patches. I'd rather see the rest of
 the code first and a final patch that introduces the fully
 functional RTAS calls and calls spapr_rtas_register().
  
>>>
>>> Thinking again, you should introduce the "fwnmi-mce" spapr capability in
>>> its own patch first, default to "off" and and have the last patch in the
>>> series to switch the default to "on" for newer machine types only.
>>>
>>> This patch should then only register the RTAS calls if "fwnmi-mcr" is set
>>> to "on".
>>>
>>> This should address the fact that we don't want to expose a partially
>>> implemented FWNMI feature to the guest, and we don't want to support
>>> FWNMI at all with older machine types for the sake of compatibility.  
>>
>> When you say "expose a partially implemented FWNMI feature to the
>> guest", do you mean while debugging/bisect we may end up with exposing
>> the partially implemented FWNMI feature? Otherwise it is expected that
> 
> Yes, we don't want to break someone else's bisect.

ok.

> 
>> QEMU runs with all the 6 patches.
>>
>> If that is the case, I will have the rtas nmi register functionality as
>> the last patch in the series. This way we don't have to have spapr cap
>> turned off first and later turned on. However, as mentioned earlier
>> (when David raised the same concern), use of guest_machine_check_addr
>> may look odd at other patches as it is set only during rtas nmi register.
>>
> 
> Why odd ?

see below

> 
>> Or else, as a workaround, I can return RTAS_OUT_NOT_SUPPORTED for rtas
>> nmi register till the entire functionality is implemented and only in
>> the last patch in the series I will return RTAS_OUT_SUCCESS. This will
>> ensure that we have a logical connection between the patches and the
>> partially implemented fwnmi is not exposed to the guest kernel.
>>
> 
> Not exactly true. FWNMI would be exposed to the guest in the device tree
> and the guest kernel would _just_ fail to set the fwnmi_active global:
> 
>   if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr,
>   machine_check_addr))
>   fwnmi_active = 1;

Sorry for the confusion. I thought the suggestion was to introduce
rtas_ibm_nmi_register() call later in the series, but now I see that I
can still have rtas_ibm_nmi_register(), but have a final patch that
calls spapr_rtas_register().


> 
>> Regards,
>> Aravinda
>>
>>
>>
>>
>>>   
>  hw/ppc/spapr.c |7 +
>  hw/ppc/spapr_rtas.c|   65 
> 
>  include/hw/ppc/spapr.h |9 ++-
>  3 files changed, 80 insertions(+), 1 deletion(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e2b33e5..fae28a9 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1808,6 +1808,11 @@ static void spapr_machine_reset(void)
>  first_ppc_cpu->env.gpr[5] = 0;
>  
>  spapr->cas_reboot = false;
> +
> +spapr->guest_machine_check_addr = -1;
> +
> +/* Signal all vCPUs waiting on this condition */
> +qemu_cond_broadcast(>mc_delivery_cond);
>  }
>  
>  static void spapr_create_nvram(SpaprMachineState *spapr)
> @@ -3072,6 +3077,8 @@ static void 

Re: [Qemu-devel] [PATCH v4 04/11] acpi: introduce AcpiDeviceIfClass.build_mem_ranges hook

2019-06-05 Thread Tao Xu

On 5/24/2019 8:35 PM, Igor Mammedov wrote:

On Wed,  8 May 2019 14:17:19 +0800
Tao Xu  wrote:


Add build_mem_ranges callback to AcpiDeviceIfClass and use
it for generating SRAT and HMAT numa memory ranges.

Suggested-by: Igor Mammedov 
Co-developed-by: Liu Jingqi 
Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

...

diff --git a/stubs/pc_build_mem_ranges.c b/stubs/pc_build_mem_ranges.c
new file mode 100644
index 00..0f104ba79d
--- /dev/null
+++ b/stubs/pc_build_mem_ranges.c
@@ -0,0 +1,6 @@
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+
+void pc_build_mem_ranges(AcpiDeviceIf *adev, MachineState *machine)
+{
+}


why do you need stub?


Hi Igor,

I have questions here, I use stub here because we add hook pointer in 
piix4.c but other arch such mips use piix4. Without stub, it will failed 
when compile, like pc_madt_cpu_entry.

Or there are other way to make it use just in pc?

Thank you!




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

2019-06-05 Thread Aravinda Prasad



On Thursday 06 June 2019 08:32 AM, David Gibson wrote:
> On Tue, Jun 04, 2019 at 12:15:26PM +0530, Aravinda Prasad wrote:
>>
>>
>> On Monday 03 June 2019 08:55 PM, Greg Kurz wrote:
>>> On Wed, 29 May 2019 11:10:49 +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 
 ---
>>>
>>> As suggested in another mail, it may be worth introducing the sPAPR cap
>>> in its own patch, earlier in the series.
>>
>> Sure, also as a workaround mentioned in the reply to that mail, I am
>> thinking of returning RTAS_OUT_NOT_SUPPORTED to rtas nmi register call
>> until the entire functionality is implemented. This will help solve
>> spapr cap issue as well.
> 
> Not registering the RTAS call at all is the correct way to handle that
> case.

ok.

> 
>>
>>>
>>> Anyway, I have some comments below.
>>>
  hw/ppc/spapr.c |1 +
  hw/ppc/spapr_caps.c|   24 
  hw/ppc/spapr_rtas.c|   18 ++
  include/hw/ppc/spapr.h |4 +++-
  target/ppc/kvm.c   |   19 +++
  target/ppc/kvm_ppc.h   |   12 
  6 files changed, 77 insertions(+), 1 deletion(-)

 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index c97f6a6..e8a77636 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -4364,6 +4364,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_ON;
  spapr_caps_add_properties(smc, _abort);
  smc->irq = _irq_dual;
  smc->dr_phb_enabled = true;
 diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
 index 31b4661..ef9e612 100644
 --- a/hw/ppc/spapr_caps.c
 +++ b/hw/ppc/spapr_caps.c
 @@ -479,6 +479,20 @@ static void cap_ccf_assist_apply(SpaprMachineState 
 *spapr, uint8_t val,
  }
  }
  
 +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
 +Error **errp)
 +{
 +if (!val) {
 +return; /* Disabled by default */
 +}
 +
 +if (tcg_enabled()) {
 +error_setg(errp, "No fwnmi support in TCG, try 
 cap-fwnmi-mce=off");
>>>
>>> Maybe expand "fwnmi" to "Firmware Assisted Non-Maskable Interrupts" ?
>>
>> sure..
>>
>>>
 +} else if (kvm_enabled() && !kvmppc_has_cap_ppc_fwnmi()) {
 +error_setg(errp, "Requested fwnmi capability not support by 
 KVM");
>>>
>>> Maybe reword and add a hint:
>>>
>>> "KVM implementation does not support Firmware Assisted Non-Maskable 
>>> Interrupts, try cap-fwnmi-mce=off"
>>
>> sure..
>>
>>>
>>>
 +}
 +}
 +
  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
  [SPAPR_CAP_HTM] = {
  .name = "htm",
 @@ -578,6 +592,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,
 @@ -717,6 +740,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, 
 SPAPR_CAP_HPT_MAXPAGESIZE);
  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 e0bdfc8..91a7ab9 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, 

Re: [Qemu-devel] [PATCH v7 2/4] rng-builtin: add an RNG backend that uses qemu_guest_getrandom()

2019-06-05 Thread Markus Armbruster
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 ...
>
> Signed-off-by: Laurent Vivier 
> ---
>  backends/Makefile.objs |  2 +-
>  backends/rng-builtin.c | 78 ++
>  qemu-options.hx|  7 
>  3 files changed, 86 insertions(+), 1 deletion(-)
>  create mode 100644 backends/rng-builtin.c
>
> diff --git a/backends/Makefile.objs b/backends/Makefile.objs
> index 981e8e122f2c..f0691116e86e 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 ..3381d47174df
> --- /dev/null
> +++ b/backends/rng-builtin.c
> @@ -0,0 +1,78 @@
> +/*
> + * 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 "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;
> +QEMUBH *bh;
> +} RngBuiltin;
> +
> +static void rng_builtin_receive_entropy_bh(void *opaque)
> +{
> +RngBuiltin *s = opaque;
> +
> +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_request_entropy(RngBackend *b, RngRequest *req)
> +{
> +RngBuiltin *s = RNG_BUILTIN(b);
> +
> +qemu_bh_schedule(s->bh);
> +}

A comment explaining the need for a BH would be nice.

Regardless:
Reviewed-by: Markus Armbruster 

[...]



Re: [Qemu-devel] [PATCH v7 0/4] rng-builtin: add an RNG backend that uses qemu_guest_getrandom()

2019-06-05 Thread Markus Armbruster
Laurent Vivier  writes:

> On 05/06/2019 19:56, Markus Armbruster wrote:
>> Laurent Vivier  writes:
>> 
>>> On 05/06/2019 15:05, Markus Armbruster wrote:
 Laurent Vivier  writes:

> Add a new RNG backend using QEMU builtin getrandom function.
>
> v7: rebase on master
> Make rng-builtin asynchronous with QEMUBH (removed existing R-b)

 Pardon the ignorant question: why is that necessary?

>>>
>>> Because request_entropy() function is called while the request is not in
>>> the requests queue, so the loop on !QSIMPLEQ_EMPTY(>parent.requests)
>>> doens't process it. The request is added just after the call.
>> 
>> In rng_backend_request_entropy().  I see.  Any particular reason for
>> this order?  "I don't know" is an acceptable answer :)
>> 
>
> Yes...
>
> and there is a reason:
>
> in rng_random_request_entropy(), QSIMPLEQ_EMPTY() is used to know if we
> have to register an fd handler with qemu_set_fd_handler().
>
> For me, it seemed easier to use QEMUBH rather than to change the
> existing algorithm, as the backend has been thought to be asynchronous.

In your shoes, I'd be tempted to explore whether changing the order
simplifies things overall.  I'm not asking you to do that; your patch is
okay as is.

Thanks!



Re: [Qemu-devel] [PATCH v9 3/6] target/ppc: Handle NMI guest exit

2019-06-05 Thread Aravinda Prasad



On Thursday 06 June 2019 07:13 AM, David Gibson wrote:
> On Wed, May 29, 2019 at 11:10:32AM +0530, Aravinda Prasad wrote:
>> Memory error such as bit flips that cannot be corrected
>> by hardware are passed on to the kernel for handling.
>> If the memory address in error belongs to guest then
>> the guest kernel is responsible for taking suitable action.
>> Patch [1] enhances KVM to exit guest with exit reason
>> set to KVM_EXIT_NMI in such cases. This patch handles
>> KVM_EXIT_NMI exit.
>>
>> [1] https://www.spinics.net/lists/kvm-ppc/msg12637.html
>> (e20bbd3d and related commits)
>>
>> Signed-off-by: Aravinda Prasad 
>> ---
>>  hw/ppc/spapr.c  |1 +
>>  hw/ppc/spapr_events.c   |   23 +++
>>  hw/ppc/spapr_rtas.c |5 +
>>  include/hw/ppc/spapr.h  |6 ++
>>  target/ppc/kvm.c|   16 
>>  target/ppc/kvm_ppc.h|2 ++
>>  target/ppc/trace-events |1 +
>>  7 files changed, 54 insertions(+)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index fae28a9..6b6c962 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1809,6 +1809,7 @@ static void spapr_machine_reset(void)
>>  
>>  spapr->cas_reboot = false;
>>  
>> +spapr->mc_status = -1;
>>  spapr->guest_machine_check_addr = -1;
>>  
>>  /* Signal all vCPUs waiting on this condition */
>> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
>> index ae0f093..a18446b 100644
>> --- a/hw/ppc/spapr_events.c
>> +++ b/hw/ppc/spapr_events.c
>> @@ -620,6 +620,29 @@ void 
>> spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
>>  RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, 
>> _id);
>>  }
>>  
>> +void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
>> +{
>> +SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> 
> You ignore the 'recovered' parameter, is that right?

I use the "recovered" parameter, but in the next patch. This was left
out when the patch was split in one of the earlier versions. Will modify it.

> 
>> +while (spapr->mc_status != -1) {
>> +/*
>> + * Check whether the same CPU got machine check error
>> + * while still handling the mc error (i.e., before
>> + * that CPU called "ibm,nmi-interlock")
>> + */
>> +if (spapr->mc_status == cpu->vcpu_id) {
>> +qemu_system_guest_panicked(NULL);
>> +return;
>> +}
>> +qemu_cond_wait_iothread(>mc_delivery_cond);
>> +/* Meanwhile if the system is reset, then just return */
>> +if (spapr->guest_machine_check_addr == -1) {
>> +return;
>> +}
>> +}
>> +spapr->mc_status = cpu->vcpu_id;
>> +}
>> +
>>  static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
>>  uint32_t token, uint32_t nargs,
>>  target_ulong args,
>> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
>> index e7509cf..e0bdfc8 100644
>> --- a/hw/ppc/spapr_rtas.c
>> +++ b/hw/ppc/spapr_rtas.c
>> @@ -379,6 +379,11 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>>  /* NMI register not called */
>>  rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
>>  } else {
>> +/*
>> + * vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
>> + * hence unset mc_status.
>> + */
>> +spapr->mc_status = -1;
>>  qemu_cond_signal(>mc_delivery_cond);
>>  rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>>  }
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index 9dc5e30..fc3a776 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -190,6 +190,11 @@ struct SpaprMachineState {
>>  
>>  /* State related to "ibm,nmi-register" and "ibm,nmi-interlock" calls */
>>  target_ulong guest_machine_check_addr;
>> +/*
>> + * mc_status is set to -1 if mc is not in progress, else is set to the 
>> CPU
>> + * handling the mc.
>> + */
>> +int mc_status;
>>  QemuCond mc_delivery_cond;
>>  
>>  /*< public >*/
>> @@ -793,6 +798,7 @@ void spapr_clear_pending_events(SpaprMachineState 
>> *spapr);
>>  int spapr_max_server_number(SpaprMachineState *spapr);
>>  void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
>>uint64_t pte0, uint64_t pte1);
>> +void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered);
>>  
>>  /* DRC callbacks. */
>>  void spapr_core_release(DeviceState *dev);
>> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
>> index 3bf0a46..39f1a73 100644
>> --- a/target/ppc/kvm.c
>> +++ b/target/ppc/kvm.c
>> @@ -1761,6 +1761,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
>> *run)
>>  ret = 0;
>>  break;
>>  
>> +case KVM_EXIT_NMI:
>> +trace_kvm_handle_nmi_exception();
>> +ret = kvm_handle_nmi(cpu, run);
>> +break;
>> +
>>  default:
>>  fprintf(stderr, "KVM: unknown exit reason 

Re: [Qemu-devel] [Qemu-ppc] [PATCH v9 1/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-06-05 Thread Aravinda Prasad



On Thursday 06 June 2019 07:05 AM, David Gibson wrote:
> On Mon, Jun 03, 2019 at 01:17:23PM +0200, Greg Kurz wrote:
>> On Mon, 3 Jun 2019 12:12:43 +0200
>> Greg Kurz  wrote:
>>
>>> On Wed, 29 May 2019 11:10:14 +0530
>>> Aravinda Prasad  wrote:
>>>
 This patch adds support in QEMU to handle "ibm,nmi-register"
 and "ibm,nmi-interlock" RTAS calls.

 The machine check notification address is saved when the
 OS issues "ibm,nmi-register" RTAS call.

 This patch also handles the case when multiple processors
 experience machine check at or about the same time by
 handling "ibm,nmi-interlock" call. In such cases, as per
 PAPR, subsequent processors serialize waiting for the first
 processor to issue the "ibm,nmi-interlock" call. The second
 processor that also received a machine check error waits
 till the first processor is done reading the error log.
 The first processor issues "ibm,nmi-interlock" call
 when the error log is consumed. This patch implements the
 releasing part of the error-log while subsequent patch
 (which builds error log) handles the locking part.

 Signed-off-by: Aravinda Prasad 
 Reviewed-by: David Gibson 
 ---  
>>>
>>> The code looks okay but it still seems wrong to advertise the RTAS
>>> calls to the guest that early in the series. The linux kernel in
>>> the guest will assume FWNMI is functional, which isn't true until
>>> patch 6 (yes, migration is part of the feature, it should be
>>> supported upfront, not fixed afterwards).
>>>
>>> It doesn't help much to introduce the RTAS calls early and to
>>> modify them in the other patches. I'd rather see the rest of
>>> the code first and a final patch that introduces the fully
>>> functional RTAS calls and calls spapr_rtas_register().
>>>
>>
>> Thinking again, you should introduce the "fwnmi-mce" spapr capability in
>> its own patch first, default to "off" and and have the last patch in the
>> series to switch the default to "on" for newer machine types only.
>>
>> This patch should then only register the RTAS calls if "fwnmi-mcr" is set
>> to "on".
> 
> Yes, I think this is a good approach.

ok

> 
>> This should address the fact that we don't want to expose a partially
>> implemented FWNMI feature to the guest, and we don't want to support
>> FWNMI at all with older machine types for the sake of compatibility.
>>
  hw/ppc/spapr.c |7 +
  hw/ppc/spapr_rtas.c|   65 
 
  include/hw/ppc/spapr.h |9 ++-
  3 files changed, 80 insertions(+), 1 deletion(-)

 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index e2b33e5..fae28a9 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -1808,6 +1808,11 @@ static void spapr_machine_reset(void)
  first_ppc_cpu->env.gpr[5] = 0;
  
  spapr->cas_reboot = false;
 +
 +spapr->guest_machine_check_addr = -1;
 +
 +/* Signal all vCPUs waiting on this condition */
 +qemu_cond_broadcast(>mc_delivery_cond);
  }
  
  static void spapr_create_nvram(SpaprMachineState *spapr)
 @@ -3072,6 +3077,8 @@ static void spapr_machine_init(MachineState *machine)
  
  kvmppc_spapr_enable_inkernel_multitce();
  }
 +
 +qemu_cond_init(>mc_delivery_cond);
  }
  
  static int spapr_kvm_type(MachineState *machine, const char *vm_type)
 diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
 index 5bc1a93..e7509cf 100644
 --- a/hw/ppc/spapr_rtas.c
 +++ b/hw/ppc/spapr_rtas.c
 @@ -352,6 +352,38 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
 SpaprMachineState *spapr,
  rtas_st(rets, 1, 100);
  }
  
 +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
 +  SpaprMachineState *spapr,
 +  uint32_t token, uint32_t nargs,
 +  target_ulong args,
 +  uint32_t nret, target_ulong rets)
 +{
 +hwaddr rtas_addr = spapr_get_rtas_addr();
 +
 +if (!rtas_addr) {
 +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
 +return;
 +}
 +
 +spapr->guest_machine_check_addr = rtas_ld(args, 1);
 +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 +}
 +
 +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
 +   SpaprMachineState *spapr,
 +   uint32_t token, uint32_t nargs,
 +   target_ulong args,
 +   uint32_t nret, target_ulong rets)
 +{
 +if (spapr->guest_machine_check_addr == -1) {
 +/* NMI register not called */
 +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 +} else {
 +qemu_cond_signal(>mc_delivery_cond);

Re: [Qemu-devel] spapr_pci: Advertise BAR reallocation capability

2019-06-05 Thread David Gibson
On Thu, Jun 06, 2019 at 02:13:20PM +1000, Alexey Kardashevskiy wrote:
> I changed my handy scripts for posting patches and the subject line
> broke, do I need to repost? It made it to the patchworks though.

No, that's fine I've seen it and will look at it when I have the chance.

> 
> 
> 
> On 06/06/2019 14:09, Alexey Kardashevskiy wrote:
> > The pseries guests do not normally allocate PCI resouces and rely on
> > the system firmware doing so. Furthermore at least at some point in
> > the past the pseries guests won't even be allowed to change BARs, probably
> > it is still the case for phyp. So since the initial commit we have [1]
> > which prevents resource reallocation.
> > 
> > This is not a problem until we want specific BAR alignments, for example,
> > PAGE_SIZE==64k to make sure we can still map MMIO BARs directly. For
> > the boot time devices we handle this in SLOF [2] but since QEMU's RTAS
> > does not allocate BARs, the guest does this instead and does not align
> > BARs even if Linux is given pci=resource_alignment=16@pci:0:0 as
> > PCI_PROBE_ONLY makes Linux ignore alignment requests.
> > 
> > ARM folks added a dial to control PCI_PROBE_ONLY via the device tree [3].
> > This makes use of the dial to advertise to the guest that we can handle
> > BAR reassignments.
> > 
> > We do not remove the flag from [1] as pseries guests are still supported
> > under phyp so having that removed may cause problems.
> > 
> > [1] 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/platforms/pseries/setup.c?h=v5.1#n773
> > [2] 
> > https://git.qemu.org/?p=SLOF.git;a=blob;f=board-qemu/slof/pci-phb.fs;h=06729bcf77a0d4e900c527adcd9befe2a269f65d;hb=HEAD#l338
> > [3] 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f81c11af
> > Signed-off-by: Alexey Kardashevskiy 
> > ---
> >  hw/ppc/spapr.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 6dd8aaac3340..84d16f9edaca 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -1209,6 +1209,9 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, 
> > void *fdt)
> >  _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path));
> >  }
> >  
> > +/* We can deal with BAR reallocation just fine, advertise it to the 
> > guest */
> > +_FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
> > +
> >  spapr_dt_ov5_platform_support(spapr, fdt, chosen);
> >  
> >  g_free(stdout_path);
> > 
> 

-- 
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] spapr_pci: Advertise BAR reallocation capability

2019-06-05 Thread Alexey Kardashevskiy
I changed my handy scripts for posting patches and the subject line
broke, do I need to repost? It made it to the patchworks though.



On 06/06/2019 14:09, Alexey Kardashevskiy wrote:
> The pseries guests do not normally allocate PCI resouces and rely on
> the system firmware doing so. Furthermore at least at some point in
> the past the pseries guests won't even be allowed to change BARs, probably
> it is still the case for phyp. So since the initial commit we have [1]
> which prevents resource reallocation.
> 
> This is not a problem until we want specific BAR alignments, for example,
> PAGE_SIZE==64k to make sure we can still map MMIO BARs directly. For
> the boot time devices we handle this in SLOF [2] but since QEMU's RTAS
> does not allocate BARs, the guest does this instead and does not align
> BARs even if Linux is given pci=resource_alignment=16@pci:0:0 as
> PCI_PROBE_ONLY makes Linux ignore alignment requests.
> 
> ARM folks added a dial to control PCI_PROBE_ONLY via the device tree [3].
> This makes use of the dial to advertise to the guest that we can handle
> BAR reassignments.
> 
> We do not remove the flag from [1] as pseries guests are still supported
> under phyp so having that removed may cause problems.
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/platforms/pseries/setup.c?h=v5.1#n773
> [2] 
> https://git.qemu.org/?p=SLOF.git;a=blob;f=board-qemu/slof/pci-phb.fs;h=06729bcf77a0d4e900c527adcd9befe2a269f65d;hb=HEAD#l338
> [3] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f81c11af
> Signed-off-by: Alexey Kardashevskiy 
> ---
>  hw/ppc/spapr.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 6dd8aaac3340..84d16f9edaca 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1209,6 +1209,9 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, 
> void *fdt)
>  _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path));
>  }
>  
> +/* We can deal with BAR reallocation just fine, advertise it to the 
> guest */
> +_FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
> +
>  spapr_dt_ov5_platform_support(spapr, fdt, chosen);
>  
>  g_free(stdout_path);
> 

-- 
Alexey



[Qemu-devel] spapr_pci: Advertise BAR reallocation capability

2019-06-05 Thread Alexey Kardashevskiy
The pseries guests do not normally allocate PCI resouces and rely on
the system firmware doing so. Furthermore at least at some point in
the past the pseries guests won't even be allowed to change BARs, probably
it is still the case for phyp. So since the initial commit we have [1]
which prevents resource reallocation.

This is not a problem until we want specific BAR alignments, for example,
PAGE_SIZE==64k to make sure we can still map MMIO BARs directly. For
the boot time devices we handle this in SLOF [2] but since QEMU's RTAS
does not allocate BARs, the guest does this instead and does not align
BARs even if Linux is given pci=resource_alignment=16@pci:0:0 as
PCI_PROBE_ONLY makes Linux ignore alignment requests.

ARM folks added a dial to control PCI_PROBE_ONLY via the device tree [3].
This makes use of the dial to advertise to the guest that we can handle
BAR reassignments.

We do not remove the flag from [1] as pseries guests are still supported
under phyp so having that removed may cause problems.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/platforms/pseries/setup.c?h=v5.1#n773
[2] 
https://git.qemu.org/?p=SLOF.git;a=blob;f=board-qemu/slof/pci-phb.fs;h=06729bcf77a0d4e900c527adcd9befe2a269f65d;hb=HEAD#l338
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f81c11af
Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6dd8aaac3340..84d16f9edaca 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1209,6 +1209,9 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, 
void *fdt)
 _FDT(fdt_setprop_string(fdt, chosen, "stdout-path", stdout_path));
 }
 
+/* We can deal with BAR reallocation just fine, advertise it to the guest 
*/
+_FDT(fdt_setprop_cell(fdt, chosen, "linux,pci-probe-only", 0));
+
 spapr_dt_ov5_platform_support(spapr, fdt, chosen);
 
 g_free(stdout_path);
-- 
2.17.1




Re: [Qemu-devel] [PATCH v2 1/5] target/i386: Add cpu die-level topology support for X86CPU

2019-06-05 Thread Eduardo Habkost
On Tue, May 21, 2019 at 12:50:52AM +0800, Like Xu wrote:
> The die-level as the first PC-specific cpu topology is added to the
> leagcy cpu topology model which only covers sockets/cores/threads.
> 
> In the new model with die-level support, the total number of logical
> processors (including offline) on board will be calculated as:
> 
>  #cpus = #sockets * #dies * #cores * #threads
> 
> and considering compatibility, the default value for #dies is 1.
> 
> A new set of die-related variables are added in smp context and the
> CPUX86State.nr_dies is assigned in x86_cpu_initfn() from PCMachineState.
> 
> Signed-off-by: Like Xu 
> ---
>  hw/i386/pc.c   | 3 +++
>  include/hw/i386/pc.h   | 2 ++
>  include/hw/i386/topology.h | 2 ++
>  qapi/misc.json | 6 --
>  target/i386/cpu.c  | 9 +
>  target/i386/cpu.h  | 3 +++
>  6 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 896c22e32e..83ab53c814 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -2341,6 +2341,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
>  
>  topo.pkg_id = cpu->socket_id;
>  topo.core_id = cpu->core_id;
> +topo.die_id = cpu->die_id;
>  topo.smt_id = cpu->thread_id;
>  cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, );
>  }
> @@ -2692,6 +2693,8 @@ static const CPUArchIdList 
> *pc_possible_cpu_arch_ids(MachineState *ms)
>   ms->smp.cores, ms->smp.threads, );
>  ms->possible_cpus->cpus[i].props.has_socket_id = true;
>  ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id;
> +ms->possible_cpus->cpus[i].props.has_die_id = true;
> +ms->possible_cpus->cpus[i].props.die_id = topo.die_id;
>  ms->possible_cpus->cpus[i].props.has_core_id = true;
>  ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
>  ms->possible_cpus->cpus[i].props.has_thread_id = true;
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index ce3c22951e..b5faf2ede9 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -24,6 +24,7 @@
>   * PCMachineState:
>   * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
>   * @boot_cpus: number of present VCPUs
> + * @smp_dies: number of dies per one package
>   */
>  struct PCMachineState {
>  /*< private >*/
> @@ -59,6 +60,7 @@ struct PCMachineState {
>  bool apic_xrupt_override;
>  unsigned apic_id_limit;
>  uint16_t boot_cpus;
> +unsigned smp_dies;
>  
>  /* NUMA information: */
>  uint64_t numa_nodes;
> diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
> index 1ebaee0f76..7f80498eb3 100644
> --- a/include/hw/i386/topology.h
> +++ b/include/hw/i386/topology.h
> @@ -47,6 +47,7 @@ typedef uint32_t apic_id_t;
>  
>  typedef struct X86CPUTopoInfo {
>  unsigned pkg_id;
> +unsigned die_id;

Isn't it better to add this field only on patch 4/5?

>  unsigned core_id;
>  unsigned smt_id;
>  } X86CPUTopoInfo;
> @@ -130,6 +131,7 @@ static inline void x86_topo_ids_from_apicid(apic_id_t 
> apicid,
>  topo->core_id = (apicid >> apicid_core_offset(nr_cores, nr_threads)) &
> ~(0xUL << apicid_core_width(nr_cores, 
> nr_threads));
>  topo->pkg_id = apicid >> apicid_pkg_offset(nr_cores, nr_threads);
> +topo->die_id = -1;

Why are you setting die_id = -1 here?

If die_id isn't valid yet, isn't it better to keep has_die_id =
false at pc_possible_cpu_arch_ids() above, and set has_die_id =
true only on patch 4/5?

>  }
>  
>  /* Make APIC ID for the CPU 'cpu_index'
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 8b3ca4fdd3..cd236c89b3 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -2924,10 +2924,11 @@
>  #
>  # @node-id: NUMA node ID the CPU belongs to
>  # @socket-id: socket number within node/board the CPU belongs to
> -# @core-id: core number within socket the CPU belongs to
> +# @die-id: die number within node/board the CPU belongs to (Since 4.1)
> +# @core-id: core number within die the CPU belongs to
>  # @thread-id: thread number within core the CPU belongs to
>  #
> -# Note: currently there are 4 properties that could be present
> +# Note: currently there are 5 properties that could be present
>  # but management should be prepared to pass through other
>  # properties with device_add command to allow for future
>  # interface extension. This also requires the filed names to be kept in
> @@ -2938,6 +2939,7 @@
>  { 'struct': 'CpuInstanceProperties',
>'data': { '*node-id': 'int',
>  '*socket-id': 'int',
> +'*die-id': 'int',
>  '*core-id': 'int',
>  '*thread-id': 'int'
>}
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 9a93dd8be7..9bd35b4965 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -55,6 +55,7 @@
>  #include "hw/xen/xen.h"
>  

Re: [Qemu-devel] [PATCH v2 1/5] target/i386: Add cpu die-level topology support for X86CPU

2019-06-05 Thread Eduardo Habkost
On Tue, May 21, 2019 at 12:50:52AM +0800, Like Xu wrote:
> The die-level as the first PC-specific cpu topology is added to the
> leagcy cpu topology model which only covers sockets/cores/threads.
> 
> In the new model with die-level support, the total number of logical
> processors (including offline) on board will be calculated as:
> 
>  #cpus = #sockets * #dies * #cores * #threads
> 
> and considering compatibility, the default value for #dies is 1.
> 
> A new set of die-related variables are added in smp context and the
> CPUX86State.nr_dies is assigned in x86_cpu_initfn() from PCMachineState.
> 
> Signed-off-by: Like Xu 
> ---
>  hw/i386/pc.c   | 3 +++
>  include/hw/i386/pc.h   | 2 ++
>  include/hw/i386/topology.h | 2 ++
>  qapi/misc.json | 6 --
>  target/i386/cpu.c  | 9 +
>  target/i386/cpu.h  | 3 +++
>  6 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 896c22e32e..83ab53c814 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -2341,6 +2341,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
>  
>  topo.pkg_id = cpu->socket_id;
>  topo.core_id = cpu->core_id;
> +topo.die_id = cpu->die_id;
>  topo.smt_id = cpu->thread_id;
>  cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, );
>  }
> @@ -2692,6 +2693,8 @@ static const CPUArchIdList 
> *pc_possible_cpu_arch_ids(MachineState *ms)
>   ms->smp.cores, ms->smp.threads, );
>  ms->possible_cpus->cpus[i].props.has_socket_id = true;
>  ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id;
> +ms->possible_cpus->cpus[i].props.has_die_id = true;
> +ms->possible_cpus->cpus[i].props.die_id = topo.die_id;
>  ms->possible_cpus->cpus[i].props.has_core_id = true;
>  ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
>  ms->possible_cpus->cpus[i].props.has_thread_id = true;
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index ce3c22951e..b5faf2ede9 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -24,6 +24,7 @@
>   * PCMachineState:
>   * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
>   * @boot_cpus: number of present VCPUs
> + * @smp_dies: number of dies per one package
>   */
>  struct PCMachineState {
>  /*< private >*/
> @@ -59,6 +60,7 @@ struct PCMachineState {
>  bool apic_xrupt_override;
>  unsigned apic_id_limit;
>  uint16_t boot_cpus;
> +unsigned smp_dies;
>  
>  /* NUMA information: */
>  uint64_t numa_nodes;
> diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
> index 1ebaee0f76..7f80498eb3 100644
> --- a/include/hw/i386/topology.h
> +++ b/include/hw/i386/topology.h
> @@ -47,6 +47,7 @@ typedef uint32_t apic_id_t;
>  
>  typedef struct X86CPUTopoInfo {
>  unsigned pkg_id;
> +unsigned die_id;
>  unsigned core_id;
>  unsigned smt_id;
>  } X86CPUTopoInfo;
> @@ -130,6 +131,7 @@ static inline void x86_topo_ids_from_apicid(apic_id_t 
> apicid,
>  topo->core_id = (apicid >> apicid_core_offset(nr_cores, nr_threads)) &
> ~(0xUL << apicid_core_width(nr_cores, 
> nr_threads));
>  topo->pkg_id = apicid >> apicid_pkg_offset(nr_cores, nr_threads);
> +topo->die_id = -1;
>  }
>  
>  /* Make APIC ID for the CPU 'cpu_index'
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 8b3ca4fdd3..cd236c89b3 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -2924,10 +2924,11 @@
>  #
>  # @node-id: NUMA node ID the CPU belongs to
>  # @socket-id: socket number within node/board the CPU belongs to
> -# @core-id: core number within socket the CPU belongs to
> +# @die-id: die number within node/board the CPU belongs to (Since 4.1)
> +# @core-id: core number within die the CPU belongs to
>  # @thread-id: thread number within core the CPU belongs to
>  #
> -# Note: currently there are 4 properties that could be present
> +# Note: currently there are 5 properties that could be present
>  # but management should be prepared to pass through other
>  # properties with device_add command to allow for future
>  # interface extension. This also requires the filed names to be kept in
> @@ -2938,6 +2939,7 @@
>  { 'struct': 'CpuInstanceProperties',
>'data': { '*node-id': 'int',
>  '*socket-id': 'int',
> +'*die-id': 'int',
>  '*core-id': 'int',
>  '*thread-id': 'int'
>}
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 9a93dd8be7..9bd35b4965 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -55,6 +55,7 @@
>  #include "hw/xen/xen.h"
>  #include "hw/i386/apic_internal.h"
>  #include "hw/boards.h"
> +#include "hw/i386/pc.h"

Now we have a circular dependency between target/i386/cpu.c and
hw/i386/pc.c.

>  #endif
>  
>  #include "disas/capstone.h"
> @@ -5595,7 +5596,13 @@ static void 

Re: [Qemu-devel] [PATCH v2 5/5] block/nvme: add support for discard

2019-06-05 Thread Fam Zheng
On Wed, 04/17 22:53, Maxim Levitsky wrote:
> Signed-off-by: Maxim Levitsky 
> ---
>  block/nvme.c   | 80 ++
>  block/trace-events |  2 ++
>  2 files changed, 82 insertions(+)
> 
> diff --git a/block/nvme.c b/block/nvme.c
> index 35b925899f..b83912c627 100644
> --- a/block/nvme.c
> +++ b/block/nvme.c
> @@ -110,6 +110,7 @@ typedef struct {
>  bool plugged;
>  
>  bool supports_write_zeros;
> +bool supports_discard;
>  
>  CoMutex dma_map_lock;
>  CoQueue dma_flush_queue;
> @@ -462,6 +463,7 @@ static void nvme_identify(BlockDriverState *bs, int 
> namespace, Error **errp)
>  
>  
>  s->supports_write_zeros = (idctrl->oncs & NVME_ONCS_WRITE_ZEROS) != 0;
> +s->supports_discard = (idctrl->oncs & NVME_ONCS_DSM) != 0;
>  
>  memset(resp, 0, 4096);
>  
> @@ -1144,6 +1146,83 @@ static coroutine_fn int 
> nvme_co_pwrite_zeroes(BlockDriverState *bs,
>  }
>  
>  
> +static int coroutine_fn nvme_co_pdiscard(BlockDriverState *bs,
> +int64_t offset, int bytes)

While you respin, you can align the parameters.

> +{
> +BDRVNVMeState *s = bs->opaque;
> +NVMeQueuePair *ioq = s->queues[1];
> +NVMeRequest *req;
> +NvmeDsmRange *buf;
> +QEMUIOVector local_qiov;
> +int r;
> +
> +NvmeCmd cmd = {
> +.opcode = NVME_CMD_DSM,
> +.nsid = cpu_to_le32(s->nsid),
> +.cdw10 = 0, /*number of ranges - 0 based*/
> +.cdw11 = cpu_to_le32(1 << 2), /*deallocate bit*/
> +};
> +
> +NVMeCoData data = {
> +.ctx = bdrv_get_aio_context(bs),
> +.ret = -EINPROGRESS,
> +};
> +
> +if (!s->supports_discard) {
> +return -ENOTSUP;
> +}
> +
> +assert(s->nr_queues > 1);
> +
> +buf = qemu_try_blockalign0(bs, 4096);
> +if (!buf) {
> +return -ENOMEM;
> +}
> +
> +buf->nlb = bytes >> s->blkshift;
> +buf->slba = offset >> s->blkshift;

This buffer is for the device, do we need to do anything about the endianness?

> +buf->cattr = 0;
> +
> +qemu_iovec_init(_qiov, 1);
> +qemu_iovec_add(_qiov, buf, 4096);
> +
> +req = nvme_get_free_req(ioq);
> +assert(req);
> +
> +qemu_co_mutex_lock(>dma_map_lock);
> +r = nvme_cmd_map_qiov(bs, , req, _qiov);
> +qemu_co_mutex_unlock(>dma_map_lock);
> +
> +if (r) {
> +req->busy = false;
> +return r;
> +}
> +
> +trace_nvme_dsm(s, offset, bytes);
> +
> +nvme_submit_command(s, ioq, req, , nvme_rw_cb, );
> +
> +data.co = qemu_coroutine_self();
> +while (data.ret == -EINPROGRESS) {
> +qemu_coroutine_yield();
> +}
> +
> +qemu_co_mutex_lock(>dma_map_lock);
> +r = nvme_cmd_unmap_qiov(bs, _qiov);
> +qemu_co_mutex_unlock(>dma_map_lock);
> +if (r) {
> +return r;
> +}
> +
> +trace_nvme_dsm_done(s, offset, bytes, data.ret);
> +
> +qemu_iovec_destroy(_qiov);
> +qemu_vfree(buf);
> +return data.ret;
> +
> +}
> +
> +
>  static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
> BlockReopenQueue *queue, Error **errp)
>  {
> @@ -1250,6 +1329,7 @@ static BlockDriver bdrv_nvme = {
>  .bdrv_co_pwritev  = nvme_co_pwritev,
>  
>  .bdrv_co_pwrite_zeroes= nvme_co_pwrite_zeroes,
> +.bdrv_co_pdiscard = nvme_co_pdiscard,
>  
>  .bdrv_co_flush_to_disk= nvme_co_flush,
>  .bdrv_reopen_prepare  = nvme_reopen_prepare,
> diff --git a/block/trace-events b/block/trace-events
> index 943a58569f..e55ac5c40b 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -148,6 +148,8 @@ nvme_write_zeros(void *s, uint64_t offset, uint64_t 
> bytes, int flags) "s %p offs
>  nvme_qiov_unaligned(const void *qiov, int n, void *base, size_t size, int 
> align) "qiov %p n %d base %p size 0x%zx align 0x%x"
>  nvme_prw_buffered(void *s, uint64_t offset, uint64_t bytes, int niov, int 
> is_write) "s %p offset %"PRId64" bytes %"PRId64" niov %d is_write %d"
>  nvme_rw_done(void *s, int is_write, uint64_t offset, uint64_t bytes, int 
> ret) "s %p is_write %d offset %"PRId64" bytes %"PRId64" ret %d"
> +nvme_dsm(void *s, uint64_t offset, uint64_t bytes) "s %p offset %"PRId64" 
> bytes %"PRId64""
> +nvme_dsm_done(void *s, uint64_t offset, uint64_t bytes, int ret) "s %p 
> offset %"PRId64" bytes %"PRId64" ret %d"
>  nvme_dma_map_flush(void *s) "s %p"
>  nvme_free_req_queue_wait(void *q) "q %p"
>  nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s 
> %p cmd %p req %p qiov %p entries %d"
> -- 
> 2.17.2
> 




Re: [Qemu-devel] [PATCH v2 3/5] vl.c: Add -smp, dies=* command line support and update -smp doc

2019-06-05 Thread Eduardo Habkost
On Tue, May 21, 2019 at 12:50:54AM +0800, Like Xu wrote:
> For PC target, users could configure the number of dies per one package
> via command line with this patch, such as "-smp dies=2,cores=4".
> 
> A new pc-specified pc_smp_parse() is introduced and to keep the interface
> consistent, refactoring legacy smp_parse() to __smp_parse() is necessary.
> 
> The parsing rules of new cpu-topology model obey the same restrictions/logic
> as the legacy socket/core/thread model especially on missing values computing.
> 
> Signed-off-by: Like Xu 
> ---
>  qemu-options.hx | 17 +-
>  vl.c| 89 -
>  2 files changed, 97 insertions(+), 9 deletions(-)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 5daa5a8fb0..7fad5b50ff 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -138,25 +138,26 @@ no incompatible TCG features have been enabled (e.g. 
> icount/replay).
>  ETEXI
>  
>  DEF("smp", HAS_ARG, QEMU_OPTION_smp,
> -"-smp 
> [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]\n"
> +"-smp 
> [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,dies=dies][,sockets=sockets]\n"
>  "set the number of CPUs to 'n' [default=1]\n"
>  "maxcpus= maximum number of total cpus, including\n"
>  "offline CPUs for hotplug, etc\n"
> -"cores= number of CPU cores on one socket\n"
> +"cores= number of CPU cores on one socket (for PC, it's 
> on one die)\n"
>  "threads= number of threads on one CPU core\n"
> +"dies= number of CPU dies on one socket (for PC only)\n"
>  "sockets= number of discrete sockets in the system\n",
>  QEMU_ARCH_ALL)
>  STEXI
> -@item -smp 
> [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
> +@item -smp 
> [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,dies=dies][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
>  @findex -smp
>  Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
>  CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs
>  to 4.
> -For the PC target, the number of @var{cores} per socket, the number
> -of @var{threads} per cores and the total number of @var{sockets} can be
> -specified. Missing values will be computed. If any on the three values is
> -given, the total number of CPUs @var{n} can be omitted. @var{maxcpus}
> -specifies the maximum number of hotpluggable CPUs.
> +For the PC target, the number of @var{cores} per die, the number of 
> @var{threads}
> +per cores, the number of @var{dies} per packages and the total number of
> +@var{sockets} can be specified. Missing values will be computed.
> +If any on the three values is given, the total number of CPUs @var{n} can be 
> omitted.
> +@var{maxcpus} specifies the maximum number of hotpluggable CPUs.
>  ETEXI
>  
>  DEF("numa", HAS_ARG, QEMU_OPTION_numa,
> diff --git a/vl.c b/vl.c
> index 8d92e2d209..66b577f447 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -63,6 +63,7 @@ int main(int argc, char **argv)
>  #include "sysemu/watchdog.h"
>  #include "hw/firmware/smbios.h"
>  #include "hw/acpi/acpi.h"
> +#include "hw/i386/pc.h"
>  #include "hw/xen/xen.h"
>  #include "hw/qdev.h"
>  #include "hw/loader.h"
> @@ -1248,6 +1249,9 @@ static QemuOptsList qemu_smp_opts = {
>  }, {
>  .name = "sockets",
>  .type = QEMU_OPT_NUMBER,
> +}, {
> +.name = "dies",
> +.type = QEMU_OPT_NUMBER,
>  }, {
>  .name = "cores",
>  .type = QEMU_OPT_NUMBER,
> @@ -1262,7 +1266,7 @@ static QemuOptsList qemu_smp_opts = {
>  },
>  };
>  
> -static void smp_parse(QemuOpts *opts)
> +static void __smp_parse(QemuOpts *opts)
>  {
>  if (opts) {
>  unsigned cpus= qemu_opt_get_number(opts, "cpus", 0);
> @@ -1334,6 +1338,89 @@ static void smp_parse(QemuOpts *opts)
>  }
>  }
>  
> +static void pc_smp_parse(QemuOpts *opts)
> +{
> +PCMachineState *pcms = (PCMachineState *)
> +object_dynamic_cast(OBJECT(current_machine), TYPE_PC_MACHINE);
> +
> +unsigned cpus= qemu_opt_get_number(opts, "cpus", 0);
> +unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
> +unsigned dies = qemu_opt_get_number(opts, "dies", 1);
> +unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
> +unsigned threads = qemu_opt_get_number(opts, "threads", 0);
> +
> +/* compute missing values, prefer sockets over cores over threads */
> +if (cpus == 0 || sockets == 0) {
> +cores = cores > 0 ? cores : 1;
> +threads = threads > 0 ? threads : 1;
> +if (cpus == 0) {
> +sockets = sockets > 0 ? sockets : 1;
> +cpus = cores * threads * dies * sockets;
> +} else {
> +current_machine->smp.max_cpus =
> +  

Re: [Qemu-devel] [PATCH v3 04/10] hw/ppc: Replace global smp variables with machine smp properties

2019-06-05 Thread David Gibson
On Wed, Jun 05, 2019 at 11:54:56PM -0300, Eduardo Habkost wrote:
> On Wed, Jun 05, 2019 at 11:52:41PM -0300, Eduardo Habkost wrote:
> > On Sun, May 19, 2019 at 04:54:22AM +0800, Like Xu wrote:
> > > The global smp variables in ppc are replaced with smp machine properties.
> > > 
> > > A local variable of the same name would be introduced in the declaration
> > > phase if it's used widely in the context OR replace it on the spot if it's
> > > only used once. No semantic changes.
> > > 
> > > Signed-off-by: Like Xu 
> > 
> > Any objections from the ppc maintainers to queueing this through
> > the Machine Core tree?
> 
> Oops, CCing the ppc maintainers.

No objection here.

Acked-by: David Gibson 

> 
> > 
> > > ---
> > >  hw/ppc/e500.c |  3 +++
> > >  hw/ppc/mac_newworld.c |  3 ++-
> > >  hw/ppc/mac_oldworld.c |  3 ++-
> > >  hw/ppc/pnv.c  |  6 --
> > >  hw/ppc/prep.c |  4 ++--
> > >  hw/ppc/spapr.c| 34 ++
> > >  hw/ppc/spapr_rtas.c   |  4 +++-
> > >  7 files changed, 42 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> > > index beb2efd694..5e42e5a059 100644
> > > --- a/hw/ppc/e500.c
> > > +++ b/hw/ppc/e500.c
> > > @@ -307,6 +307,7 @@ static int 
> > > ppce500_load_device_tree(PPCE500MachineState *pms,
> > >  bool dry_run)
> > >  {
> > >  MachineState *machine = MACHINE(pms);
> > > +unsigned int smp_cpus = machine->smp.cpus;
> > >  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
> > >  CPUPPCState *env = first_cpu->env_ptr;
> > >  int ret = -1;
> > > @@ -734,6 +735,7 @@ static DeviceState 
> > > *ppce500_init_mpic_qemu(PPCE500MachineState *pms,
> > >  SysBusDevice *s;
> > >  int i, j, k;
> > >  MachineState *machine = MACHINE(pms);
> > > +unsigned int smp_cpus = machine->smp.cpus;
> > >  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
> > >  
> > >  dev = qdev_create(NULL, TYPE_OPENPIC);
> > > @@ -846,6 +848,7 @@ void ppce500_init(MachineState *machine)
> > >  struct boot_info *boot_info;
> > >  int dt_size;
> > >  int i;
> > > +unsigned int smp_cpus = machine->smp.cpus;
> > >  /* irq num for pin INTA, INTB, INTC and INTD is 1, 2, 3 and
> > >   * 4 respectively */
> > >  unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
> > > diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
> > > index 02d8559621..257b26ee24 100644
> > > --- a/hw/ppc/mac_newworld.c
> > > +++ b/hw/ppc/mac_newworld.c
> > > @@ -135,6 +135,7 @@ static void ppc_core99_init(MachineState *machine)
> > >  DeviceState *dev, *pic_dev;
> > >  hwaddr nvram_addr = 0xFFF04000;
> > >  uint64_t tbfreq;
> > > +unsigned int smp_cpus = machine->smp.cpus;
> > >  
> > >  linux_boot = (kernel_filename != NULL);
> > >  
> > > @@ -464,7 +465,7 @@ static void ppc_core99_init(MachineState *machine)
> > >  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
> > >  
> > >  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> > > -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> > > +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, 
> > > (uint16_t)machine->smp.max_cpus);
> > >  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
> > >  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
> > >  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> > > diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> > > index 460cbc7923..1968f05a6c 100644
> > > --- a/hw/ppc/mac_oldworld.c
> > > +++ b/hw/ppc/mac_oldworld.c
> > > @@ -99,6 +99,7 @@ static void ppc_heathrow_init(MachineState *machine)
> > >  DeviceState *dev, *pic_dev;
> > >  BusState *adb_bus;
> > >  int bios_size;
> > > +unsigned int smp_cpus = machine->smp.cpus;
> > >  uint16_t ppc_boot_device;
> > >  DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
> > >  void *fw_cfg;
> > > @@ -322,7 +323,7 @@ static void ppc_heathrow_init(MachineState *machine)
> > >  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
> > >  
> > >  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> > > -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> > > +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, 
> > > (uint16_t)machine->smp.max_cpus);
> > >  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
> > >  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
> > >  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> > > index 1e8c505936..3bb15338de 100644
> > > --- a/hw/ppc/pnv.c
> > > +++ b/hw/ppc/pnv.c
> > > @@ -678,7 +678,8 @@ static void pnv_init(MachineState *machine)
> > >  object_property_add_child(OBJECT(pnv), chip_name, chip, 
> > > _fatal);
> > >  object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
> > >  _fatal);
> > > -

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

2019-06-05 Thread David Gibson
On Tue, Jun 04, 2019 at 11:59:13AM +0530, Aravinda Prasad wrote:
> 
> 
> On Monday 03 June 2019 07:30 PM, Greg Kurz wrote:
> > On Wed, 29 May 2019 11:10:40 +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 |5 +
> >>  hw/ppc/spapr_events.c  |  236 
> >> 
> >>  include/hw/ppc/spapr.h |4 +
> >>  3 files changed, 245 insertions(+)
> >>
> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >> index 6b6c962..c97f6a6 100644
> >> --- a/hw/ppc/spapr.c
> >> +++ b/hw/ppc/spapr.c
> >> @@ -2910,6 +2910,11 @@ 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. */
> >> +g_assert(spapr->rtas_size < RTAS_ERROR_LOG_OFFSET);
> > 
> > I don't see the point of this assertion... especially with the assignment
> > below.
> 
> It is required because we want to ensure that the rtas image size is
> less than RTAS_ERROR_LOG_OFFSET, or else we will overwrite the rtas
> image with rtas error when we hit machine check exception. But I think a
> comment in the code will help. Will add it.
> 
> 
> > 
> >> +spapr->rtas_size = RTAS_ERROR_LOG_MAX;
> > 
> > As requested by David, this should only be done when the spapr cap is set,
> > so that 4.0 machine types and older continue to use the current size.
> 
> Due to other issue of re-allocating the blob and as this is not that
> much space, we agreed to keep the size to RTAS_ERROR_LOG_MAX always.
> 
> Link to the discussion on this:
> http://lists.nongnu.org/archive/html/qemu-ppc/2019-05/msg00275.html

Sorry, I wasn't clear in that discussion.  It is definitely *not* ok
to advertise the increased size to the guest for old machine types.
It *is* ok to waste some space inside qemu internal allocations if it
reduces conditionals.


> 
> > 
> >> +
> >>  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 a18446b..573c0b7 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 {
> >> +#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;
> 

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

2019-06-05 Thread David Gibson
On Tue, Jun 04, 2019 at 11:01:19AM +0200, Greg Kurz wrote:
> On Tue, 4 Jun 2019 11:59:13 +0530
> Aravinda Prasad  wrote:
> 
> > On Monday 03 June 2019 07:30 PM, Greg Kurz wrote:
> > > On Wed, 29 May 2019 11:10:40 +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 |5 +
> > >>  hw/ppc/spapr_events.c  |  236 
> > >> 
> > >>  include/hw/ppc/spapr.h |4 +
> > >>  3 files changed, 245 insertions(+)
> > >>
> > >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > >> index 6b6c962..c97f6a6 100644
> > >> --- a/hw/ppc/spapr.c
> > >> +++ b/hw/ppc/spapr.c
> > >> @@ -2910,6 +2910,11 @@ 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. */
> > >> +g_assert(spapr->rtas_size < RTAS_ERROR_LOG_OFFSET);  
> > > 
> > > I don't see the point of this assertion... especially with the assignment
> > > below.  
> > 
> > It is required because we want to ensure that the rtas image size is
> > less than RTAS_ERROR_LOG_OFFSET, or else we will overwrite the rtas
> > image with rtas error when we hit machine check exception. But I think a
> > comment in the code will help. Will add it.
> 
> I'd rather exit QEMU properly instead of aborting then. Also this is only
> needed if the guest has a chance to use FWNMI, ie. the spapr cap is
> set.

I think assert() is appropriate in this case.  If it fails it means
something is wrong in the code, not with configuration.

> 
> > 
> > >   
> > >> +spapr->rtas_size = RTAS_ERROR_LOG_MAX;  
> > > 
> > > As requested by David, this should only be done when the spapr cap is set,
> > > so that 4.0 machine types and older continue to use the current size.  
> > 
> > Due to other issue of re-allocating the blob and as this is not that
> > much space, we agreed to keep the size to RTAS_ERROR_LOG_MAX always.
> > 
> > Link to the discussion on this:
> > http://lists.nongnu.org/archive/html/qemu-ppc/2019-05/msg00275.html
> > 
> 
> Indeed, and in the next mail in that thread, David writes:
> 
> > No, that's not right.  It's impractical to change the allocation
> > depending on whether fwnmi is currently active.  But you *can* (and
> > should) base the allocation on whether fwnmi is *possible* - that is,
> > the value of the spapr cap.
> 
> ie, allocate RTAS_ERROR_LOG_MAX when the spapr cap is set, allocate
> the file size otherwise.
> 
> > >   
> > >> +
> > >>  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 a18446b..573c0b7 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 {
> > >> +#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
> > >> 

Re: [Qemu-devel] [PATCH v9 6/6] migration: Include migration support for machine check handling

2019-06-05 Thread David Gibson
On Wed, May 29, 2019 at 11:10:57AM +0530, Aravinda Prasad wrote:
> This patch includes migration support for machine check
> handling. Especially this patch blocks VM migration
> requests until the machine check error handling is
> complete as (i) these errors are specific to the source
> hardware and is irrelevant on the target hardware,
> (ii) these errors cause data corruption and should
> be handled before migration.
> 
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c |   20 
>  hw/ppc/spapr_events.c  |   17 +
>  hw/ppc/spapr_rtas.c|4 
>  include/hw/ppc/spapr.h |2 ++
>  4 files changed, 43 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e8a77636..31c4850 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2104,6 +2104,25 @@ static const VMStateDescription vmstate_spapr_dtb = {
>  },
>  };
>  
> +static bool spapr_fwnmi_needed(void *opaque)
> +{
> +SpaprMachineState *spapr = (SpaprMachineState *)opaque;
> +
> +return (spapr->guest_machine_check_addr == -1) ? 0 : 1;

Since we're introducing a PAPR capability to enable this, it would
actually be better to check that here, rather than the runtime state.
That leads to less cases and easier to understand semantics for the
migration stream.

> +}
> +
> +static const VMStateDescription vmstate_spapr_machine_check = {
> +.name = "spapr_machine_check",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = spapr_fwnmi_needed,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT64(guest_machine_check_addr, SpaprMachineState),
> +VMSTATE_INT32(mc_status, SpaprMachineState),
> +VMSTATE_END_OF_LIST()
> +},
> +};
> +
>  static const VMStateDescription vmstate_spapr = {
>  .name = "spapr",
>  .version_id = 3,
> @@ -2137,6 +2156,7 @@ static const VMStateDescription vmstate_spapr = {
>  _spapr_dtb,
>  _spapr_cap_large_decr,
>  _spapr_cap_ccf_assist,
> +_spapr_machine_check,
>  NULL
>  }
>  };
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index 573c0b7..35e21e4 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -41,6 +41,7 @@
>  #include "qemu/bcd.h"
>  #include "hw/ppc/spapr_ovec.h"
>  #include 
> +#include "migration/blocker.h"
>  
>  #define RTAS_LOG_VERSION_MASK   0xff00
>  #define   RTAS_LOG_VERSION_60x0600
> @@ -855,6 +856,22 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, 
> bool recovered)
>  void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
>  {
>  SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> +int ret;
> +Error *local_err = NULL;
> +
> +error_setg(>fwnmi_migration_blocker,
> +"Live migration not supported during machine check handling");
> +ret = migrate_add_blocker(spapr->fwnmi_migration_blocker, _err);
> +if (ret < 0) {
> +/*
> + * We don't want to abort and let the migration to continue. In a
> + * rare case, the machine check handler will run on the target
> + * hardware. Though this is not preferable, it is better than 
> aborting
> + * the migration or killing the VM.
> + */
> +error_free(spapr->fwnmi_migration_blocker);

You should set fwnmi_migration_blocker to NULL here as well.

As mentioned on an earlier iteration, the migration blocker is the
same every time.  Couldn't you just create it once and free at final
teardown, rather than recreating it for every NMI?

> +warn_report_err(local_err);
> +}
>  
>  while (spapr->mc_status != -1) {
>  /*
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 91a7ab9..c849223 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -50,6 +50,7 @@
>  #include "target/ppc/mmu-hash64.h"
>  #include "target/ppc/mmu-book3s-v3.h"
>  #include "kvm_ppc.h"
> +#include "migration/blocker.h"
>  
>  static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr,
> uint32_t token, uint32_t nargs,
> @@ -404,6 +405,9 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>  spapr->mc_status = -1;
>  qemu_cond_signal(>mc_delivery_cond);
>  rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +migrate_del_blocker(spapr->fwnmi_migration_blocker);
> +error_free(spapr->fwnmi_migration_blocker);
> +spapr->fwnmi_migration_blocker = NULL;
>  }
>  }
>  
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index bd75d4b..6c0cfd8 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -214,6 +214,8 @@ struct SpaprMachineState {
>  SpaprCapabilities def, eff, mig;
>  
>  unsigned gpu_numa_id;
> +
> +Error *fwnmi_migration_blocker;
>  };
>  
>  #define H_SUCCESS 0
> 

-- 
David Gibson| I'll have my music baroque, and my code

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

2019-06-05 Thread David Gibson
On Tue, Jun 04, 2019 at 12:15:26PM +0530, Aravinda Prasad wrote:
> 
> 
> On Monday 03 June 2019 08:55 PM, Greg Kurz wrote:
> > On Wed, 29 May 2019 11:10:49 +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 
> >> ---
> > 
> > As suggested in another mail, it may be worth introducing the sPAPR cap
> > in its own patch, earlier in the series.
> 
> Sure, also as a workaround mentioned in the reply to that mail, I am
> thinking of returning RTAS_OUT_NOT_SUPPORTED to rtas nmi register call
> until the entire functionality is implemented. This will help solve
> spapr cap issue as well.

Not registering the RTAS call at all is the correct way to handle that
case.

> 
> > 
> > Anyway, I have some comments below.
> > 
> >>  hw/ppc/spapr.c |1 +
> >>  hw/ppc/spapr_caps.c|   24 
> >>  hw/ppc/spapr_rtas.c|   18 ++
> >>  include/hw/ppc/spapr.h |4 +++-
> >>  target/ppc/kvm.c   |   19 +++
> >>  target/ppc/kvm_ppc.h   |   12 
> >>  6 files changed, 77 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >> index c97f6a6..e8a77636 100644
> >> --- a/hw/ppc/spapr.c
> >> +++ b/hw/ppc/spapr.c
> >> @@ -4364,6 +4364,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_ON;
> >>  spapr_caps_add_properties(smc, _abort);
> >>  smc->irq = _irq_dual;
> >>  smc->dr_phb_enabled = true;
> >> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> >> index 31b4661..ef9e612 100644
> >> --- a/hw/ppc/spapr_caps.c
> >> +++ b/hw/ppc/spapr_caps.c
> >> @@ -479,6 +479,20 @@ static void cap_ccf_assist_apply(SpaprMachineState 
> >> *spapr, uint8_t val,
> >>  }
> >>  }
> >>  
> >> +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
> >> +Error **errp)
> >> +{
> >> +if (!val) {
> >> +return; /* Disabled by default */
> >> +}
> >> +
> >> +if (tcg_enabled()) {
> >> +error_setg(errp, "No fwnmi support in TCG, try 
> >> cap-fwnmi-mce=off");
> > 
> > Maybe expand "fwnmi" to "Firmware Assisted Non-Maskable Interrupts" ?
> 
> sure..
> 
> > 
> >> +} else if (kvm_enabled() && !kvmppc_has_cap_ppc_fwnmi()) {
> >> +error_setg(errp, "Requested fwnmi capability not support by 
> >> KVM");
> > 
> > Maybe reword and add a hint:
> > 
> > "KVM implementation does not support Firmware Assisted Non-Maskable 
> > Interrupts, try cap-fwnmi-mce=off"
> 
> sure..
> 
> > 
> > 
> >> +}
> >> +}
> >> +
> >>  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
> >>  [SPAPR_CAP_HTM] = {
> >>  .name = "htm",
> >> @@ -578,6 +592,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,
> >> @@ -717,6 +740,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, 
> >> SPAPR_CAP_HPT_MAXPAGESIZE);
> >>  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 e0bdfc8..91a7ab9 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 

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

2019-06-05 Thread David Gibson
On Wed, May 29, 2019 at 11:10:49AM +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|   24 
>  hw/ppc/spapr_rtas.c|   18 ++
>  include/hw/ppc/spapr.h |4 +++-
>  target/ppc/kvm.c   |   19 +++
>  target/ppc/kvm_ppc.h   |   12 
>  6 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index c97f6a6..e8a77636 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4364,6 +4364,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_ON;

You need to turn this back off by default for the older machine types.

>  spapr_caps_add_properties(smc, _abort);
>  smc->irq = _irq_dual;
>  smc->dr_phb_enabled = true;
> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> index 31b4661..ef9e612 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -479,6 +479,20 @@ static void cap_ccf_assist_apply(SpaprMachineState 
> *spapr, uint8_t val,
>  }
>  }
>  
> +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
> +Error **errp)
> +{
> +if (!val) {
> +return; /* Disabled by default */
> +}
> +
> +if (tcg_enabled()) {
> +error_setg(errp, "No fwnmi support in TCG, try 
> cap-fwnmi-mce=off");
> +} else if (kvm_enabled() && !kvmppc_has_cap_ppc_fwnmi()) {
> +error_setg(errp, "Requested fwnmi capability not support by 
> KVM");
> +}
> +}
> +
>  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>  [SPAPR_CAP_HTM] = {
>  .name = "htm",
> @@ -578,6 +592,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,
> @@ -717,6 +740,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, 
> SPAPR_CAP_HPT_MAXPAGESIZE);
>  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 e0bdfc8..91a7ab9 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,
> @@ -358,6 +359,7 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>target_ulong args,
>uint32_t nret, target_ulong rets)
>  {
> +int ret;
>  hwaddr rtas_addr = spapr_get_rtas_addr();
>  
>  if (!rtas_addr) {
> @@ -365,6 +367,22 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
>  return;
>  }
>  
> +if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == 0) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +return;
> +}
> +
> +ret = kvmppc_fwnmi_enable(cpu);
> +if (ret == 1) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +return;
> +}
> +
> +if (ret < 0) {
> +rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
> +return;
> +}
> +
>  spapr->guest_machine_check_addr = rtas_ld(args, 1);
>  rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index c717ab2..bd75d4b 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -78,8 +78,10 @@ typedef enum {
>  #define 

Re: [Qemu-devel] [PATCH v3 10/10] vl.c: Replace smp global variables with smp machine properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:28AM +0800, Like Xu wrote:
> The global smp variables in vl.c are completely replaced with machine 
> properties.
> 
> Form this commit, the smp_cpus/smp_cores/smp_threads/max_cpus are deprecated
> and only machine properties within MachineState are fully applied and enabled.
> 
> Signed-off-by: Like Xu 
> Reviewed-by: Alistair Francis 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v4 07/11] hmat acpi: Build Memory Side Cache Information Structure(s) in ACPI HMAT

2019-06-05 Thread Tao Xu

On 6/5/2019 8:12 PM, Igor Mammedov wrote:

On Wed, 5 Jun 2019 14:04:10 +0800
Tao Xu  wrote:


On 6/4/2019 11:04 PM, Igor Mammedov wrote:

On Wed,  8 May 2019 14:17:22 +0800
Tao Xu  wrote:
   

...

+
+/* SMBIOS Handles */
+/* TBD: set smbios handles */
+build_append_int_noprefix(table_data, 0, 2 * n);

Is memory side cache structure useful at all without pointing to SMBIOS entries?
   

They are not useful yet, and the kernel 5.1 HMAT sysfs doesn't show
SMBIOS entries. We can update it if it useful in the future.


In that case I'd suggest to drop it for now until this table is properly
populated and ready for consumption. (i.e. drop this patch and corresponding
CLI 9/11 patch).



But the kernel HMAT can read othe Memory Side Cache Information except 
SMBIOS entries and the host HMAT tables also haven’t SMBIOS Handles it 
also shows Number of SMBIOS handles (n) as 0. So I am wondering if it is 
better to setting "SMBIOS handles (n)" as 0, remove TODO and comment the 
reason why set it 0?




Re: [Qemu-devel] [PATCH v3 00/10] Refactor cpu topo into machine properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:18AM +0800, Like Xu wrote:
> This patch series make existing cores/threads/sockets into machine
> properties and get rid of global smp_* variables they use currently.
> 
> The purpose of getting rid of globals is disentangle layer violations and
> let's do it one step at a time by replacing the smp_foo with 
> qdev_get_machine()
> as few calls as possible and delay other related refactoring efforts.

Thanks, and sorry for taking so long to review this.  This
version looks good, I'm planning to queue it.  I will just wait
for a few days to hear from the maintainers of the machines that
are touched by the series.

> 
> ==changelog==
> 
> v3:
> 
> - rephrase commit messages
> - s/of/of present/ for CpuTopology comment
> - drop reduanct arguments such as cpu_type
> - use ms instead of macs in migration context
> - rebase to commit 1b46b4daa6
> 
> v2: https://patchwork.ozlabs.org/cover/1095727/
> 
> - pass MachineState via call chain with trivial fixups
> - replace smp_cpus directly at places if it's only used once
> - s/topo/smp/ and drop smp_ prefix inside CpuTopology structure
> - add more commit messages to explaining what patch does
> - fix Patchew build failure for xen usage
> - use macs rather than ms in migration context for MigrationState
> - cleanup unrelated and redundant changes
> - spilt OpenRISC and RISC-V related patches
> 
> v1: https://patchwork.kernel.org/cover/10876667/
> 
> Like Xu (10):
>   hw/boards: Add struct CpuTopology to MachineState
>   machine: Refactor smp-related call chains to pass MachineState
>   general: Replace global smp variables with smp machine properties
>   hw/ppc: Replace global smp variables with machine smp properties
>   hw/riscv: Replace global smp variables with machine smp properties
>   hw/s390x: Replace global smp variables with machine smp properties
>   hw/i386: Replace global smp variables with machine smp properties
>   hw/arm: Replace global smp variables with machine smp properties
>   hw: Replace global smp variables with MachineState for all remaining archs
>   vl.c: Replace smp global variables with smp machine properties
> 
>  accel/kvm/kvm-all.c  |  4 +--
>  backends/hostmem.c   |  6 +++--
>  cpus.c   |  6 +++--
>  exec.c   |  3 ++-
>  gdbstub.c|  4 +++
>  hw/alpha/dp264.c |  1 +
>  hw/arm/fsl-imx6.c|  6 -
>  hw/arm/fsl-imx6ul.c  |  6 -
>  hw/arm/fsl-imx7.c|  7 +++--
>  hw/arm/highbank.c|  1 +
>  hw/arm/mcimx6ul-evk.c|  2 +-
>  hw/arm/mcimx7d-sabre.c   |  2 +-
>  hw/arm/raspi.c   |  4 +--
>  hw/arm/realview.c|  1 +
>  hw/arm/sabrelite.c   |  2 +-
>  hw/arm/vexpress.c| 16 +++-
>  hw/arm/virt.c| 10 ++--
>  hw/arm/xlnx-zynqmp.c | 16 +++-
>  hw/cpu/core.c|  4 ++-
>  hw/hppa/machine.c|  4 ++-
>  hw/i386/acpi-build.c | 13 ++
>  hw/i386/kvmvapic.c   |  7 +++--
>  hw/i386/pc.c | 33 ++--
>  hw/i386/xen/xen-hvm.c|  4 +++
>  hw/mips/boston.c |  2 +-
>  hw/mips/mips_malta.c | 24 +
>  hw/openrisc/openrisc_sim.c   |  1 +
>  hw/ppc/e500.c|  3 +++
>  hw/ppc/mac_newworld.c|  3 ++-
>  hw/ppc/mac_oldworld.c|  3 ++-
>  hw/ppc/pnv.c |  9 ---
>  hw/ppc/prep.c|  4 +--
>  hw/ppc/spapr.c   | 37 ++
>  hw/ppc/spapr_rtas.c  |  4 ++-
>  hw/riscv/sifive_e.c  |  6 +++--
>  hw/riscv/sifive_plic.c   |  3 +++
>  hw/riscv/sifive_u.c  |  6 +++--
>  hw/riscv/spike.c |  2 ++
>  hw/riscv/virt.c  |  1 +
>  hw/s390x/s390-virtio-ccw.c   |  9 ---
>  hw/s390x/sclp.c  |  2 +-
>  hw/smbios/smbios.c   | 26 +++
>  hw/sparc/sun4m.c |  2 ++
>  hw/sparc64/sun4u.c   |  4 +--
>  hw/xtensa/sim.c  |  2 +-
>  hw/xtensa/xtfpga.c   |  1 +
>  include/hw/boards.h  | 19 --
>  include/hw/firmware/smbios.h |  5 ++--
>  include/hw/i386/pc.h |  2 +-
>  migration/postcopy-ram.c |  8 +-
>  numa.c   |  1 +
>  qmp.c|  2 +-
>  target/arm/cpu.c |  8 +-
>  target/i386/cpu.c|  4 ++-
>  target/openrisc/sys_helper.c |  6 -
>  target/s390x/cpu.c   |  3 +++
>  target/s390x/excp_helper.c   |  5 
>  tcg/tcg.c| 13 +-
>  vl.c | 50 +++-
>  59 files changed, 301 insertions(+), 141 deletions(-)
> 
> -- 
> 2.21.0
> 
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v3 08/10] hw/arm: Replace global smp variables with machine smp properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:26AM +0800, Like Xu wrote:
> The global smp variables in arm are replaced with smp machine properties.
> The init_cpus() and *_create_rpu() are refactored to pass MachineState.
> 
> A local variable of the same name would be introduced in the declaration
> phase if it's used widely in the context OR replace it on the spot if it's
> only used once. No semantic changes.
> 
> Signed-off-by: Like Xu 
> Reviewed-by: Alistair Francis 

CCing arm maintainers.  Any objection to merging this through the
Machine Core tree?

> ---
>  hw/arm/fsl-imx6.c  |  6 +-
>  hw/arm/fsl-imx6ul.c|  6 +-
>  hw/arm/fsl-imx7.c  |  7 +--
>  hw/arm/highbank.c  |  1 +
>  hw/arm/mcimx6ul-evk.c  |  2 +-
>  hw/arm/mcimx7d-sabre.c |  2 +-
>  hw/arm/raspi.c |  4 ++--
>  hw/arm/realview.c  |  1 +
>  hw/arm/sabrelite.c |  2 +-
>  hw/arm/vexpress.c  | 16 ++--
>  hw/arm/virt.c  |  8 +++-
>  hw/arm/xlnx-zynqmp.c   | 16 ++--
>  target/arm/cpu.c   |  8 +++-
>  13 files changed, 56 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
> index 7b7b97f74c..ed772d5bd9 100644
> --- a/hw/arm/fsl-imx6.c
> +++ b/hw/arm/fsl-imx6.c
> @@ -23,6 +23,7 @@
>  #include "qapi/error.h"
>  #include "qemu-common.h"
>  #include "hw/arm/fsl-imx6.h"
> +#include "hw/boards.h"
>  #include "sysemu/sysemu.h"
>  #include "chardev/char.h"
>  #include "qemu/error-report.h"
> @@ -33,11 +34,12 @@
>  
>  static void fsl_imx6_init(Object *obj)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX6State *s = FSL_IMX6(obj);
>  char name[NAME_SIZE];
>  int i;
>  
> -for (i = 0; i < MIN(smp_cpus, FSL_IMX6_NUM_CPUS); i++) {
> +for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6_NUM_CPUS); i++) {
>  snprintf(name, NAME_SIZE, "cpu%d", i);
>  object_initialize_child(obj, name, >cpu[i], sizeof(s->cpu[i]),
>  "cortex-a9-" TYPE_ARM_CPU, _abort, 
> NULL);
> @@ -93,9 +95,11 @@ static void fsl_imx6_init(Object *obj)
>  
>  static void fsl_imx6_realize(DeviceState *dev, Error **errp)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX6State *s = FSL_IMX6(dev);
>  uint16_t i;
>  Error *err = NULL;
> +unsigned int smp_cpus = ms->smp.cpus;
>  
>  if (smp_cpus > FSL_IMX6_NUM_CPUS) {
>  error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
> diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
> index 4b56bfa8d1..74b8ecbbb6 100644
> --- a/hw/arm/fsl-imx6ul.c
> +++ b/hw/arm/fsl-imx6ul.c
> @@ -21,6 +21,7 @@
>  #include "qemu-common.h"
>  #include "hw/arm/fsl-imx6ul.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/boards.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/error-report.h"
>  
> @@ -28,11 +29,12 @@
>  
>  static void fsl_imx6ul_init(Object *obj)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX6ULState *s = FSL_IMX6UL(obj);
>  char name[NAME_SIZE];
>  int i;
>  
> -for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
> +for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6UL_NUM_CPUS); i++) {
>  snprintf(name, NAME_SIZE, "cpu%d", i);
>  object_initialize_child(obj, name, >cpu[i], sizeof(s->cpu[i]),
>  "cortex-a7-" TYPE_ARM_CPU, _abort, 
> NULL);
> @@ -156,10 +158,12 @@ static void fsl_imx6ul_init(Object *obj)
>  
>  static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX6ULState *s = FSL_IMX6UL(dev);
>  int i;
>  qemu_irq irq;
>  char name[NAME_SIZE];
> +unsigned int smp_cpus = ms->smp.cpus;
>  
>  if (smp_cpus > FSL_IMX6UL_NUM_CPUS) {
>  error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
> diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
> index 7663ad6861..71cc414de6 100644
> --- a/hw/arm/fsl-imx7.c
> +++ b/hw/arm/fsl-imx7.c
> @@ -23,6 +23,7 @@
>  #include "qemu-common.h"
>  #include "hw/arm/fsl-imx7.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/boards.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/error-report.h"
>  
> @@ -30,12 +31,12 @@
>  
>  static void fsl_imx7_init(Object *obj)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX7State *s = FSL_IMX7(obj);
>  char name[NAME_SIZE];
>  int i;
>  
> -
> -for (i = 0; i < MIN(smp_cpus, FSL_IMX7_NUM_CPUS); i++) {
> +for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
>  snprintf(name, NAME_SIZE, "cpu%d", i);
>  object_initialize_child(obj, name, >cpu[i], sizeof(s->cpu[i]),
>  ARM_CPU_TYPE_NAME("cortex-a7"), _abort,
> @@ -155,11 +156,13 @@ static void fsl_imx7_init(Object *obj)
>  
>  static void fsl_imx7_realize(DeviceState *dev, Error **errp)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  FslIMX7State *s = FSL_IMX7(dev);
>  

Re: [Qemu-devel] [PATCH v3 09/10] hw: Replace global smp variables with MachineState for all remaining archs

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:27AM +0800, Like Xu wrote:
> The global smp variables in alpha/hppa/mips/openrisc/sparc*/xtensa codes
> are replaced with smp properties from MachineState.
> 
> A local variable of the same name would be introduced in the declaration
> phase if it's used widely in the context OR replace it on the spot if it's
> only used once. No semantic changes.
> 
> Signed-off-by: Like Xu 
> Reviewed-by: Alistair Francis 

CCing the maintainers for those machines.  Any objections to merging this
through the Machine Core tree?

> ---
>  hw/alpha/dp264.c   | 1 +
>  hw/hppa/machine.c  | 2 ++
>  hw/mips/boston.c   | 2 +-
>  hw/mips/mips_malta.c   | 2 ++
>  hw/openrisc/openrisc_sim.c | 1 +
>  hw/sparc/sun4m.c   | 2 ++
>  hw/sparc64/sun4u.c | 4 ++--
>  hw/xtensa/sim.c| 2 +-
>  hw/xtensa/xtfpga.c | 1 +
>  9 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
> index 0347eb897c..9dfb835013 100644
> --- a/hw/alpha/dp264.c
> +++ b/hw/alpha/dp264.c
> @@ -63,6 +63,7 @@ static void clipper_init(MachineState *machine)
>  char *palcode_filename;
>  uint64_t palcode_entry, palcode_low, palcode_high;
>  uint64_t kernel_entry, kernel_low, kernel_high;
> +unsigned int smp_cpus = machine->smp.cpus;
>  
>  /* Create up to 4 cpus.  */
>  memset(cpus, 0, sizeof(cpus));
> diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
> index 416e67bab1..662838d83b 100644
> --- a/hw/hppa/machine.c
> +++ b/hw/hppa/machine.c
> @@ -72,6 +72,7 @@ static void machine_hppa_init(MachineState *machine)
>  MemoryRegion *ram_region;
>  MemoryRegion *cpu_region;
>  long i;
> +unsigned int smp_cpus = machine->smp.cpus;
>  
>  ram_size = machine->ram_size;
>  
> @@ -242,6 +243,7 @@ static void machine_hppa_init(MachineState *machine)
>  
>  static void hppa_machine_reset(MachineState *ms)
>  {
> +unsigned int smp_cpus = ms->smp.cpus;
>  int i;
>  
>  qemu_devices_reset();
> diff --git a/hw/mips/boston.c b/hw/mips/boston.c
> index a8b29f62f5..ccbfac54ef 100644
> --- a/hw/mips/boston.c
> +++ b/hw/mips/boston.c
> @@ -460,7 +460,7 @@ static void boston_mach_init(MachineState *machine)
>  
>  object_property_set_str(OBJECT(s->cps), machine->cpu_type, "cpu-type",
>  );
> -object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", );
> +object_property_set_int(OBJECT(s->cps), machine->smp.cpus, "num-vp", 
> );
>  object_property_set_bool(OBJECT(s->cps), true, "realized", );
>  
>  if (err != NULL) {
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 5fe9512c24..ead5976d1a 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -1095,6 +1095,8 @@ static int64_t load_kernel (void)
>  
>  static void malta_mips_config(MIPSCPU *cpu)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
> +unsigned int smp_cpus = ms->smp.cpus;
>  CPUMIPSState *env = >env;
>  CPUState *cs = CPU(cpu);
>  
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index 0a906d815e..8d828e78ee 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -131,6 +131,7 @@ static void openrisc_sim_init(MachineState *machine)
>  qemu_irq *cpu_irqs[2];
>  qemu_irq serial_irq;
>  int n;
> +unsigned int smp_cpus = machine->smp.cpus;
>  
>  for (n = 0; n < smp_cpus; n++) {
>  cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
> diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
> index 07d126aea8..5c3739f2ef 100644
> --- a/hw/sparc/sun4m.c
> +++ b/hw/sparc/sun4m.c
> @@ -852,6 +852,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
>  FWCfgState *fw_cfg;
>  DeviceState *dev;
>  SysBusDevice *s;
> +unsigned int smp_cpus = machine->smp.cpus;
> +unsigned int max_cpus = machine->smp.max_cpus;
>  
>  /* init CPUs */
>  for(i = 0; i < smp_cpus; i++) {
> diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
> index 399f2d73c8..0807f274bf 100644
> --- a/hw/sparc64/sun4u.c
> +++ b/hw/sparc64/sun4u.c
> @@ -678,8 +678,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>  _CFG_IO(dev)->comb_iomem);
>  
>  fw_cfg = FW_CFG(dev);
> -fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> +fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus);
> +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
>  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
>  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
>  fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
> diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
> index 12c7437398..a4eef76fbc 100644
> --- a/hw/xtensa/sim.c
> +++ b/hw/xtensa/sim.c
> @@ -60,7 +60,7 @@ static void 

Re: [Qemu-devel] [PATCH v3 07/10] hw/i386: Replace global smp variables with machine smp properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:25AM +0800, Like Xu wrote:
> The global smp variables in i386 are replaced with smp machine properties.
> To avoid calling qdev_get_machine() as much as possible, some related funtions
> for acpi data generations are refactored. No semantic changes.
> 
> A local variable of the same name would be introduced in the declaration
> phase if it's used widely in the context OR replace it on the spot if it's
> only used once. No semantic changes.
> 
> Signed-off-by: Like Xu 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v3 06/10] hw/s390x: Replace global smp variables with machine smp properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:24AM +0800, Like Xu wrote:
> The global smp variables in s390x are replaced with smp machine properties.
> 
> A local variable of the same name would be introduced in the declaration
> phase if it's used widely in the context OR replace it on the spot if it's
> only used once. No semantic changes.
> 
> Signed-off-by: Like Xu 

CCing s390 maintainers.

Any objections to merging this through the Machine Core tree?

> ---
>  hw/s390x/s390-virtio-ccw.c | 3 ++-
>  hw/s390x/sclp.c| 2 +-
>  target/s390x/cpu.c | 3 +++
>  target/s390x/excp_helper.c | 5 +
>  4 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index ed1fe7a93e..692ad6e372 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -83,7 +83,7 @@ static void s390_init_cpus(MachineState *machine)
>  /* initialize possible_cpus */
>  mc->possible_cpu_arch_ids(machine);
>  
> -for (i = 0; i < smp_cpus; i++) {
> +for (i = 0; i < machine->smp.cpus; i++) {
>  s390x_new_cpu(machine->cpu_type, i, _fatal);
>  }
>  }
> @@ -410,6 +410,7 @@ static CpuInstanceProperties 
> s390_cpu_index_to_props(MachineState *ms,
>  static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
>  {
>  int i;
> +unsigned int max_cpus = ms->smp.max_cpus;
>  
>  if (ms->possible_cpus) {
>  g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus);
> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
> index 4510a800cb..fac7c3bb6c 100644
> --- a/hw/s390x/sclp.c
> +++ b/hw/s390x/sclp.c
> @@ -64,7 +64,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>  prepare_cpu_entries(sclp, read_info->entries, _count);
>  read_info->entries_cpu = cpu_to_be16(cpu_count);
>  read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
> -read_info->highest_cpu = cpu_to_be16(max_cpus - 1);
> +read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
>  
>  read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
>  
> diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
> index b1df63d82c..f1e5c0d9c3 100644
> --- a/target/s390x/cpu.c
> +++ b/target/s390x/cpu.c
> @@ -37,6 +37,7 @@
>  #include "hw/qdev-properties.h"
>  #ifndef CONFIG_USER_ONLY
>  #include "hw/hw.h"
> +#include "hw/boards.h"
>  #include "sysemu/arch_init.h"
>  #include "sysemu/sysemu.h"
>  #endif
> @@ -193,6 +194,8 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>  }
>  
>  #if !defined(CONFIG_USER_ONLY)
> +MachineState *ms = MACHINE(qdev_get_machine());
> +unsigned int max_cpus = ms->smp.max_cpus;
>  if (cpu->env.core_id >= max_cpus) {
>  error_setg(, "Unable to add CPU with core-id: %" PRIu32
> ", maximum core-id: %d", cpu->env.core_id,
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 3a467b72c5..1c6938effc 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -31,6 +31,7 @@
>  #ifndef CONFIG_USER_ONLY
>  #include "sysemu/sysemu.h"
>  #include "hw/s390x/s390_flic.h"
> +#include "hw/boards.h"
>  #endif
>  
>  void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t 
> code,
> @@ -300,6 +301,10 @@ static void do_ext_interrupt(CPUS390XState *env)
>  g_assert(cpu_addr < S390_MAX_CPUS);
>  lowcore->cpu_addr = cpu_to_be16(cpu_addr);
>  clear_bit(cpu_addr, env->emergency_signals);
> +#ifndef CONFIG_USER_ONLY
> +MachineState *ms = MACHINE(qdev_get_machine());
> +unsigned int max_cpus = ms->smp.max_cpus;
> +#endif
>  if (bitmap_empty(env->emergency_signals, max_cpus)) {
>  env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
>  }
> -- 
> 2.21.0
> 
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v2 4/5] block/nvme: add support for write zeros

2019-06-05 Thread Fam Zheng
On Wed, 04/17 22:53, Maxim Levitsky wrote:
> Signed-off-by: Maxim Levitsky 
> ---
>  block/nvme.c | 69 +++-
>  block/trace-events   |  1 +
>  include/block/nvme.h | 19 +++-
>  3 files changed, 87 insertions(+), 2 deletions(-)
> 
> diff --git a/block/nvme.c b/block/nvme.c
> index 0b1da54574..35b925899f 100644
> --- a/block/nvme.c
> +++ b/block/nvme.c
> @@ -109,6 +109,8 @@ typedef struct {
>  uint64_t max_transfer;
>  bool plugged;
>  
> +bool supports_write_zeros;
> +
>  CoMutex dma_map_lock;
>  CoQueue dma_flush_queue;
>  
> @@ -457,6 +459,10 @@ static void nvme_identify(BlockDriverState *bs, int 
> namespace, Error **errp)
>  s->max_transfer = MIN_NON_ZERO(s->max_transfer,
>s->page_size / sizeof(uint64_t) * s->page_size);
>  
> +
> +

Too many blank lines here.

> +s->supports_write_zeros = (idctrl->oncs & NVME_ONCS_WRITE_ZEROS) != 0;
> +
>  memset(resp, 0, 4096);
>  
>  cmd.cdw10 = 0;
> @@ -469,6 +475,11 @@ static void nvme_identify(BlockDriverState *bs, int 
> namespace, Error **errp)
>  s->nsze = le64_to_cpu(idns->nsze);
>  lbaf = >lbaf[NVME_ID_NS_FLBAS_INDEX(idns->flbas)];
>  
> +if (NVME_ID_NS_DLFEAT_WRITE_ZEROS(idns->dlfeat) &&
> +NVME_ID_NS_DLFEAT_READ_BEHAVIOR(idns->dlfeat) ==
> +NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ZEROS)
> +bs->supported_write_flags |= BDRV_REQ_MAY_UNMAP;
> +
>  if (lbaf->ms) {
>  error_setg(errp, "Namespaces with metadata are not yet supported");
>  goto out;
> @@ -763,6 +774,8 @@ static int nvme_file_open(BlockDriverState *bs, QDict 
> *options, int flags,
>  int ret;
>  BDRVNVMeState *s = bs->opaque;
>  
> +bs->supported_write_flags = BDRV_REQ_FUA;
> +
>  opts = qemu_opts_create(_opts, NULL, 0, _abort);
>  qemu_opts_absorb_qdict(opts, options, _abort);
>  device = qemu_opt_get(opts, NVME_BLOCK_OPT_DEVICE);
> @@ -791,7 +804,6 @@ static int nvme_file_open(BlockDriverState *bs, QDict 
> *options, int flags,
>  goto fail;
>  }
>  }
> -bs->supported_write_flags = BDRV_REQ_FUA;
>  return 0;
>  fail:
>  nvme_close(bs);
> @@ -1080,6 +1092,58 @@ static coroutine_fn int nvme_co_flush(BlockDriverState 
> *bs)
>  }
>  
>  
> +static coroutine_fn int nvme_co_pwrite_zeroes(BlockDriverState *bs,
> +int64_t offset, int bytes, BdrvRequestFlags flags)
> +{
> +BDRVNVMeState *s = bs->opaque;
> +NVMeQueuePair *ioq = s->queues[1];
> +NVMeRequest *req;
> +
> +if (!s->supports_write_zeros) {
> +return -ENOTSUP;
> +}

Local variables declaration below statements is not allowed as per coding style.

> +
> +uint32_t cdw12 = ((bytes >> s->blkshift) - 1) & 0x;
> +
> +NvmeCmd cmd = {
> +.opcode = NVME_CMD_WRITE_ZEROS,
> +.nsid = cpu_to_le32(s->nsid),
> +.cdw10 = cpu_to_le32((offset >> s->blkshift) & 0x),
> +.cdw11 = cpu_to_le32(((offset >> s->blkshift) >> 32) & 0x),
> +};
> +
> +NVMeCoData data = {
> +.ctx = bdrv_get_aio_context(bs),
> +.ret = -EINPROGRESS,
> +};
> +
> +if (flags & BDRV_REQ_MAY_UNMAP) {
> +cdw12 |= (1 << 25);
> +}
> +
> +if (flags & BDRV_REQ_FUA) {
> +cdw12 |= (1 << 30);
> +}
> +
> +cmd.cdw12 = cpu_to_le32(cdw12);
> +
> +trace_nvme_write_zeros(s, offset, bytes, flags);
> +assert(s->nr_queues > 1);
> +req = nvme_get_free_req(ioq);
> +assert(req);
> +
> +nvme_submit_command(s, ioq, req, , nvme_rw_cb, );
> +
> +data.co = qemu_coroutine_self();
> +while (data.ret == -EINPROGRESS) {
> +qemu_coroutine_yield();
> +}
> +
> +trace_nvme_rw_done(s, true, offset, bytes, data.ret);
> +return data.ret;
> +}
> +
> +
>  static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
> BlockReopenQueue *queue, Error **errp)
>  {
> @@ -1184,6 +1248,9 @@ static BlockDriver bdrv_nvme = {
>  
>  .bdrv_co_preadv   = nvme_co_preadv,
>  .bdrv_co_pwritev  = nvme_co_pwritev,
> +
> +.bdrv_co_pwrite_zeroes= nvme_co_pwrite_zeroes,
> +
>  .bdrv_co_flush_to_disk= nvme_co_flush,
>  .bdrv_reopen_prepare  = nvme_reopen_prepare,
>  
> diff --git a/block/trace-events b/block/trace-events
> index 7335a42540..943a58569f 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -144,6 +144,7 @@ nvme_submit_command_raw(int c0, int c1, int c2, int c3, 
> int c4, int c5, int c6,
>  nvme_handle_event(void *s) "s %p"
>  nvme_poll_cb(void *s) "s %p"
>  nvme_prw_aligned(void *s, int is_write, uint64_t offset, uint64_t bytes, int 
> flags, int niov) "s %p is_write %d offset %"PRId64" bytes %"PRId64" flags %d 
> niov %d"
> +nvme_write_zeros(void *s, uint64_t offset, uint64_t bytes, int flags) "s %p 
> offset %"PRId64" bytes %"PRId64" flags %d"
>  nvme_qiov_unaligned(const void *qiov, int n, void *base, 

Re: [Qemu-devel] [PATCH v3 04/10] hw/ppc: Replace global smp variables with machine smp properties

2019-06-05 Thread Eduardo Habkost
On Wed, Jun 05, 2019 at 11:52:41PM -0300, Eduardo Habkost wrote:
> On Sun, May 19, 2019 at 04:54:22AM +0800, Like Xu wrote:
> > The global smp variables in ppc are replaced with smp machine properties.
> > 
> > A local variable of the same name would be introduced in the declaration
> > phase if it's used widely in the context OR replace it on the spot if it's
> > only used once. No semantic changes.
> > 
> > Signed-off-by: Like Xu 
> 
> Any objections from the ppc maintainers to queueing this through
> the Machine Core tree?

Oops, CCing the ppc maintainers.

> 
> > ---
> >  hw/ppc/e500.c |  3 +++
> >  hw/ppc/mac_newworld.c |  3 ++-
> >  hw/ppc/mac_oldworld.c |  3 ++-
> >  hw/ppc/pnv.c  |  6 --
> >  hw/ppc/prep.c |  4 ++--
> >  hw/ppc/spapr.c| 34 ++
> >  hw/ppc/spapr_rtas.c   |  4 +++-
> >  7 files changed, 42 insertions(+), 15 deletions(-)
> > 
> > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> > index beb2efd694..5e42e5a059 100644
> > --- a/hw/ppc/e500.c
> > +++ b/hw/ppc/e500.c
> > @@ -307,6 +307,7 @@ static int ppce500_load_device_tree(PPCE500MachineState 
> > *pms,
> >  bool dry_run)
> >  {
> >  MachineState *machine = MACHINE(pms);
> > +unsigned int smp_cpus = machine->smp.cpus;
> >  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
> >  CPUPPCState *env = first_cpu->env_ptr;
> >  int ret = -1;
> > @@ -734,6 +735,7 @@ static DeviceState 
> > *ppce500_init_mpic_qemu(PPCE500MachineState *pms,
> >  SysBusDevice *s;
> >  int i, j, k;
> >  MachineState *machine = MACHINE(pms);
> > +unsigned int smp_cpus = machine->smp.cpus;
> >  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
> >  
> >  dev = qdev_create(NULL, TYPE_OPENPIC);
> > @@ -846,6 +848,7 @@ void ppce500_init(MachineState *machine)
> >  struct boot_info *boot_info;
> >  int dt_size;
> >  int i;
> > +unsigned int smp_cpus = machine->smp.cpus;
> >  /* irq num for pin INTA, INTB, INTC and INTD is 1, 2, 3 and
> >   * 4 respectively */
> >  unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
> > diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
> > index 02d8559621..257b26ee24 100644
> > --- a/hw/ppc/mac_newworld.c
> > +++ b/hw/ppc/mac_newworld.c
> > @@ -135,6 +135,7 @@ static void ppc_core99_init(MachineState *machine)
> >  DeviceState *dev, *pic_dev;
> >  hwaddr nvram_addr = 0xFFF04000;
> >  uint64_t tbfreq;
> > +unsigned int smp_cpus = machine->smp.cpus;
> >  
> >  linux_boot = (kernel_filename != NULL);
> >  
> > @@ -464,7 +465,7 @@ static void ppc_core99_init(MachineState *machine)
> >  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
> >  
> >  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> > -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> > +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, 
> > (uint16_t)machine->smp.max_cpus);
> >  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
> >  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
> >  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> > diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> > index 460cbc7923..1968f05a6c 100644
> > --- a/hw/ppc/mac_oldworld.c
> > +++ b/hw/ppc/mac_oldworld.c
> > @@ -99,6 +99,7 @@ static void ppc_heathrow_init(MachineState *machine)
> >  DeviceState *dev, *pic_dev;
> >  BusState *adb_bus;
> >  int bios_size;
> > +unsigned int smp_cpus = machine->smp.cpus;
> >  uint16_t ppc_boot_device;
> >  DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
> >  void *fw_cfg;
> > @@ -322,7 +323,7 @@ static void ppc_heathrow_init(MachineState *machine)
> >  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
> >  
> >  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> > -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> > +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, 
> > (uint16_t)machine->smp.max_cpus);
> >  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
> >  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
> >  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> > index 1e8c505936..3bb15338de 100644
> > --- a/hw/ppc/pnv.c
> > +++ b/hw/ppc/pnv.c
> > @@ -678,7 +678,8 @@ static void pnv_init(MachineState *machine)
> >  object_property_add_child(OBJECT(pnv), chip_name, chip, 
> > _fatal);
> >  object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
> >  _fatal);
> > -object_property_set_int(chip, smp_cores, "nr-cores", _fatal);
> > +object_property_set_int(chip, machine->smp.cores,
> > +"nr-cores", _fatal);
> >  object_property_set_bool(chip, true, "realized", _fatal);
> >  }
> >  g_free(chip_typename);
> > @@ -1134,6 +1135,7 @@ static 

Re: [Qemu-devel] [PATCH v3 04/10] hw/ppc: Replace global smp variables with machine smp properties

2019-06-05 Thread Eduardo Habkost
On Sun, May 19, 2019 at 04:54:22AM +0800, Like Xu wrote:
> The global smp variables in ppc are replaced with smp machine properties.
> 
> A local variable of the same name would be introduced in the declaration
> phase if it's used widely in the context OR replace it on the spot if it's
> only used once. No semantic changes.
> 
> Signed-off-by: Like Xu 

Any objections from the ppc maintainers to queueing this through
the Machine Core tree?

> ---
>  hw/ppc/e500.c |  3 +++
>  hw/ppc/mac_newworld.c |  3 ++-
>  hw/ppc/mac_oldworld.c |  3 ++-
>  hw/ppc/pnv.c  |  6 --
>  hw/ppc/prep.c |  4 ++--
>  hw/ppc/spapr.c| 34 ++
>  hw/ppc/spapr_rtas.c   |  4 +++-
>  7 files changed, 42 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index beb2efd694..5e42e5a059 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -307,6 +307,7 @@ static int ppce500_load_device_tree(PPCE500MachineState 
> *pms,
>  bool dry_run)
>  {
>  MachineState *machine = MACHINE(pms);
> +unsigned int smp_cpus = machine->smp.cpus;
>  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
>  CPUPPCState *env = first_cpu->env_ptr;
>  int ret = -1;
> @@ -734,6 +735,7 @@ static DeviceState 
> *ppce500_init_mpic_qemu(PPCE500MachineState *pms,
>  SysBusDevice *s;
>  int i, j, k;
>  MachineState *machine = MACHINE(pms);
> +unsigned int smp_cpus = machine->smp.cpus;
>  const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
>  
>  dev = qdev_create(NULL, TYPE_OPENPIC);
> @@ -846,6 +848,7 @@ void ppce500_init(MachineState *machine)
>  struct boot_info *boot_info;
>  int dt_size;
>  int i;
> +unsigned int smp_cpus = machine->smp.cpus;
>  /* irq num for pin INTA, INTB, INTC and INTD is 1, 2, 3 and
>   * 4 respectively */
>  unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
> diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
> index 02d8559621..257b26ee24 100644
> --- a/hw/ppc/mac_newworld.c
> +++ b/hw/ppc/mac_newworld.c
> @@ -135,6 +135,7 @@ static void ppc_core99_init(MachineState *machine)
>  DeviceState *dev, *pic_dev;
>  hwaddr nvram_addr = 0xFFF04000;
>  uint64_t tbfreq;
> +unsigned int smp_cpus = machine->smp.cpus;
>  
>  linux_boot = (kernel_filename != NULL);
>  
> @@ -464,7 +465,7 @@ static void ppc_core99_init(MachineState *machine)
>  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
>  
>  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
>  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
>  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
>  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
> index 460cbc7923..1968f05a6c 100644
> --- a/hw/ppc/mac_oldworld.c
> +++ b/hw/ppc/mac_oldworld.c
> @@ -99,6 +99,7 @@ static void ppc_heathrow_init(MachineState *machine)
>  DeviceState *dev, *pic_dev;
>  BusState *adb_bus;
>  int bios_size;
> +unsigned int smp_cpus = machine->smp.cpus;
>  uint16_t ppc_boot_device;
>  DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
>  void *fw_cfg;
> @@ -322,7 +323,7 @@ static void ppc_heathrow_init(MachineState *machine)
>  sysbus_mmio_map(s, 1, CFG_ADDR + 2);
>  
>  fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
>  fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
>  fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
>  fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 1e8c505936..3bb15338de 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -678,7 +678,8 @@ static void pnv_init(MachineState *machine)
>  object_property_add_child(OBJECT(pnv), chip_name, chip, 
> _fatal);
>  object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",
>  _fatal);
> -object_property_set_int(chip, smp_cores, "nr-cores", _fatal);
> +object_property_set_int(chip, machine->smp.cores,
> +"nr-cores", _fatal);
>  object_property_set_bool(chip, true, "realized", _fatal);
>  }
>  g_free(chip_typename);
> @@ -1134,6 +1135,7 @@ static void pnv_chip_instance_init(Object *obj)
>  
>  static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
>  {
> +MachineState *ms = MACHINE(qdev_get_machine());
>  Error *error = NULL;
>  PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>  const char *typename = pnv_chip_core_typename(chip);
> @@ -1168,7 

Re: [Qemu-devel] [Qemu-ppc] [PATCH v9 1/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-06-05 Thread David Gibson
On Mon, Jun 03, 2019 at 01:17:23PM +0200, Greg Kurz wrote:
> On Mon, 3 Jun 2019 12:12:43 +0200
> Greg Kurz  wrote:
> 
> > On Wed, 29 May 2019 11:10:14 +0530
> > Aravinda Prasad  wrote:
> > 
> > > This patch adds support in QEMU to handle "ibm,nmi-register"
> > > and "ibm,nmi-interlock" RTAS calls.
> > > 
> > > The machine check notification address is saved when the
> > > OS issues "ibm,nmi-register" RTAS call.
> > > 
> > > This patch also handles the case when multiple processors
> > > experience machine check at or about the same time by
> > > handling "ibm,nmi-interlock" call. In such cases, as per
> > > PAPR, subsequent processors serialize waiting for the first
> > > processor to issue the "ibm,nmi-interlock" call. The second
> > > processor that also received a machine check error waits
> > > till the first processor is done reading the error log.
> > > The first processor issues "ibm,nmi-interlock" call
> > > when the error log is consumed. This patch implements the
> > > releasing part of the error-log while subsequent patch
> > > (which builds error log) handles the locking part.
> > > 
> > > Signed-off-by: Aravinda Prasad 
> > > Reviewed-by: David Gibson 
> > > ---  
> > 
> > The code looks okay but it still seems wrong to advertise the RTAS
> > calls to the guest that early in the series. The linux kernel in
> > the guest will assume FWNMI is functional, which isn't true until
> > patch 6 (yes, migration is part of the feature, it should be
> > supported upfront, not fixed afterwards).
> > 
> > It doesn't help much to introduce the RTAS calls early and to
> > modify them in the other patches. I'd rather see the rest of
> > the code first and a final patch that introduces the fully
> > functional RTAS calls and calls spapr_rtas_register().
> > 
> 
> Thinking again, you should introduce the "fwnmi-mce" spapr capability in
> its own patch first, default to "off" and and have the last patch in the
> series to switch the default to "on" for newer machine types only.
> 
> This patch should then only register the RTAS calls if "fwnmi-mcr" is set
> to "on".

Yes, I think this is a good approach.

> This should address the fact that we don't want to expose a partially
> implemented FWNMI feature to the guest, and we don't want to support
> FWNMI at all with older machine types for the sake of compatibility.
> 
> > >  hw/ppc/spapr.c |7 +
> > >  hw/ppc/spapr_rtas.c|   65 
> > > 
> > >  include/hw/ppc/spapr.h |9 ++-
> > >  3 files changed, 80 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index e2b33e5..fae28a9 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -1808,6 +1808,11 @@ static void spapr_machine_reset(void)
> > >  first_ppc_cpu->env.gpr[5] = 0;
> > >  
> > >  spapr->cas_reboot = false;
> > > +
> > > +spapr->guest_machine_check_addr = -1;
> > > +
> > > +/* Signal all vCPUs waiting on this condition */
> > > +qemu_cond_broadcast(>mc_delivery_cond);
> > >  }
> > >  
> > >  static void spapr_create_nvram(SpaprMachineState *spapr)
> > > @@ -3072,6 +3077,8 @@ static void spapr_machine_init(MachineState 
> > > *machine)
> > >  
> > >  kvmppc_spapr_enable_inkernel_multitce();
> > >  }
> > > +
> > > +qemu_cond_init(>mc_delivery_cond);
> > >  }
> > >  
> > >  static int spapr_kvm_type(MachineState *machine, const char *vm_type)
> > > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > > index 5bc1a93..e7509cf 100644
> > > --- a/hw/ppc/spapr_rtas.c
> > > +++ b/hw/ppc/spapr_rtas.c
> > > @@ -352,6 +352,38 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
> > > SpaprMachineState *spapr,
> > >  rtas_st(rets, 1, 100);
> > >  }
> > >  
> > > +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> > > +  SpaprMachineState *spapr,
> > > +  uint32_t token, uint32_t nargs,
> > > +  target_ulong args,
> > > +  uint32_t nret, target_ulong rets)
> > > +{
> > > +hwaddr rtas_addr = spapr_get_rtas_addr();
> > > +
> > > +if (!rtas_addr) {
> > > +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> > > +return;
> > > +}
> > > +
> > > +spapr->guest_machine_check_addr = rtas_ld(args, 1);
> > > +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> > > +}
> > > +
> > > +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> > > +   SpaprMachineState *spapr,
> > > +   uint32_t token, uint32_t nargs,
> > > +   target_ulong args,
> > > +   uint32_t nret, target_ulong rets)
> > > +{
> > > +if (spapr->guest_machine_check_addr == -1) {
> > > +/* NMI register not called */
> > > +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> > > +} else {
> > > +

Re: [Qemu-devel] [PATCH v9 3/6] target/ppc: Handle NMI guest exit

2019-06-05 Thread David Gibson
On Wed, May 29, 2019 at 11:10:32AM +0530, Aravinda Prasad wrote:
> Memory error such as bit flips that cannot be corrected
> by hardware are passed on to the kernel for handling.
> If the memory address in error belongs to guest then
> the guest kernel is responsible for taking suitable action.
> Patch [1] enhances KVM to exit guest with exit reason
> set to KVM_EXIT_NMI in such cases. This patch handles
> KVM_EXIT_NMI exit.
> 
> [1] https://www.spinics.net/lists/kvm-ppc/msg12637.html
> (e20bbd3d and related commits)
> 
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c  |1 +
>  hw/ppc/spapr_events.c   |   23 +++
>  hw/ppc/spapr_rtas.c |5 +
>  include/hw/ppc/spapr.h  |6 ++
>  target/ppc/kvm.c|   16 
>  target/ppc/kvm_ppc.h|2 ++
>  target/ppc/trace-events |1 +
>  7 files changed, 54 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index fae28a9..6b6c962 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1809,6 +1809,7 @@ static void spapr_machine_reset(void)
>  
>  spapr->cas_reboot = false;
>  
> +spapr->mc_status = -1;
>  spapr->guest_machine_check_addr = -1;
>  
>  /* Signal all vCPUs waiting on this condition */
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index ae0f093..a18446b 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -620,6 +620,29 @@ void 
> spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
>  RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, _id);
>  }
>  
> +void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
> +{
> +SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());

You ignore the 'recovered' parameter, is that right?

> +while (spapr->mc_status != -1) {
> +/*
> + * Check whether the same CPU got machine check error
> + * while still handling the mc error (i.e., before
> + * that CPU called "ibm,nmi-interlock")
> + */
> +if (spapr->mc_status == cpu->vcpu_id) {
> +qemu_system_guest_panicked(NULL);
> +return;
> +}
> +qemu_cond_wait_iothread(>mc_delivery_cond);
> +/* Meanwhile if the system is reset, then just return */
> +if (spapr->guest_machine_check_addr == -1) {
> +return;
> +}
> +}
> +spapr->mc_status = cpu->vcpu_id;
> +}
> +
>  static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
>  uint32_t token, uint32_t nargs,
>  target_ulong args,
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index e7509cf..e0bdfc8 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -379,6 +379,11 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
>  /* NMI register not called */
>  rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
>  } else {
> +/*
> + * vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
> + * hence unset mc_status.
> + */
> +spapr->mc_status = -1;
>  qemu_cond_signal(>mc_delivery_cond);
>  rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 9dc5e30..fc3a776 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -190,6 +190,11 @@ struct SpaprMachineState {
>  
>  /* State related to "ibm,nmi-register" and "ibm,nmi-interlock" calls */
>  target_ulong guest_machine_check_addr;
> +/*
> + * mc_status is set to -1 if mc is not in progress, else is set to the 
> CPU
> + * handling the mc.
> + */
> +int mc_status;
>  QemuCond mc_delivery_cond;
>  
>  /*< public >*/
> @@ -793,6 +798,7 @@ void spapr_clear_pending_events(SpaprMachineState *spapr);
>  int spapr_max_server_number(SpaprMachineState *spapr);
>  void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
>uint64_t pte0, uint64_t pte1);
> +void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered);
>  
>  /* DRC callbacks. */
>  void spapr_core_release(DeviceState *dev);
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 3bf0a46..39f1a73 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1761,6 +1761,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
> *run)
>  ret = 0;
>  break;
>  
> +case KVM_EXIT_NMI:
> +trace_kvm_handle_nmi_exception();
> +ret = kvm_handle_nmi(cpu, run);
> +break;
> +
>  default:
>  fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>  ret = -1;
> @@ -2844,6 +2849,17 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  return data & 0x;
>  }
>  
> +int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
> +{
> +bool recovered = run->flags & KVM_RUN_PPC_NMI_DISP_FULLY_RECOV;
> +
> +cpu_synchronize_state(CPU(cpu));
> +
> +

Re: [Qemu-devel] [PATCH v9 1/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-06-05 Thread David Gibson
On Wed, May 29, 2019 at 11:10:14AM +0530, Aravinda Prasad wrote:
> This patch adds support in QEMU to handle "ibm,nmi-register"
> and "ibm,nmi-interlock" RTAS calls.
> 
> The machine check notification address is saved when the
> OS issues "ibm,nmi-register" RTAS call.
> 
> This patch also handles the case when multiple processors
> experience machine check at or about the same time by
> handling "ibm,nmi-interlock" call. In such cases, as per
> PAPR, subsequent processors serialize waiting for the first
> processor to issue the "ibm,nmi-interlock" call. The second
> processor that also received a machine check error waits
> till the first processor is done reading the error log.
> The first processor issues "ibm,nmi-interlock" call
> when the error log is consumed. This patch implements the
> releasing part of the error-log while subsequent patch
> (which builds error log) handles the locking part.
> 
> Signed-off-by: Aravinda Prasad 
> Reviewed-by: David Gibson 
> ---
>  hw/ppc/spapr.c |7 +
>  hw/ppc/spapr_rtas.c|   65 
> 
>  include/hw/ppc/spapr.h |9 ++-
>  3 files changed, 80 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e2b33e5..fae28a9 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1808,6 +1808,11 @@ static void spapr_machine_reset(void)
>  first_ppc_cpu->env.gpr[5] = 0;
>  
>  spapr->cas_reboot = false;
> +
> +spapr->guest_machine_check_addr = -1;
> +
> +/* Signal all vCPUs waiting on this condition */
> +qemu_cond_broadcast(>mc_delivery_cond);
>  }
>  
>  static void spapr_create_nvram(SpaprMachineState *spapr)
> @@ -3072,6 +3077,8 @@ static void spapr_machine_init(MachineState *machine)
>  
>  kvmppc_spapr_enable_inkernel_multitce();
>  }
> +
> +qemu_cond_init(>mc_delivery_cond);
>  }
>  
>  static int spapr_kvm_type(MachineState *machine, const char *vm_type)
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 5bc1a93..e7509cf 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -352,6 +352,38 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  rtas_st(rets, 1, 100);
>  }
>  
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +  SpaprMachineState *spapr,
> +  uint32_t token, uint32_t nargs,
> +  target_ulong args,
> +  uint32_t nret, target_ulong rets)
> +{
> +hwaddr rtas_addr = spapr_get_rtas_addr();
> +
> +if (!rtas_addr) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +return;
> +}
> +
> +spapr->guest_machine_check_addr = rtas_ld(args, 1);
> +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> +   SpaprMachineState *spapr,
> +   uint32_t token, uint32_t nargs,
> +   target_ulong args,
> +   uint32_t nret, target_ulong rets)
> +{
> +if (spapr->guest_machine_check_addr == -1) {
> +/* NMI register not called */
> +rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> +} else {
> +qemu_cond_signal(>mc_delivery_cond);
> +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +}
> +
>  static struct rtas_call {
>  const char *name;
>  spapr_rtas_fn fn;
> @@ -470,6 +502,35 @@ void spapr_load_rtas(SpaprMachineState *spapr, void 
> *fdt, hwaddr addr)
>  }
>  }
>  
> +hwaddr spapr_get_rtas_addr(void)
> +{
> +SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> +int rtas_node;
> +const struct fdt_property *rtas_addr_prop;
> +void *fdt = spapr->fdt_blob;
> +uint32_t rtas_addr;
> +
> +/* fetch rtas addr from fdt */
> +rtas_node = fdt_path_offset(fdt, "/rtas");
> +if (rtas_node == 0) {
> +return 0;

This is incorrect, a return code < 0 indicates an error which you
should check for.  A return code of 0 indicates the root node, which
could only happen if libfdt was badly buggy.

> +}
> +
> +rtas_addr_prop = fdt_get_property(fdt, rtas_node, "linux,rtas-base", 
> NULL);

fdt_get_property is generally only needed for certain edge cases.
fdt_getprop() is a better option.

> +if (!rtas_addr_prop) {
> +return 0;
> +}
> +
> +/*
> + * We assume that the OS called RTAS instantiate-rtas, but some other
> + * OS might call RTAS instantiate-rtas-64 instead. This fine as of now
> + * as SLOF only supports 32-bit variant.
> + */
> +rtas_addr = fdt32_to_cpu(*(uint32_t *)rtas_addr_prop->data);
> +return (hwaddr)rtas_addr;
> +}
> +
> +
>  static void core_rtas_register_types(void)
>  {
>  spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
> @@ -493,6 +554,10 @@ static void core_rtas_register_types(void)
>

[Qemu-devel] [PATCH 1/2] migration/xbzrle: update cache and current_data in one place

2019-06-05 Thread Wei Yang
When we are not in the last_stage, we need to update the cache if page
is not the same.

Currently this procedure is scattered in two places and mixed with
encoding status check.

This patch extract this general step out to make the code a little bit
easy to read.

Signed-off-by: Wei Yang 
---
 migration/ram.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index e9b40d636d..878cd8de7a 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1594,25 +1594,24 @@ static int save_xbzrle_page(RAMState *rs, uint8_t 
**current_data,
 encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
TARGET_PAGE_SIZE, XBZRLE.encoded_buf,
TARGET_PAGE_SIZE);
+
+/*
+ * we need to update the data in the cache, in order to get the same data
+ */
+if (!last_stage && encoded_len != 0) {
+memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
+*current_data = prev_cached_page;
+}
+
 if (encoded_len == 0) {
 trace_save_xbzrle_page_skipping();
 return 0;
 } else if (encoded_len == -1) {
 trace_save_xbzrle_page_overflow();
 xbzrle_counters.overflow++;
-/* update data in the cache */
-if (!last_stage) {
-memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);
-*current_data = prev_cached_page;
-}
 return -1;
 }
 
-/* we need to update the data in the cache, in order to get the same data 
*/
-if (!last_stage) {
-memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
-}
-
 /* Send XBZRLE based compressed page */
 bytes_xbzrle = save_page_header(rs, rs->f, block,
 offset | RAM_SAVE_FLAG_XBZRLE);
-- 
2.19.1




[Qemu-devel] [PATCH 2/2] migration/xbzrle: cleanup the handling cache miss condition

2019-06-05 Thread Wei Yang
For cache miss condition not in last_stage, we need to insert data into
cache. When this step succeed, current_data should be updated. While no
matter these checks pass or not, -1 is returned.

Based on this, the logic in cache miss handling could be simplified a
little.

Signed-off-by: Wei Yang 
---
 migration/ram.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 878cd8de7a..67ba075cc4 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1572,15 +1572,14 @@ static int save_xbzrle_page(RAMState *rs, uint8_t 
**current_data,
 if (!cache_is_cached(XBZRLE.cache, current_addr,
  ram_counters.dirty_sync_count)) {
 xbzrle_counters.cache_miss++;
-if (!last_stage) {
-if (cache_insert(XBZRLE.cache, current_addr, *current_data,
- ram_counters.dirty_sync_count) == -1) {
-return -1;
-} else {
-/* update *current_data when the page has been
-   inserted into cache */
-*current_data = get_cached_data(XBZRLE.cache, current_addr);
-}
+if (!last_stage &&
+!cache_insert(XBZRLE.cache, current_addr, *current_data,
+  ram_counters.dirty_sync_count)) {
+/*
+ * update *current_data when the page has been inserted into
+ * cache
+ */
+*current_data = get_cached_data(XBZRLE.cache, current_addr);
 }
 return -1;
 }
-- 
2.19.1




[Qemu-devel] [PATCH 0/2] xbzrle: improve readability a little

2019-06-05 Thread Wei Yang
Two trivial patches to make save_xbzrle_page() a little bit easy to
understand.

Wei Yang (2):
  migration/xbzrle: update cache and current_data in one place
  migration/xbzrle: cleanup the handling cache miss condition

 migration/ram.c | 36 +---
 1 file changed, 17 insertions(+), 19 deletions(-)

-- 
2.19.1




Re: [Qemu-devel] [PATCH v2 1/2] x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE

2019-06-05 Thread Tao Xu

On 6/4/2019 10:34 PM, Cornelia Huck wrote:

On Fri, 24 May 2019 16:18:38 +0800
Tao Xu  wrote:


UMONITOR, UMWAIT and TPAUSE are a set of user wait instructions.
Availability of the user wait instructions is indicated by the presence
of the CPUID feature flag WAITPKG CPUID.0x07.0x0:ECX[5].

The patch enable the umonitor, umwait and tpause features in KVM.
Because umwait and tpause can put a (psysical) CPU into a power saving
state, by default we dont't expose it in kvm and provide a capability to
enable it. Use kvm capability to enable UMONITOR, UMWAIT and TPAUSE when
QEMU use "-overcommit cpu-pm=on, a VM can use UMONITOR, UMWAIT and TPAUSE
instructions. If the instruction causes a delay, the amount of time
delayed is called here the physical delay. The physical delay is first
computed by determining the virtual delay (the time to delay relative to
the VM’s timestamp counter). Otherwise, UMONITOR, UMWAIT and TPAUSE cause
an invalid-opcode exception(#UD).

The release document ref below link:
https://software.intel.com/sites/default/files/\
managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf

Co-developed-by: Jingqi Liu 
Signed-off-by: Jingqi Liu 
Signed-off-by: Tao Xu 
---
  linux-headers/linux/kvm.h |  1 +
  target/i386/cpu.c |  3 ++-
  target/i386/cpu.h |  1 +
  target/i386/kvm.c | 13 +
  4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index c8423e760c..86cc2dbdd0 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -993,6 +993,7 @@ struct kvm_ppc_resize_hpt {
  #define KVM_CAP_ARM_SVE 170
  #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171
  #define KVM_CAP_ARM_PTRAUTH_GENERIC 172
+#define KVM_CAP_ENABLE_USR_WAIT_PAUSE 173
  
  #ifdef KVM_CAP_IRQ_ROUTING
  


No comment on the actual change, but please split out any linux-header
changes so they can be replaced with a proper headers update when the
code is merged.

Thank you for your review, I will update this patch when the kvm patch 
change a lot.




[Qemu-devel] QEMU/KVM migration backwards compatibility broken?

2019-06-05 Thread Liran Alon
Hi,

Looking at QEMU source code, I am puzzled regarding how migration backwards 
compatibility is preserved regarding X86CPU.

As I understand it, fields that are based on KVM capabilities and guest runtime 
usage are defined in VMState subsections in order to not send them if not 
necessary.
This is done such that in case they are not needed and we migrate to an old 
QEMU which don’t support loading this state, migration will still succeed
(As .needed() method will return false and therefore this state won’t be sent 
as part of migration stream).
Furthermore, in case .needed() returns true and old QEMU don’t support loading 
this state, migration fails. As it should because we are aware that guest state
is not going to be restored properly on destination.

I’m puzzled about what will happen in the following scenario:
1) Source is running new QEMU with new KVM that supports save of some VMState 
subsection.
2) Destination is running new QEMU that supports load this state but with old 
kernel that doesn’t know how to load this state.

I would have expected in this case that if source .needed() returns true, then 
migration will fail because of lack of support in destination kernel.
However, it seems from current QEMU code that this will actually succeed in 
many cases.

For example, if msr_smi_count is sent as part of migration stream (See 
vmstate_msr_smi_count) and destination have has_msr_smi_count==false,
then destination will succeed loading migration stream but kvm_put_msrs() will 
actually ignore env->msr_smi_count and will successfully load guest state.
Therefore, migration will succeed even though it should have failed…

It seems to me that QEMU should have for every such VMState subsection, a 
.post_load() method that verifies that relevant capability is supported by 
kernel
and otherwise fail migration.

What do you think? Should I really create a patch to modify all these CPUX86 
VMState subsections to behave like this?

Thanks,
-Liran


Re: [Qemu-devel] Fwd: [j...@sing.id.au: atomic failures on qemu-system-riscv64]

2019-06-05 Thread Palmer Dabbelt

On Wed, 05 Jun 2019 13:59:53 PDT (-0700), ma...@decred.org wrote:

Joel is on vacation so here it is again.


Begin forwarded message:

From: Alistair Francis 
Subject: Re: [j...@sing.id.au: atomic failures on qemu-system-riscv64]
Date: June 5, 2019 at 7:19:53 PM GMT+1
To: "j...@sing.id.au" , "pal...@sifive.com" 
Cc: "ma...@decred.org" , "m...@carlosedp.com" 


On Fri, 2019-05-31 at 03:21 +1000, Joel Sing wrote:

I've just sent this to qemu-ri...@nongnu.org - forwarding for
visibility...


Hello Joel,

Can you please send this to the QEMU mailing list?
https://wiki.qemu.org/Contribute/MailingLists



- Forwarded message from Joel Sing  -

Date: Fri, 31 May 2019 03:20:03 +1000
From: Joel Sing 
To: qemu-ri...@nongnu.org
Subject: atomic failures on qemu-system-riscv64
User-Agent: Mutt/1.10.1 (2018-07-13)

While working on a Go (www.golang.org) port for riscv, I've run
into issues with atomics (namely LR/SC) on qemu-system-riscv64.
There are several reproducers for this problem including (using
gcc builtin atomics):

 https://gist.github.com/4a6f656c/8433032a3f70893a278259f8108aad90

And a version using inline assembly:

 https://gist.github.com/4a6f656c/d883091f5ca811822720213be343a75a

Depending on the qemu configuration the number of threads may
need increasing (to force context switching) and/or run in a
loop. Go's sync/atomic tests also fail regularly.

Having dug into the qemu code, what I believe is happening is
along the lines of the following:

1. Thread 1 runs and executes an LR - this assigns an address
  to load_res and a value to load_val (say 1).

2. A context switch occurs and thread 2 is now run - it runs
  an LR and SC on the same address modifying the stored value.
  Another LR is executed loading load_val with the current
  value (say 3).

3. A context switch occurs and thread 1 is now run again, it
  continues on its LR/SC sequence and now runs the SC instruction.
  This is based on the assumption that it had a reservation
  and the SC will fail if the memory has changed. The underlying
  implementation of SC is a cmpxchg with the value in load_val
  - this no longer has the original value and hence successfully
  compares (as does the tcg_gen_setcond_tl() between the returned
  value and load_val) thus the SC succeeds when it should not.

The diff below clears load_res when the mode changes - with this
applied the reproducers work correctly, as do Go's atomic tests.
I'm not sure this "fix" is 100% correct, but it certainly verifies
where the problem lies. It does also fall inline with the RISCV
spec:

"The SC must fail if there is an observable memory access from
another hart to the address, or if there is an intervening context
switch on this hart, or if in the meantime the hart executed a
privileged exception-return instruction."


Sorry about this, but that wording is actually a bug in the ISA manual.  The
current version says

   An SC must fail if there is
   another SC (to any address) between the LR and the SC in program
   order.  The precise statement of the atomicity requirements for
   successful LR/SC sequences is defined by the Atomicity Axiom in
   Section~\ref{sec:rvwmo}.
   
   \begin{commentary}

   A store-conditional instruction to a scratch word of memory should be used
   during a preemptive context switch to forcibly yield any existing load
   reservation.
   \end{commentary}

The text in version 2.2 was changed because it doesn't really have meaning:
harts are a hardware construct, but context switches are a software context.
There were a few of these bugs floating around the ISA manual and we cleaned
them up more than a year ago, but the version on the RISC-V website hasn't
changed.  The ratified ISA manual will have the correct wording.

That said, the Linux user ABI allows programs to rely on reservations being
shot down on context switches -- if that wasn't the case then LR/SC would be
useless.  That's how the ambiguous wording snuck into the user ISA manual: we
confused the ISA behavior (ie, what the hardware does) with the user ABI
behavior (ie, what programs can rely on).

The reason you're only seeing this in QEMU is because the hardware has a
timeout on load reservations of something like 1000 cycles, and the Linux
context switching code takes longer than that timeout.  For some reason I
remember having fixed this bug in Linux, but I must have forgotten to actually
send out the patch.

Also, unless I'm misunderstanding something our implementation of LR/SC is
pretty broken.  We're just using a CAS to check if the value changed, which
suffers from the ABA problem that LR/SC is there to fix in the first place.  I
might be missing something here, though, as it looks like MIPS is doing
essentially the same thing.


diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b17f169681..9875b8e5d3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -113,6 +113,8 @@ void riscv_cpu_set_mode(CPURISCVState *env,

Re: [Qemu-devel] [PATCH v6 0/6] linux-user/aarch64: Support PROT_BTI

2019-06-05 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190605205706.569-1-richard.hender...@linaro.org/



Hi,

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

Subject: [Qemu-devel] [PATCH v6 0/6] linux-user/aarch64: Support PROT_BTI
Type: series
Message-id: 20190605205706.569-1-richard.hender...@linaro.org

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

From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/20190605205706.569-1-richard.hender...@linaro.org -> 
patchew/20190605205706.569-1-richard.hender...@linaro.org
Switched to a new branch 'test'
6038ce2e0e tests/tcg/aarch64: Add bti smoke test
b16ad5bd7b linux-user: Parse NT_GNU_PROPERTY_TYPE_0 notes
68fefef717 include/elf: Add defines related to notes for GNU systems
951669d523 linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI
6ec44edda5 linux-user: Validate mmap/mprotect prot value
4eb77556ad linux-user/aarch64: Reset btype for syscalls and signals

=== OUTPUT BEGIN ===
1/6 Checking commit 4eb77556ad1e (linux-user/aarch64: Reset btype for syscalls 
and signals)
2/6 Checking commit 6ec44edda5a0 (linux-user: Validate mmap/mprotect prot value)
3/6 Checking commit 951669d5231b (linux-user: Set PAGE_TARGET_1 for 
TARGET_PROT_BTI)
4/6 Checking commit 68fefef717be (include/elf: Add defines related to notes for 
GNU systems)
5/6 Checking commit b16ad5bd7b5c (linux-user: Parse NT_GNU_PROPERTY_TYPE_0 
notes)
6/6 Checking commit 6038ce2e0e44 (tests/tcg/aarch64: Add bti smoke test)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#33: 
new file mode 100644

ERROR: code indent should never use tabs
#50: FILE: tests/tcg/aarch64/bti-1.c:13:
+^Ihint^I#34\n\$

ERROR: code indent should never use tabs
#51: FILE: tests/tcg/aarch64/bti-1.c:14:
+^Ib^Iskip2_sigill2\n\$

ERROR: externs should be avoided in .c files
#133: FILE: tests/tcg/aarch64/bti-crt.inc.c:13:
+int main(void);

ERROR: code indent should never use tabs
#180: FILE: tests/tcg/aarch64/bti-crt.inc.c:60:
+^I.align^I3\n\$

ERROR: code indent should never use tabs
#181: FILE: tests/tcg/aarch64/bti-crt.inc.c:61:
+^I.long^I4\n\$

ERROR: code indent should never use tabs
#182: FILE: tests/tcg/aarch64/bti-crt.inc.c:62:
+.long^I16\n\$

ERROR: code indent should never use tabs
#183: FILE: tests/tcg/aarch64/bti-crt.inc.c:63:
+.long^I5\n\$

ERROR: code indent should never use tabs
#184: FILE: tests/tcg/aarch64/bti-crt.inc.c:64:
+.string^I\"GNU\"\n\$

ERROR: code indent should never use tabs
#185: FILE: tests/tcg/aarch64/bti-crt.inc.c:65:
+^I.long^I0xc000\n\$

ERROR: code indent should never use tabs
#186: FILE: tests/tcg/aarch64/bti-crt.inc.c:66:
+^I.long^I4\n\$

ERROR: code indent should never use tabs
#187: FILE: tests/tcg/aarch64/bti-crt.inc.c:67:
+^I.long^I1\n\$

ERROR: code indent should never use tabs
#189: FILE: tests/tcg/aarch64/bti-crt.inc.c:69:
+^I.previous");$

total: 12 errors, 1 warnings, 153 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190605205706.569-1-richard.hender...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCHv4 4/6] RISC-V: Check PMP during Page Table Walks

2019-06-05 Thread Hesham Almatary
On Wed, 5 Jun 2019 at 23:07, Alistair Francis  wrote:
>
> On Thu, May 30, 2019 at 6:52 AM Hesham Almatary
>  wrote:
> >
> > The PMP should be checked when doing a page table walk, and report access
> > fault exception if the to-be-read PTE failed the PMP check.
> >
> > Suggested-by: Jonathan Behrens 
> > Signed-off-by: Hesham Almatary 
> > ---
> >  target/riscv/cpu.h|  1 +
> >  target/riscv/cpu_helper.c | 10 +-
> >  2 files changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index c17184f4e4..ab3ba3f15a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -94,6 +94,7 @@ enum {
> >  #define PRIV_VERSION_1_09_1 0x00010901
> >  #define PRIV_VERSION_1_10_0 0x00011000
> >
> > +#define TRANSLATE_PMP_FAIL 2
> >  #define TRANSLATE_FAIL 1
> >  #define TRANSLATE_SUCCESS 0
> >  #define NB_MMU_MODES 4
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 5a1cd7cf96..00bc4f1712 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -211,6 +211,12 @@ restart:
> >
> >  /* check that physical address of PTE is legal */
> >  target_ulong pte_addr = base + idx * ptesize;
> > +
> > +if (riscv_feature(env, RISCV_FEATURE_PMP) &&
> > +!pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
> > +1 << MMU_DATA_LOAD, PRV_S)) {
>
> Shouldn't we be passing mode in here?
>
I actually thought this way at the start. But then I made it PRV_S for
intentionality; as in PTW (in the current master, without hypervisor
extensions) always goes under PMP protection in S-Mode.
This also aligns with Spike implementation here [1].

[1] 
https://github.com/riscv/riscv-isa-sim/blob/8ac902f6ff877e976af434bfe8fa8445930174a1/riscv/mmu.cc#L288


> Alistair
>
> > +return TRANSLATE_PMP_FAIL;
> > +}
> >  #if defined(TARGET_RISCV32)
> >  target_ulong pte = ldl_phys(cs->as, pte_addr);
> >  #elif defined(TARGET_RISCV64)
> > @@ -413,8 +419,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, 
> > int size,
> >  (ret == TRANSLATE_SUCCESS) &&
> >  !pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type,
> >  mode)) {
> > +ret = TRANSLATE_PMP_FAIL;
> > +}
> > +if (ret == TRANSLATE_PMP_FAIL) {
> >  pmp_violation = true;
> > -ret = TRANSLATE_FAIL;
> >  }
> >  if (ret == TRANSLATE_SUCCESS) {
> >  tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
> > --
> > 2.17.1
> >
> >



Re: [Qemu-devel] [PATCH v6] ssh: switch from libssh2 to libssh

2019-06-05 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20190605213654.9785-1-ptosc...@redhat.com/



Hi,

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

Message-id: 20190605213654.9785-1-ptosc...@redhat.com
Type: series
Subject: [Qemu-devel] [PATCH v6] ssh: switch from libssh2 to libssh

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

Switched to a new branch 'test'
abef817 ssh: switch from libssh2 to libssh

=== OUTPUT BEGIN ===
WARNING: Block comments use a leading /* on a separate line
#68: FILE: block/ssh.c:46:
+/* TRACE_LIBSSH= enables tracing in libssh itself.

WARNING: Block comments use a leading /* on a separate line
#95: FILE: block/ssh.c:64:
+/* File attributes at open.  We try to keep the .size field

WARNING: Block comments use a leading /* on a separate line
#484: FILE: block/ssh.c:491:
+/* Try to authenticate with publickey, using the ssh-agent

WARNING: Block comments use a leading /* on a separate line
#553: FILE: block/ssh.c:662:
+/* Try to disable the Nagle algorithm on TCP sockets to reduce latency,

WARNING: Block comments use a leading /* on a separate line
#575: FILE: block/ssh.c:679:
+/* Make sure we are in blocking mode during the connection and

WARNING: Block comments use a leading /* on a separate line
#895: FILE: block/ssh.c:1062:
+/* The size of SFTP packets is limited to 32K bytes, so limit

WARNING: line over 80 characters
#947: FILE: block/ssh.c:1135:
+trace_ssh_write_buf(buf, end_of_vec - buf, MIN(end_of_vec - buf, 
131072));

WARNING: Block comments use a leading /* on a separate line
#948: FILE: block/ssh.c:1136:
+/* Avoid too large data packets, as libssh currently does not

ERROR: Hex numbers must be prefixed with '0x'
#1122: FILE: block/trace-events:185:
+ssh_auth_methods(int methods) "auth methods=%x"

total: 1 errors, 8 warnings, 1175 lines checked

Commit abef817e4e8f (ssh: switch from libssh2 to libssh) has style problems, 
please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190605213654.9785-1-ptosc...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] Deprecation policy and build dependencies

2019-06-05 Thread Eric Blake
On 6/5/19 3:49 PM, Eduardo Habkost wrote:
> On Wed, Jun 05, 2019 at 03:42:39PM -0500, Eric Blake wrote:
>> On 6/5/19 3:13 PM, Eduardo Habkost wrote:
>>
 IOW, I don't think RHEL-7 support as a build platform blocks us from
 dropping py2. We merely need to tweak our build platforms doc to clarify
 our intent wrt add-on yum repos.
>>>
>>> If we clarify the docs in QEMU 4.1, is there anything that
>>> prevents us from removing Python 2 support in QEMU 4.1 too?
>>
>> My take (but not definitive): if we have any CI setups that are testing
>> RHEL 7 without software collections and/or EPEL, then save Python 2
>> removal for 4.2 to give us time to update CI setups. But if all of our
>> CI setups are already fine, and we clarify the docs, then I'm all for
>> getting rid of Python 2 support in 4.1.
> 
> If we do this soon, CI system owners will have at least 9 weeks
> to fix them before 4.1.0 is released.
> 
>>
>> Similarly, if we are going to outlaw in-tree builds, let's get that done
>> in 4.1 instead of waiting yet another release.
> 
> I'm missing the context on this.  Is this from a separate discussion?

Yes, separate threads (for example, this one:
https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg02553.html),
but related in that it is a build change that would affect existing
development and CI. If we're going to make life harder by pulling the
plug on old ways, we might as well pull the plug on multiple things at once.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v6] ssh: switch from libssh2 to libssh

2019-06-05 Thread Pino Toscano
Rewrite the implementation of the ssh block driver to use libssh instead
of libssh2.  The libssh library has various advantages over libssh2:
- easier API for authentication (for example for using ssh-agent)
- easier API for known_hosts handling
- supports newer types of keys in known_hosts

Use APIs/features available in libssh 0.8 conditionally, to support
older versions (which are not recommended though).

Signed-off-by: Pino Toscano 
---

Changes from v5:
- adapt to newer tracing APIs
- disable ssh compression (mimic what libssh2 does by default)
- use build time checks for libssh 0.8, and use newer APIs directly

Changes from v4:
- fix wrong usages of error_setg/session_error_setg/sftp_error_setg
- fix few return code checks
- remove now-unused parameters in few internal functions
- allow authentication with "none" method
- switch to unsigned int for the port number
- enable TCP_NODELAY on the socket
- fix one reference error message in iotest 207

Changes from v3:
- fix socket cleanup in connect_to_ssh()
- add comments about the socket cleanup
- improve the error reporting (closer to what was with libssh2)
- improve EOF detection on sftp_read()

Changes from v2:
- used again an own fd
- fixed co_yield() implementation

Changes from v1:
- fixed jumbo packets writing
- fixed missing 'err' assignment
- fixed commit message

 block/Makefile.objs|   6 +-
 block/ssh.c| 610 +++--
 block/trace-events |  14 +-
 configure  |  62 ++--
 tests/qemu-iotests/207.out |   2 +-
 5 files changed, 351 insertions(+), 343 deletions(-)

diff --git a/block/Makefile.objs b/block/Makefile.objs
index ae11605c9f..bf01429dd5 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -31,7 +31,7 @@ block-obj-$(CONFIG_CURL) += curl.o
 block-obj-$(CONFIG_RBD) += rbd.o
 block-obj-$(CONFIG_GLUSTERFS) += gluster.o
 block-obj-$(CONFIG_VXHS) += vxhs.o
-block-obj-$(CONFIG_LIBSSH2) += ssh.o
+block-obj-$(CONFIG_LIBSSH) += ssh.o
 block-obj-y += accounting.o dirty-bitmap.o
 block-obj-y += write-threshold.o
 block-obj-y += backup.o
@@ -52,8 +52,8 @@ rbd.o-libs := $(RBD_LIBS)
 gluster.o-cflags   := $(GLUSTERFS_CFLAGS)
 gluster.o-libs := $(GLUSTERFS_LIBS)
 vxhs.o-libs:= $(VXHS_LIBS)
-ssh.o-cflags   := $(LIBSSH2_CFLAGS)
-ssh.o-libs := $(LIBSSH2_LIBS)
+ssh.o-cflags   := $(LIBSSH_CFLAGS)
+ssh.o-libs := $(LIBSSH_LIBS)
 block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o
 block-obj-$(if $(CONFIG_DMG),m,n) += $(block-obj-dmg-bz2-y)
 dmg-bz2.o-libs := $(BZIP2_LIBS)
diff --git a/block/ssh.c b/block/ssh.c
index 12fd4f39e8..ce2363a471 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -24,8 +24,8 @@
 
 #include "qemu/osdep.h"
 
-#include 
-#include 
+#include 
+#include 
 
 #include "block/block_int.h"
 #include "block/qdict.h"
@@ -43,14 +43,13 @@
 #include "qapi/qobject-output-visitor.h"
 #include "trace.h"
 
-/*
- * TRACE_LIBSSH2= enables tracing in libssh2 itself.  Note
- * that this requires that libssh2 was specially compiled with the
- * `./configure --enable-debug' option, so most likely you will have
- * to compile it yourself.  The meaning of  is described
- * here: http://www.libssh2.org/libssh2_trace.html
+/* TRACE_LIBSSH= enables tracing in libssh itself.
+ * The meaning of  is described here:
+ * http://api.libssh.org/master/group__libssh__log.html
  */
-#define TRACE_LIBSSH2 0 /* or try: LIBSSH2_TRACE_SFTP */
+#define TRACE_LIBSSH  0 /* see: SSH_LOG_* */
+
+#define HAVE_LIBSSH_0_8 (LIBSSH_VERSION_INT >= SSH_VERSION_INT(0, 8, 0))
 
 typedef struct BDRVSSHState {
 /* Coroutine. */
@@ -58,18 +57,14 @@ typedef struct BDRVSSHState {
 
 /* SSH connection. */
 int sock; /* socket */
-LIBSSH2_SESSION *session; /* ssh session */
-LIBSSH2_SFTP *sftp;   /* sftp session */
-LIBSSH2_SFTP_HANDLE *sftp_handle; /* sftp remote file handle */
+ssh_session session;  /* ssh session */
+sftp_session sftp;/* sftp session */
+sftp_file sftp_handle;/* sftp remote file handle */
 
-/* See ssh_seek() function below. */
-int64_t offset;
-bool offset_op_read;
-
-/* File attributes at open.  We try to keep the .filesize field
+/* File attributes at open.  We try to keep the .size field
  * updated if it changes (eg by writing at the end of the file).
  */
-LIBSSH2_SFTP_ATTRIBUTES attrs;
+sftp_attributes attrs;
 
 InetSocketAddress *inet;
 
@@ -89,7 +84,6 @@ static void ssh_state_init(BDRVSSHState *s)
 {
 memset(s, 0, sizeof *s);
 s->sock = -1;
-s->offset = -1;
 qemu_co_mutex_init(>lock);
 }
 
@@ -97,21 +91,20 @@ static void ssh_state_free(BDRVSSHState *s)
 {
 g_free(s->user);
 
+if (s->attrs) {
+sftp_attributes_free(s->attrs);
+}
 if (s->sftp_handle) {
-libssh2_sftp_close(s->sftp_handle);
+sftp_close(s->sftp_handle);
 }
 if 

Re: [Qemu-devel] [PATCH 3/4] BootLinuxConsoleTest: Run kerneltests BusyBox on Malta

2019-06-05 Thread Cleber Rosa
On Tue, May 21, 2019 at 01:19:09AM +0200, Philippe Mathieu-Daudé wrote:
> This tests boots a Linux kernel on a Malta machine up to a
> busybox shell on the serial console. Few commands are executed
> before halting the machine (via reboot).
> 
> We use the initrd cpio image from the kerneltests project:
> https://kerneltests.org/
> 
> If MIPS is a target being built, "make check-acceptance" will
> automatically include this test by the use of the "arch:mips" tags.
> 
> Alternatively, this test can be run using:
> 
>   $ avocado --show=console run -t arch:mips 
> tests/acceptance/boot_linux_console.py
>   [...]
>   console: Boot successful.
>   [...]
>   console: / # uname -a
>   console: Linux buildroot 4.5.0-2-4kc-malta #1 Debian 4.5.5-1 (2016-05-29) 
> mips GNU/Linux
>   console: / # reboot

This seems like an ordinary input on the console...

>   console: / # reboot: Restarting system
>

And this seems like a perfectly normal output from the called
command. But, I also noticed this:

console: cat /proc/cpuinfo
console: / # cat /proc/cpuinfo
console: system type: MIPS Malta

Which seems to indicate an erroneous echo behavior of the console.
Any hints?

> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  tests/acceptance/boot_linux_console.py | 49 ++
>  1 file changed, 49 insertions(+)
> 
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 1c330871c0..60ea240ab6 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -11,6 +11,7 @@
>  import os
>  import logging
>  import lzma
> +import gzip
>  import shutil
>  
>  from avocado_qemu import Test
> @@ -47,6 +48,11 @@ class BootLinuxConsole(Test):
>  fail = 'Failure message found in console: %s' % 
> failure_message
>  self.fail(fail)
>  
> +def exec_command_and_wait_for_pattern(self, command, success_message):
> +command += '\n'
> +self.vm.console_socket.sendall(command.encode())
> +self.wait_for_console_pattern(success_message)
> +
>  def extract_from_deb(self, deb, path):
>  """
>  Extracts a file from a deb package into the test workdir
> @@ -138,6 +144,49 @@ class BootLinuxConsole(Test):
>  console_pattern = 'Kernel command line: %s' % kernel_command_line
>  self.wait_for_console_pattern(console_pattern)
>  
> +def test_mips_malta_cpio(self):
> +"""
> +:avocado: tags=arch:mips
> +:avocado: tags=machine:malta
> +:avocado: tags=endian:big
> +"""
> +deb_url = ('http://snapshot.debian.org/archive/debian/'
> +   '20160601T041800Z/pool/main/l/linux/'
> +   'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb')
> +deb_hash = 'a3c84f3e88b54e06107d65a410d1d1e8e0f340f8'
> +deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
> +kernel_path = self.extract_from_deb(deb_path,
> +
> '/boot/vmlinux-4.5.0-2-4kc-malta')
> +initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
> +  '8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/'
> +  'mips/rootfs.cpio.gz')
> +initrd_hash = 'bf806e17009360a866bf537f6de66590de349a99'
> +initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
> +initrd_path = self.workdir + "rootfs.cpio"
> +
> +with gzip.open(initrd_path_gz, 'rb') as f_in:
> +with open(initrd_path, 'wb') as f_out:
> +shutil.copyfileobj(f_in, f_out)

The last four lines can be replaced by:

initrd_path = archive.extract(initrd_path_gz,
  os.path.join(self.workdir, "rootfs.cpio"))

And with that, the gzip import can also be removed.

> +
> +self.vm.set_machine('malta')
> +self.vm.set_console()
> +kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
> +   + 'console=ttyS0 console=tty '
> +   + 'rdinit=/sbin/init noreboot')
> +self.vm.add_args('-kernel', kernel_path,
> + '-initrd', initrd_path,
> + '-append', kernel_command_line,
> + '-no-reboot')
> +self.vm.launch()
> +self.wait_for_console_pattern('Boot successful.')
> +
> +self.exec_command_and_wait_for_pattern('cat /proc/cpuinfo',
> +   'BogoMIPS')
> +self.exec_command_and_wait_for_pattern('uname -a',
> +   'Debian')
> +self.exec_command_and_wait_for_pattern('reboot',
> +   'reboot: Restarting system')
> +
>  def do_test_mips_malta32el_nanomips(self, kernel_url, kernel_hash):
>  kernel_path_xz = 

[Qemu-devel] Fwd: [j...@sing.id.au: atomic failures on qemu-system-riscv64]

2019-06-05 Thread Marco Peereboom
Joel is on vacation so here it is again.

> Begin forwarded message:
> 
> From: Alistair Francis 
> Subject: Re: [j...@sing.id.au: atomic failures on qemu-system-riscv64]
> Date: June 5, 2019 at 7:19:53 PM GMT+1
> To: "j...@sing.id.au" , "pal...@sifive.com" 
> 
> Cc: "ma...@decred.org" , "m...@carlosedp.com" 
> 
> 
> On Fri, 2019-05-31 at 03:21 +1000, Joel Sing wrote:
>> I've just sent this to qemu-ri...@nongnu.org - forwarding for
>> visibility...
> 
> Hello Joel,
> 
> Can you please send this to the QEMU mailing list?
> https://wiki.qemu.org/Contribute/MailingLists
> 
>> 
>> - Forwarded message from Joel Sing  -
>> 
>> Date: Fri, 31 May 2019 03:20:03 +1000
>> From: Joel Sing 
>> To: qemu-ri...@nongnu.org
>> Subject: atomic failures on qemu-system-riscv64
>> User-Agent: Mutt/1.10.1 (2018-07-13)
>> 
>> While working on a Go (www.golang.org) port for riscv, I've run
>> into issues with atomics (namely LR/SC) on qemu-system-riscv64.
>> There are several reproducers for this problem including (using
>> gcc builtin atomics):
>> 
>>  https://gist.github.com/4a6f656c/8433032a3f70893a278259f8108aad90
>> 
>> And a version using inline assembly:
>> 
>>  https://gist.github.com/4a6f656c/d883091f5ca811822720213be343a75a
>> 
>> Depending on the qemu configuration the number of threads may
>> need increasing (to force context switching) and/or run in a
>> loop. Go's sync/atomic tests also fail regularly.
>> 
>> Having dug into the qemu code, what I believe is happening is
>> along the lines of the following:
>> 
>> 1. Thread 1 runs and executes an LR - this assigns an address
>>   to load_res and a value to load_val (say 1).
>> 
>> 2. A context switch occurs and thread 2 is now run - it runs
>>   an LR and SC on the same address modifying the stored value.
>>   Another LR is executed loading load_val with the current
>>   value (say 3).
>> 
>> 3. A context switch occurs and thread 1 is now run again, it
>>   continues on its LR/SC sequence and now runs the SC instruction.
>>   This is based on the assumption that it had a reservation
>>   and the SC will fail if the memory has changed. The underlying
>>   implementation of SC is a cmpxchg with the value in load_val
>>   - this no longer has the original value and hence successfully
>>   compares (as does the tcg_gen_setcond_tl() between the returned
>>   value and load_val) thus the SC succeeds when it should not.
>> 
>> The diff below clears load_res when the mode changes - with this
>> applied the reproducers work correctly, as do Go's atomic tests.
>> I'm not sure this "fix" is 100% correct, but it certainly verifies
>> where the problem lies. It does also fall inline with the RISCV
>> spec:
>> 
>> "The SC must fail if there is an observable memory access from
>> another hart to the address, or if there is an intervening context
>> switch on this hart, or if in the meantime the hart executed a
>> privileged exception-return instruction."
>> 
>> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>> index b17f169681..9875b8e5d3 100644
>> --- a/target/riscv/cpu_helper.c
>> +++ b/target/riscv/cpu_helper.c
>> @@ -113,6 +113,8 @@ void riscv_cpu_set_mode(CPURISCVState *env,
>> target_ulong newpriv)
>> }
>> /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>> env->priv = newpriv;
>> +
>> +env->load_res = 0;
> 
> This looks ok to me, I'll read the spec to double check though. Do you
> mind adding a comment in the code as to why this is required?
> 
> Alistair
> 
>> }
>> 
>> /* get_physical_address - get the physical address for this virtual
>> address
>> 
>> - End forwarded message -



signature.asc
Description: Message signed with OpenPGP


Re: [Qemu-devel] [PATCH v6 4/6] include/elf: Add defines related to notes for GNU systems

2019-06-05 Thread Aleksandar Markovic
On Jun 5, 2019 11:03 PM, "Richard Henderson" 
wrote:
>
> This is a collection of related defines for notes, copied
> from glibc's .  We're not going to use all of these
> right away, but it seemed foolish to cherry-pick only the
> ones we need now.
>

But you are doing exactly that: cherry-picking, but this time according to
some undisclosed criterium. Why don't you state your motivation in the
commit message in a clear way? Why only these items are chosen? Confusing
and confused.

Regards,
Aleksandar

> Signed-off-by: Richard Henderson 
> ---
>  include/elf.h | 48 
>  1 file changed, 48 insertions(+)
>
> diff --git a/include/elf.h b/include/elf.h
> index ea7708a4ea..6f3eada36f 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -1650,6 +1650,54 @@ typedef struct elf64_shdr {
>  #define NT_ARM_HW_WATCH 0x403   /* ARM hardware watchpoint
registers */
>  #define NT_ARM_SYSTEM_CALL  0x404   /* ARM system call number */
>
> +/* Defined note types for GNU systems.  */
> +
> +#define NT_GNU_ABI_TAG  1   /* ABI information */
> +#define NT_GNU_HWCAP2   /* Synthetic hwcap information */
> +#define NT_GNU_BUILD_ID 3   /* Build ID */
> +#define NT_GNU_GOLD_VERSION 4   /* Version of ld.gold */
> +#define NT_GNU_PROPERTY_TYPE_0  5   /* Program property */
> +
> +/* Values used in GNU .note.gnu.property notes
(NT_GNU_PROPERTY_TYPE_0).  */
> +
> +#define GNU_PROPERTY_STACK_SIZE 1
> +#define GNU_PROPERTY_NO_COPY_ON_PROTECTED   2
> +
> +#define GNU_PROPERTY_LOPROC 0xc000
> +#define GNU_PROPERTY_HIPROC 0xdfff
> +#define GNU_PROPERTY_LOUSER 0xe000
> +#define GNU_PROPERTY_HIUSER 0x
> +
> +#define GNU_PROPERTY_X86_ISA_1_USED 0xc000
> +#define GNU_PROPERTY_X86_ISA_1_NEEDED   0xc001
> +
> +#define GNU_PROPERTY_X86_ISA_1_486  (1U << 0)
> +#define GNU_PROPERTY_X86_ISA_1_586  (1U << 1)
> +#define GNU_PROPERTY_X86_ISA_1_686  (1U << 2)
> +#define GNU_PROPERTY_X86_ISA_1_SSE  (1U << 3)
> +#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4)
> +#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5)
> +#define GNU_PROPERTY_X86_ISA_1_SSSE3(1U << 6)
> +#define GNU_PROPERTY_X86_ISA_1_SSE4_1   (1U << 7)
> +#define GNU_PROPERTY_X86_ISA_1_SSE4_2   (1U << 8)
> +#define GNU_PROPERTY_X86_ISA_1_AVX  (1U << 9)
> +#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512F  (1U << 11)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16)
> +#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17)
> +
> +#define GNU_PROPERTY_X86_FEATURE_1_AND  0xc002
> +#define GNU_PROPERTY_X86_FEATURE_1_IBT  (1U << 0)
> +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK(1U << 1)
> +
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND  0xc000
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI  (1u << 0)
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC  (1u << 1)
> +
>  /*
>   * Physical entry point into the kernel.
>   *
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCHv4 4/6] RISC-V: Check PMP during Page Table Walks

2019-06-05 Thread Alistair Francis
On Thu, May 30, 2019 at 6:52 AM Hesham Almatary
 wrote:
>
> The PMP should be checked when doing a page table walk, and report access
> fault exception if the to-be-read PTE failed the PMP check.
>
> Suggested-by: Jonathan Behrens 
> Signed-off-by: Hesham Almatary 
> ---
>  target/riscv/cpu.h|  1 +
>  target/riscv/cpu_helper.c | 10 +-
>  2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index c17184f4e4..ab3ba3f15a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -94,6 +94,7 @@ enum {
>  #define PRIV_VERSION_1_09_1 0x00010901
>  #define PRIV_VERSION_1_10_0 0x00011000
>
> +#define TRANSLATE_PMP_FAIL 2
>  #define TRANSLATE_FAIL 1
>  #define TRANSLATE_SUCCESS 0
>  #define NB_MMU_MODES 4
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 5a1cd7cf96..00bc4f1712 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -211,6 +211,12 @@ restart:
>
>  /* check that physical address of PTE is legal */
>  target_ulong pte_addr = base + idx * ptesize;
> +
> +if (riscv_feature(env, RISCV_FEATURE_PMP) &&
> +!pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
> +1 << MMU_DATA_LOAD, PRV_S)) {

Shouldn't we be passing mode in here?

Alistair

> +return TRANSLATE_PMP_FAIL;
> +}
>  #if defined(TARGET_RISCV32)
>  target_ulong pte = ldl_phys(cs->as, pte_addr);
>  #elif defined(TARGET_RISCV64)
> @@ -413,8 +419,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
> size,
>  (ret == TRANSLATE_SUCCESS) &&
>  !pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type,
>  mode)) {
> +ret = TRANSLATE_PMP_FAIL;
> +}
> +if (ret == TRANSLATE_PMP_FAIL) {
>  pmp_violation = true;
> -ret = TRANSLATE_FAIL;
>  }
>  if (ret == TRANSLATE_SUCCESS) {
>  tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
> --
> 2.17.1
>
>



Re: [Qemu-devel] [PATCHv4 3/6] RISC-V: Check for the effective memory privilege mode during PMP checks

2019-06-05 Thread Alistair Francis
On Thu, May 30, 2019 at 6:52 AM Hesham Almatary
 wrote:
>
> The current PMP check function checks for env->priv which is not the effective
> memory privilege mode.
>
> For example, mstatus.MPRV could be set while executing in M-Mode, and in that
> case the privilege mode for the PMP check should be S-Mode rather than M-Mode
> (in env->priv) if mstatus.MPP == PRV_S.
>
> This patch passes the effective memory privilege mode to the PMP check.
> Functions that call the PMP check should pass the correct memory privilege 
> mode
> after reading mstatus' MPRV/MPP or hstatus.SPRV (if Hypervisor mode exists).
>
> Suggested-by: Alistair Francis 
> Signed-off-by: Hesham Almatary 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c | 10 +-
>  target/riscv/pmp.c|  6 +++---
>  target/riscv/pmp.h|  2 +-
>  3 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 7c7282c680..5a1cd7cf96 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -392,19 +392,27 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, 
> int size,
>  int prot;
>  bool pmp_violation = false;
>  int ret = TRANSLATE_FAIL;
> +int mode = mmu_idx;
>
>  qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
>__func__, address, access_type, mmu_idx);
>
>  ret = get_physical_address(env, , , address, access_type, 
> mmu_idx);
>
> +if (mode == PRV_M && access_type != MMU_INST_FETCH) {
> +if (get_field(env->mstatus, MSTATUS_MPRV)) {
> +mode = get_field(env->mstatus, MSTATUS_MPP);
> +}
> +}
> +
>  qemu_log_mask(CPU_LOG_MMU,
>"%s address=%" VADDR_PRIx " ret %d physical " 
> TARGET_FMT_plx
>" prot %d\n", __func__, address, ret, pa, prot);
>
>  if (riscv_feature(env, RISCV_FEATURE_PMP) &&
>  (ret == TRANSLATE_SUCCESS) &&
> -!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type)) {
> +!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type,
> +mode)) {
>  pmp_violation = true;
>  ret = TRANSLATE_FAIL;
>  }
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index b11c4ae22f..89170bc11d 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -229,7 +229,7 @@ static int pmp_is_in_range(CPURISCVState *env, int 
> pmp_index, target_ulong addr)
>   * Check if the address has required RWX privs to complete desired operation
>   */
>  bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> -target_ulong size, pmp_priv_t privs)
> +target_ulong size, pmp_priv_t privs, target_ulong mode)
>  {
>  int i = 0;
>  int ret = -1;
> @@ -265,7 +265,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
> addr,
>  }
>
>  allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> -if ((env->priv != PRV_M) || pmp_is_locked(env, i)) {
> +if ((mode != PRV_M) || pmp_is_locked(env, i)) {
>  allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
>  }
>
> @@ -281,7 +281,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
> addr,
>
>  /* No rule matched */
>  if (ret == -1) {
> -if (env->priv == PRV_M) {
> +if (mode == PRV_M) {
>  ret = 1; /* Privileged spec v1.10 states if no PMP entry matches 
> an
>* M-Mode access, the access succeeds */
>  } else {
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index 66790950eb..8e19793132 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -59,6 +59,6 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
> addr_index,
>  target_ulong val);
>  target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
>  bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> -target_ulong size, pmp_priv_t priv);
> +target_ulong size, pmp_priv_t priv, target_ulong mode);
>
>  #endif
> --
> 2.17.1
>
>



[Qemu-devel] [PATCH v6 2/6] linux-user: Validate mmap/mprotect prot value

2019-06-05 Thread Richard Henderson
The kernel will return -EINVAL for bits set in the prot argument
that are unknown or invalid.  Previously we were simply cropping
out the bits that we care about.

Introduce validate_prot_to_pageflags to perform this check in a
single place between the two syscalls.  Differentiate between
the target and host versions of prot.  Compute the qemu internal
page_flags value at the same time.

Signed-off-by: Richard Henderson 
---
 linux-user/mmap.c | 106 --
 1 file changed, 75 insertions(+), 31 deletions(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index af41339d57..3117f57fd8 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -61,11 +61,38 @@ void mmap_fork_end(int child)
 pthread_mutex_unlock(_mutex);
 }
 
+/*
+ * Validate target prot bitmask.
+ * Return the prot bitmask for the host in *HOST_PROT.
+ * Return 0 if the target prot bitmask is invalid, otherwise
+ * the internal qemu page_flags (which will include PAGE_VALID).
+ */
+static int validate_prot_to_pageflags(int *host_prot, int prot)
+{
+int valid = PROT_READ | PROT_WRITE | PROT_EXEC | TARGET_PROT_SEM;
+int page_flags = (prot & PAGE_BITS) | PAGE_VALID;
+
+/*
+ * For the host, we need not pass anything except read/write/exec.
+ * While PROT_SEM is allowed by all hosts, it is also ignored, so
+ * don't bother transforming guest bit to host bit.  Any other
+ * target-specific prot bits will not be understood by the host
+ * and will need to be encoded into page_flags for qemu emulation.
+ *
+ * TODO: We do not actually have to map guest pages as executable,
+ * since they will not be directly executed by the host.  We only
+ * need to remember exec within page_flags.
+ */
+*host_prot = prot & (PROT_READ | PROT_WRITE | PROT_EXEC);
+
+return prot & ~valid ? 0 : page_flags;
+}
+
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
-int target_mprotect(abi_ulong start, abi_ulong len, int prot)
+int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
 {
 abi_ulong end, host_start, host_end, addr;
-int prot1, ret;
+int prot1, ret, page_flags, host_prot;
 
 #ifdef DEBUG_MMAP
 printf("mprotect: start=0x" TARGET_ABI_FMT_lx
@@ -75,56 +102,65 @@ int target_mprotect(abi_ulong start, abi_ulong len, int 
prot)
prot & PROT_EXEC ? 'x' : '-');
 #endif
 
-if ((start & ~TARGET_PAGE_MASK) != 0)
+if ((start & ~TARGET_PAGE_MASK) != 0) {
 return -TARGET_EINVAL;
+}
+page_flags = validate_prot_to_pageflags(_prot, target_prot);
+if (!page_flags) {
+return -TARGET_EINVAL;
+}
 len = TARGET_PAGE_ALIGN(len);
 end = start + len;
 if (!guest_range_valid(start, len)) {
 return -TARGET_ENOMEM;
 }
-prot &= PROT_READ | PROT_WRITE | PROT_EXEC;
-if (len == 0)
+if (len == 0) {
 return 0;
+}
 
 mmap_lock();
 host_start = start & qemu_host_page_mask;
 host_end = HOST_PAGE_ALIGN(end);
 if (start > host_start) {
 /* handle host page containing start */
-prot1 = prot;
-for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
+prot1 = host_prot;
+for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
 prot1 |= page_get_flags(addr);
 }
 if (host_end == host_start + qemu_host_page_size) {
-for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
+for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
 prot1 |= page_get_flags(addr);
 }
 end = host_end;
 }
-ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & 
PAGE_BITS);
-if (ret != 0)
+ret = mprotect(g2h(host_start), qemu_host_page_size,
+   prot1 & PAGE_BITS);
+if (ret != 0) {
 goto error;
+}
 host_start += qemu_host_page_size;
 }
 if (end < host_end) {
-prot1 = prot;
-for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
+prot1 = host_prot;
+for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
 prot1 |= page_get_flags(addr);
 }
-ret = mprotect(g2h(host_end - qemu_host_page_size), 
qemu_host_page_size,
-   prot1 & PAGE_BITS);
-if (ret != 0)
+ret = mprotect(g2h(host_end - qemu_host_page_size),
+   qemu_host_page_size, prot1 & PAGE_BITS);
+if (ret != 0) {
 goto error;
+}
 host_end -= qemu_host_page_size;
 }
 
 /* handle the pages in the middle */
 if (host_start < host_end) {
-ret = mprotect(g2h(host_start), host_end - host_start, prot);
-if (ret != 0)
+ret = mprotect(g2h(host_start), host_end - host_start, host_prot);
+if (ret != 0) {
 goto error;
+}
 }
-

Re: [Qemu-devel] [PATCH 1/2] BootLinuxConsoleTest: Do not log empty lines

2019-06-05 Thread Aleksandar Markovic
On May 21, 2019 12:07 AM, "Philippe Mathieu-Daudé"  wrote:
>
> Avoid to log empty lines in console debug logs.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---

Acked-by: Aleksandar Markovic 

>  tests/acceptance/boot_linux_console.py | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/tests/acceptance/boot_linux_console.py
b/tests/acceptance/boot_linux_console.py
> index d5c500ea30..f593f3858e 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -37,8 +37,10 @@ class BootLinuxConsole(Test):
>  console = self.vm.console_socket.makefile()
>  console_logger = logging.getLogger('console')
>  while True:
> -msg = console.readline()
> -console_logger.debug(msg.strip())
> +msg = console.readline().strip()
> +if not msg:
> +continue
> +console_logger.debug(msg)
>  if success_message in msg:
>  break
>  if failure_message in msg:
> --
> 2.19.1
>
>


Re: [Qemu-devel] Headers without multiple inclusion guards

2019-06-05 Thread Alistair Francis
On Tue, May 28, 2019 at 11:13 AM Markus Armbruster  wrote:
>
> We have a bunch of headers without multiple inclusion guards.  Some are
> clearly intentional, some look accidental.  Too many for me to find out
> by examining each of them, so I'm asking their maintainers.
>
> Why do I ask?  I'd like to mark the intentional ones and fix the
> accidental ones, so they don't flunk "make check-headers" from "[RFC v4
> 0/7] Baby steps towards saner headers" just because they lack multiple
> inclusion guards.
>

Sorry for the delay I have been on holidays. I think the ARM ones have
all been covered by Peter, here is some info on the RISC-V includes.



> linux-user/riscv/sockbits.h
> linux-user/riscv/syscall_nr.h
> linux-user/riscv/target_syscall.h
> linux-user/riscv/termbits.h

I'm not sure here, it looks like all targets have the same guards, so
just follow what the others do here.



> target/riscv/cpu_bits.h
> target/riscv/cpu_user.h

These should have guards

> target/riscv/helper.h

Intentional

> target/riscv/instmap.h

I think this should have a guard.

Alistair



[Qemu-devel] [PATCH v6 3/6] linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI

2019-06-05 Thread Richard Henderson
Transform the prot bit to a qemu internal page bit, and save
it in the page tables.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h |  2 ++
 linux-user/syscall_defs.h  |  4 
 linux-user/mmap.c  | 16 
 target/arm/translate-a64.c |  6 +++---
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index da07ce311f..e65530acae 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -249,6 +249,8 @@ extern intptr_t qemu_host_page_mask;
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
 #define PAGE_RESERVED  0x0020
 #endif
+/* Target-specific bits that will be used via page_get_flags().  */
+#define PAGE_TARGET_1  0x0080
 
 #if defined(CONFIG_USER_ONLY)
 void page_dump(FILE *f);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 7f141f699c..9a8a14e81e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1097,6 +1097,10 @@ struct target_winsize {
 #define TARGET_PROT_SEM 0x08
 #endif
 
+#ifdef TARGET_AARCH64
+#define TARGET_PROT_BTI 0x10
+#endif
+
 /* Common */
 #define TARGET_MAP_SHARED  0x01/* Share changes */
 #define TARGET_MAP_PRIVATE 0x02/* Changes are private */
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 3117f57fd8..def64a41d5 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -85,6 +85,22 @@ static int validate_prot_to_pageflags(int *host_prot, int 
prot)
  */
 *host_prot = prot & (PROT_READ | PROT_WRITE | PROT_EXEC);
 
+#ifdef TARGET_AARCH64
+/*
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
+ * Since this is the unusual case, don't bother checking unless
+ * the bit has been requested.  If set and valid, record the bit
+ * within QEMU's page_flags as PAGE_TARGET_1.
+ */
+if (prot & TARGET_PROT_BTI) {
+ARMCPU *cpu = ARM_CPU(thread_cpu);
+if (cpu_isar_feature(aa64_bti, cpu)) {
+valid |= TARGET_PROT_BTI;
+page_flags |= PAGE_TARGET_1;
+}
+}
+#endif
+
 return prot & ~valid ? 0 : page_flags;
 }
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 092f0df3c4..5043344eba 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14115,10 +14115,10 @@ static void disas_data_proc_simd_fp(DisasContext *s, 
uint32_t insn)
  */
 static bool is_guarded_page(CPUARMState *env, DisasContext *s)
 {
-#ifdef CONFIG_USER_ONLY
-return false;  /* FIXME */
-#else
 uint64_t addr = s->base.pc_first;
+#ifdef CONFIG_USER_ONLY
+return page_get_flags(addr) & PAGE_TARGET_1;
+#else
 int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
 unsigned int index = tlb_index(env, mmu_idx, addr);
 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
-- 
2.17.1




[Qemu-devel] [PATCH v6 6/6] tests/tcg/aarch64: Add bti smoke test

2019-06-05 Thread Richard Henderson
This will build with older toolchains, without the upstream support
for -mbranch-protection.  Such a toolchain will produce a warning
in such cases,

ld: warning: /tmp/ccyZt0kq.o: unsupported GNU_PROPERTY_TYPE (5) \
type: 0xc000

but the still places the note at the correct location in the binary
for processing by the runtime loader.

Signed-off-by: Richard Henderson 
---
 tests/tcg/aarch64/bti-1.c | 77 +++
 tests/tcg/aarch64/bti-crt.inc.c   | 69 +++
 tests/tcg/aarch64/Makefile.target |  3 ++
 3 files changed, 149 insertions(+)
 create mode 100644 tests/tcg/aarch64/bti-1.c
 create mode 100644 tests/tcg/aarch64/bti-crt.inc.c

diff --git a/tests/tcg/aarch64/bti-1.c b/tests/tcg/aarch64/bti-1.c
new file mode 100644
index 00..2aee57ea7a
--- /dev/null
+++ b/tests/tcg/aarch64/bti-1.c
@@ -0,0 +1,77 @@
+/*
+ * Branch target identification, basic notskip cases.
+ */
+
+#include "bti-crt.inc.c"
+
+/*
+ * Work around lack of -mbranch-protection=standard in older toolchains.
+ * The signal handler is invoked by the kernel with PSTATE.BTYPE=2, which
+ * means that the handler must begin with a marker like BTI_C.
+ */
+asm("skip2_sigill1:\n\
+   hint#34\n\
+   b   skip2_sigill2\n\
+.type skip2_sigill1,%function\n\
+.size skip2_sigill1,8");
+
+extern void skip2_sigill1(int sig, siginfo_t *info, ucontext_t *uc)
+__attribute__((visibility("hidden")));
+
+static void __attribute__((used))
+skip2_sigill2(int sig, siginfo_t *info, ucontext_t *uc)
+{
+uc->uc_mcontext.pc += 8;
+uc->uc_mcontext.pstate = 1;
+}
+
+#define NOP   "nop"
+#define BTI_N "hint #32"
+#define BTI_C "hint #34"
+#define BTI_J "hint #36"
+#define BTI_JC"hint #38"
+
+#define BTYPE_1(DEST) \
+asm("mov %0,#1; adr x16, 1f; br x16; 1: " DEST "; mov %0,#0" \
+: "=r"(skipped) : : "x16")
+
+#define BTYPE_2(DEST) \
+asm("mov %0,#1; adr x16, 1f; blr x16; 1: " DEST "; mov %0,#0" \
+: "=r"(skipped) : : "x16", "x30")
+
+#define BTYPE_3(DEST) \
+asm("mov %0,#1; adr x15, 1f; br x15; 1: " DEST "; mov %0,#0" \
+: "=r"(skipped) : : "x15")
+
+#define TEST(WHICH, DEST, EXPECT) \
+do { WHICH(DEST); fail += skipped ^ EXPECT; } while (0)
+
+
+int main()
+{
+int fail = 0;
+int skipped;
+
+/* Signal-like with SA_SIGINFO.  */
+signal_info(SIGILL, skip2_sigill1);
+
+TEST(BTYPE_1, NOP, 1);
+TEST(BTYPE_1, BTI_N, 1);
+TEST(BTYPE_1, BTI_C, 0);
+TEST(BTYPE_1, BTI_J, 0);
+TEST(BTYPE_1, BTI_JC, 0);
+
+TEST(BTYPE_2, NOP, 1);
+TEST(BTYPE_2, BTI_N, 1);
+TEST(BTYPE_2, BTI_C, 0);
+TEST(BTYPE_2, BTI_J, 1);
+TEST(BTYPE_2, BTI_JC, 0);
+
+TEST(BTYPE_3, NOP, 1);
+TEST(BTYPE_3, BTI_N, 1);
+TEST(BTYPE_3, BTI_C, 1);
+TEST(BTYPE_3, BTI_J, 0);
+TEST(BTYPE_3, BTI_JC, 0);
+
+return fail;
+}
diff --git a/tests/tcg/aarch64/bti-crt.inc.c b/tests/tcg/aarch64/bti-crt.inc.c
new file mode 100644
index 00..bb363853de
--- /dev/null
+++ b/tests/tcg/aarch64/bti-crt.inc.c
@@ -0,0 +1,69 @@
+/*
+ * Minimal user-environment for testing BTI.
+ *
+ * Normal libc is not built with BTI support enabled, and so could
+ * generate a BTI TRAP before ever reaching main.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+int main(void);
+
+void _start(void)
+{
+exit(main());
+}
+
+void exit(int ret)
+{
+register int x0 __asm__("x0") = ret;
+register int x8 __asm__("x8") = __NR_exit;
+
+asm volatile("svc #0" : : "r"(x0), "r"(x8));
+__builtin_unreachable();
+}
+
+/*
+ * Irritatingly, the user API struct sigaction does not match the
+ * kernel API struct sigaction.  So for simplicity, isolate the
+ * kernel ABI here, and make this act like signal.
+ */
+void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *))
+{
+struct kernel_sigaction {
+void (*handler)(int, siginfo_t *, ucontext_t *);
+unsigned long flags;
+unsigned long restorer;
+unsigned long mask;
+} sa = { fn, SA_SIGINFO, 0, 0 };
+
+register int x0 __asm__("x0") = sig;
+register void *x1 __asm__("x1") = 
+register void *x2 __asm__("x2") = 0;
+register int x3 __asm__("x3") = sizeof(unsigned long);
+register int x8 __asm__("x8") = __NR_rt_sigaction;
+
+asm volatile("svc #0"
+ : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
+}
+
+/*
+ * Create the PT_NOTE that will enable BTI in the page tables.
+ * This will be created by the compiler with -mbranch-protection=standard,
+ * but as of 2019-03-29, this is has not been committed to gcc mainline.
+ * This will probably be in GCC10.
+ */
+asm(".section .note.gnu.property,\"a\"\n\
+   .align  3\n\
+   .long   4\n\
+.long  16\n\
+.long  5\n\
+.string\"GNU\"\n\
+   .long   0xc000\n\
+   .long   4\n\
+   .long   1\n\
+.align  3\n\
+   .previous");
diff --git a/tests/tcg/aarch64/Makefile.target 

[Qemu-devel] [PATCH v6 1/6] linux-user/aarch64: Reset btype for syscalls and signals

2019-06-05 Thread Richard Henderson
The value of btype for syscalls is CONSTRAINED UNPREDICTABLE,
so we need to make sure that the value is 0 before clone,
fork, or syscall return.

The kernel sets btype for the signal handler as if for a call.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/cpu_loop.c |  7 +++
 linux-user/aarch64/signal.c   | 10 --
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 2f2f63e3e8..1f68b13168 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -86,6 +86,13 @@ void cpu_loop(CPUARMState *env)
 
 switch (trapnr) {
 case EXCP_SWI:
+/*
+ * The state of BTYPE on syscall entry is CONSTRAINED
+ * UNPREDICTABLE.  The real kernel will need to tidy this up
+ * as well.  Do this before syscalls so that the value is
+ * correct on return from syscall (especially clone & fork).
+ */
+env->btype = 0;
 ret = do_syscall(env,
  env->xregs[8],
  env->xregs[0],
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index f84a9cf28a..5605d404b3 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -506,10 +506,16 @@ static void target_setup_frame(int usig, struct 
target_sigaction *ka,
 + offsetof(struct target_rt_frame_record, tramp);
 }
 env->xregs[0] = usig;
-env->xregs[31] = frame_addr;
 env->xregs[29] = frame_addr + fr_ofs;
-env->pc = ka->_sa_handler;
 env->xregs[30] = return_addr;
+env->xregs[31] = frame_addr;
+env->pc = ka->_sa_handler;
+
+/* Invoke the signal handler as if by indirect call.  */
+if (cpu_isar_feature(aa64_bti, arm_env_get_cpu(env))) {
+env->btype = 2;
+}
+
 if (info) {
 tswap_siginfo(>info, info);
 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
-- 
2.17.1




[Qemu-devel] [PATCH v6 5/6] linux-user: Parse NT_GNU_PROPERTY_TYPE_0 notes

2019-06-05 Thread Richard Henderson
For aarch64, this includes the GNU_PROPERTY_AARCH64_FEATURE_1_BTI bit,
which indicates that the image should be mapped with guarded pages.

Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 83 +++-
 1 file changed, 75 insertions(+), 8 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a57b7049dd..1a12c60a33 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2253,7 +2253,7 @@ static void load_elf_image(const char *image_name, int 
image_fd,
 struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
 struct elf_phdr *phdr;
 abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
-int i, retval;
+int i, retval, prot_exec = PROT_EXEC;
 const char *errmsg;
 
 /* First of all, some simple consistency checks */
@@ -2288,17 +2288,78 @@ static void load_elf_image(const char *image_name, int 
image_fd,
 loaddr = -1, hiaddr = 0;
 info->alignment = 0;
 for (i = 0; i < ehdr->e_phnum; ++i) {
-if (phdr[i].p_type == PT_LOAD) {
-abi_ulong a = phdr[i].p_vaddr - phdr[i].p_offset;
+struct elf_phdr *eppnt = phdr + i;
+
+if (eppnt->p_type == PT_LOAD) {
+abi_ulong a = eppnt->p_vaddr - eppnt->p_offset;
 if (a < loaddr) {
 loaddr = a;
 }
-a = phdr[i].p_vaddr + phdr[i].p_memsz;
+a = eppnt->p_vaddr + eppnt->p_memsz;
 if (a > hiaddr) {
 hiaddr = a;
 }
 ++info->nsegs;
-info->alignment |= phdr[i].p_align;
+info->alignment |= eppnt->p_align;
+} else if (eppnt->p_type == PT_NOTE) {
+#ifdef TARGET_AARCH64
+/*
+ * Process NT_GNU_PROPERTY_TYPE_0.
+ *
+ * TODO: The only item that is AArch64 specific is the
+ * GNU_PROPERTY_AARCH64_FEATURE_1_AND processing at the end.
+ * If we were to ever process GNU_PROPERTY_X86_*, all of the
+ * code through checking the gnu0 magic number is sharable.
+ * But for now, since this *is* only used by AArch64, don't
+ * process the note elsewhere.
+ */
+const uint32_t gnu0_magic = const_le32('G' | 'N' << 8 | 'U' << 16);
+uint32_t note[7];
+
+/*
+ * The note contents are 7 words, but depending on LP64 vs ILP32
+ * there may be an 8th padding word at the end.  Check for and
+ * read the minimum size.  Further checks below will validate
+ * that the sizes of everything involved are as we expect.
+ */
+if (eppnt->p_filesz < sizeof(note)) {
+continue;
+}
+if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
+memcpy(note, bprm_buf + eppnt->p_offset, sizeof(note));
+} else {
+retval = pread(image_fd, note, sizeof(note), eppnt->p_offset);
+if (retval != sizeof(note)) {
+goto exit_perror;
+}
+}
+#ifdef BSWAP_NEEDED
+for (i = 0; i < ARRAY_SIZE(note); ++i) {
+bswap32s(note + i);
+}
+#endif
+/*
+ * Check that this is a NT_GNU_PROPERTY_TYPE_0 note.
+ * Again, descsz includes padding.  Full size validation
+ * awaits checking the final payload.
+ */
+if (note[0] != 4 ||   /* namesz */
+note[1] < 12 ||   /* descsz */
+note[2] != NT_GNU_PROPERTY_TYPE_0 ||  /* type */
+note[3] != gnu0_magic) {  /* name */
+continue;
+}
+/*
+ * Check for the BTI feature.  If present, this indicates
+ * that all the executable pages of the binary should be
+ * mapped with PROT_BTI, so that branch targets are enforced.
+ */
+if (note[4] == GNU_PROPERTY_AARCH64_FEATURE_1_AND &&
+note[5] == 4 &&
+(note[6] & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
+prot_exec |= TARGET_PROT_BTI;
+}
+#endif /* TARGET_AARCH64 */
 }
 }
 
@@ -2358,9 +2419,15 @@ static void load_elf_image(const char *image_name, int 
image_fd,
 abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len;
 int elf_prot = 0;
 
-if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
-if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
-if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
+if (eppnt->p_flags & PF_R) {
+elf_prot |= PROT_READ;
+}
+if (eppnt->p_flags & PF_W) {
+elf_prot |= PROT_WRITE;
+}
+if (eppnt->p_flags & PF_X) {
+elf_prot |= prot_exec;
+

[Qemu-devel] [PULL SUBSYSTEM s390x 21/33] s390x/tcg: Implement VECTOR LOAD LENGTHENED

2019-06-05 Thread David Hildenbrand
Take care of reading/indicating the 32-bit elements.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c | 19 ++
 target/s390x/vec_fpu_helper.c   | 35 +
 4 files changed, 58 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 10a9cb39b6..cb25141ffe 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -278,6 +278,8 @@ DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, 
cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfd64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index f77aa41253..5afdb36aec 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1230,6 +1230,8 @@
 F(0xe7e5, VFD, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
 /* VECTOR LOAD FP INTEGER */
 F(0xe7c7, VFI, VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR LOAD LENGTHENED */
+F(0xe7c4, VFLL,VRR_a, V,   0, 0, 0, 0, vfll, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 59d8b971c0..a25985e5c9 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2679,3 +2679,22 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps 
*o)
deposit32(m4, 4, 4, erm), fn);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfll(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m3);
+const uint8_t m4 = get_field(s->fields, m4);
+gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vfll32;
+
+if (fpf != FPF_SHORT || extract32(m4, 0, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m4, 3, 1)) {
+fn = gen_helper_gvec_vfll32s;
+}
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2), cpu_env,
+   0, fn);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index bdcafc6738..f5b7fdf871 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -409,3 +409,38 @@ void HELPER(gvec_vfi64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vop64_2(v1, v2, env, true, XxC, erm, vfi64, GETPC());
 }
+
+static void vfll32(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+   bool s, uintptr_t retaddr)
+{
+uint8_t vxc, vec_exc = 0;
+S390Vector tmp = {};
+int i;
+
+for (i = 0; i < 2; i++) {
+/* load from even element */
+const float32 a = s390_vec_read_element32(v2, i * 2);
+const uint64_t ret = float32_to_float64(a, >fpu_status);
+
+s390_vec_write_element64(, i, ret);
+/* indicate the source element */
+vxc = check_ieee_exc(env, i * 2, false, _exc);
+if (s || vxc) {
+break;
+}
+}
+handle_ieee_exc(env, vxc, vec_exc, retaddr);
+*v1 = tmp;
+}
+
+void HELPER(gvec_vfll32)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+vfll32(v1, v2, env, false, GETPC());
+}
+
+void HELPER(gvec_vfll32s)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+vfll32(v1, v2, env, true, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PATCH v6 4/6] include/elf: Add defines related to notes for GNU systems

2019-06-05 Thread Richard Henderson
This is a collection of related defines for notes, copied
from glibc's .  We're not going to use all of these
right away, but it seemed foolish to cherry-pick only the
ones we need now.

Signed-off-by: Richard Henderson 
---
 include/elf.h | 48 
 1 file changed, 48 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index ea7708a4ea..6f3eada36f 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1650,6 +1650,54 @@ typedef struct elf64_shdr {
 #define NT_ARM_HW_WATCH 0x403   /* ARM hardware watchpoint registers */
 #define NT_ARM_SYSTEM_CALL  0x404   /* ARM system call number */
 
+/* Defined note types for GNU systems.  */
+
+#define NT_GNU_ABI_TAG  1   /* ABI information */
+#define NT_GNU_HWCAP2   /* Synthetic hwcap information */
+#define NT_GNU_BUILD_ID 3   /* Build ID */
+#define NT_GNU_GOLD_VERSION 4   /* Version of ld.gold */
+#define NT_GNU_PROPERTY_TYPE_0  5   /* Program property */
+
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).  */
+
+#define GNU_PROPERTY_STACK_SIZE 1
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED   2
+
+#define GNU_PROPERTY_LOPROC 0xc000
+#define GNU_PROPERTY_HIPROC 0xdfff
+#define GNU_PROPERTY_LOUSER 0xe000
+#define GNU_PROPERTY_HIUSER 0x
+
+#define GNU_PROPERTY_X86_ISA_1_USED 0xc000
+#define GNU_PROPERTY_X86_ISA_1_NEEDED   0xc001
+
+#define GNU_PROPERTY_X86_ISA_1_486  (1U << 0)
+#define GNU_PROPERTY_X86_ISA_1_586  (1U << 1)
+#define GNU_PROPERTY_X86_ISA_1_686  (1U << 2)
+#define GNU_PROPERTY_X86_ISA_1_SSE  (1U << 3)
+#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4)
+#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5)
+#define GNU_PROPERTY_X86_ISA_1_SSSE3(1U << 6)
+#define GNU_PROPERTY_X86_ISA_1_SSE4_1   (1U << 7)
+#define GNU_PROPERTY_X86_ISA_1_SSE4_2   (1U << 8)
+#define GNU_PROPERTY_X86_ISA_1_AVX  (1U << 9)
+#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10)
+#define GNU_PROPERTY_X86_ISA_1_AVX512F  (1U << 11)
+#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12)
+#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13)
+#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14)
+#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15)
+#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16)
+#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17)
+
+#define GNU_PROPERTY_X86_FEATURE_1_AND  0xc002
+#define GNU_PROPERTY_X86_FEATURE_1_IBT  (1U << 0)
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK(1U << 1)
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND  0xc000
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI  (1u << 0)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC  (1u << 1)
+
 /*
  * Physical entry point into the kernel.
  *
-- 
2.17.1




[Qemu-devel] [PULL SUBSYSTEM s390x 22/33] s390x/tcg: Implement VECTOR LOAD ROUNDED

2019-06-05 Thread David Hildenbrand
We can reuse some of the infrastructure introduced for
VECTOR FP CONVERT FROM FIXED 64-BIT and friends.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 43 +
 4 files changed, 50 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index cb25141ffe..7526f8e8c6 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -280,6 +280,8 @@ DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 5afdb36aec..f03914d528 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1232,6 +1232,8 @@
 F(0xe7c7, VFI, VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR LOAD LENGTHENED */
 F(0xe7c4, VFLL,VRR_a, V,   0, 0, 0, 0, vfll, 0, IF_VEC)
+/* VECTOR LOAD ROUNDED */
+F(0xe7c5, VFLR,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index a25985e5c9..73e1b1062a 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2672,6 +2672,9 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
 case 0xc7:
 fn = se ? gen_helper_gvec_vfi64s : gen_helper_gvec_vfi64;
 break;
+case 0xc5:
+fn = se ? gen_helper_gvec_vflr64s : gen_helper_gvec_vflr64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index f5b7fdf871..764f7379da 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -444,3 +444,46 @@ void HELPER(gvec_vfll32s)(void *v1, const void *v2, 
CPUS390XState *env,
 {
 vfll32(v1, v2, env, true, GETPC());
 }
+
+static void vflr64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+   bool s, bool XxC, uint8_t erm, uintptr_t retaddr)
+{
+uint8_t vxc, vec_exc = 0;
+S390Vector tmp = {};
+int i, old_mode;
+
+old_mode = s390_swap_bfp_rounding_mode(env, erm);
+for (i = 0; i < 2; i++) {
+float64 a = s390_vec_read_element64(v2, i);
+uint32_t ret = float64_to_float32(a, >fpu_status);
+
+/* place at even element */
+s390_vec_write_element32(, i * 2, ret);
+/* indicate the source element */
+vxc = check_ieee_exc(env, i, XxC, _exc);
+if (s || vxc) {
+break;
+}
+}
+s390_restore_bfp_rounding_mode(env, old_mode);
+handle_ieee_exc(env, vxc, vec_exc, retaddr);
+*v1 = tmp;
+}
+
+void HELPER(gvec_vflr64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vflr64(v1, v2, env, false, XxC, erm, GETPC());
+}
+
+void HELPER(gvec_vflr64s)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vflr64(v1, v2, env, true, XxC, erm, GETPC());
+}
-- 
2.21.0




Re: [Qemu-devel] [PATCH 2/2] BootLinuxConsoleTest: Test the SmartFusion2 board

2019-06-05 Thread Eduardo Habkost
On Wed, Jun 05, 2019 at 12:06:59PM -0400, Cleber Rosa wrote:
> On Tue, May 21, 2019 at 12:06:35AM +0200, Philippe Mathieu-Daudé wrote:
> > Similar to the x86_64/pc test, it boots a Linux kernel on an
> > Emcraft board and verify the serial is working.
> > 
> > If ARM is a target being built, "make check-acceptance" will
> > automatically include this test by the use of the "arch:arm" tags.
> > 
> > Alternatively, this test can be run using:
> > 
> >   $ avocado run -t arch:arm tests/acceptance
> >   $ avocado run -t machine:emcraft-sf2 tests/acceptance
> >
> 
> The pattern accepted as a tag currently doesn't include a dash, see:
> 
>
> https://avocado-framework.readthedocs.io/en/68.0/ReferenceGuide.html#docstring-directives-rules
> 

Why isn't this causing test jobs to fail?

This patch is already queued on python-next, should I remove it?


> My suggestion is to replace the dash for an underline.  This was done
> on the s390 test:
> 
>:avocado: tags=machine:s390_ccw_virtio

I would love if we stopped using the docstring to store
machine-readable data and used Python class attributes or
methods, like most Python APIs do.  e.g.:

  class MyTest(avocado.Test):
  tags = {'machine':'s390-ccw-virtio'}

  def test_my_feature(self):
  ...


I understand the Avocado runner currently tries to not run any
test code at the "list" step.  But can we have a mode where it
will actually load the Python module and look at the class
objects directly, instead of trying to parse the Python code
without evaluating it?

> [...]

-- 
Eduardo



[Qemu-devel] [PATCH v6 0/6] linux-user/aarch64: Support PROT_BTI

2019-06-05 Thread Richard Henderson
Dave Martin has recently posted a kernel patch set for 
supporting ARMv8.5 Branch Target Identification in userland.

  http://lists.infradead.org/pipermail/linux-arm-kernel/2019-May/654654.html

While that support is not yet in the upstream kernel, it looks
to be close to its final form.  Note that the patch set spells
this PROT_BTI_GUARDED, but review suggested to rename to PROT_BTI.

Changes since v5:
  * New function to validate the target PROT parameter for mmap/mprotect.
  * Require BTI in the cpu for PROT_BTI set.
  * Set PSTATE.BTYPE=2 for the signal handler.
Adjust the smoke test to match.
  * Tidy up the note parsing.


r~


Richard Henderson (6):
  linux-user/aarch64: Reset btype for syscalls and signals
  linux-user: Validate mmap/mprotect prot value
  linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI
  include/elf: Add defines related to notes for GNU systems
  linux-user: Parse NT_GNU_PROPERTY_TYPE_0 notes
  tests/tcg/aarch64: Add bti smoke test

 include/elf.h |  48 
 include/exec/cpu-all.h|   2 +
 linux-user/syscall_defs.h |   4 +
 linux-user/aarch64/cpu_loop.c |   7 ++
 linux-user/aarch64/signal.c   |  10 ++-
 linux-user/elfload.c  |  83 ++--
 linux-user/mmap.c | 122 ++
 target/arm/translate-a64.c|   6 +-
 tests/tcg/aarch64/bti-1.c |  77 +++
 tests/tcg/aarch64/bti-crt.inc.c   |  69 +
 tests/tcg/aarch64/Makefile.target |   3 +
 11 files changed, 387 insertions(+), 44 deletions(-)
 create mode 100644 tests/tcg/aarch64/bti-1.c
 create mode 100644 tests/tcg/aarch64/bti-crt.inc.c

-- 
2.17.1




[Qemu-devel] [PULL SUBSYSTEM s390x 16/33] s390x/tcg: Implement VECTOR FP CONVERT FROM LOGICAL 64-BIT

2019-06-05 Thread David Hildenbrand
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 23 +++
 4 files changed, 30 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index a60f4c49fc..6fd996e924 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -268,6 +268,8 @@ DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, 
i32)
 DEF_HELPER_5(gvec_vfche64s_cc, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcdlg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index d3386024c8..465b36dd70 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1220,6 +1220,8 @@
 F(0xe7ea, VFCHE,   VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
 /* VECTOR FP CONVERT FROM FIXED 64-BIT */
 F(0xe7c3, VCDG,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP CONVERT FROM LOGICAL 64-BIT */
+F(0xe7c1, VCDLG,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 6741b707cc..fa755cd1d6 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2657,6 +2657,9 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
 case 0xc3:
 fn = se ? gen_helper_gvec_vcdg64s : gen_helper_gvec_vcdg64;
 break;
+case 0xc1:
+fn = se ? gen_helper_gvec_vcdlg64s : gen_helper_gvec_vcdlg64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 53430c7843..181378e167 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -300,3 +300,26 @@ void HELPER(gvec_vcdg64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vop64_2(v1, v2, env, true, XxC, erm, vcdg64, GETPC());
 }
+
+static uint64_t vcdlg64(uint64_t a, float_status *s)
+{
+return uint64_to_float64(a, s);
+}
+
+void HELPER(gvec_vcdlg64)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, false, XxC, erm, vcdlg64, GETPC());
+}
+
+void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
+   uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, true, XxC, erm, vcdlg64, GETPC());
+}
-- 
2.21.0




Re: [Qemu-devel] Deprecation policy and build dependencies

2019-06-05 Thread Eduardo Habkost
On Wed, Jun 05, 2019 at 03:42:39PM -0500, Eric Blake wrote:
> On 6/5/19 3:13 PM, Eduardo Habkost wrote:
> 
> >> IOW, I don't think RHEL-7 support as a build platform blocks us from
> >> dropping py2. We merely need to tweak our build platforms doc to clarify
> >> our intent wrt add-on yum repos.
> > 
> > If we clarify the docs in QEMU 4.1, is there anything that
> > prevents us from removing Python 2 support in QEMU 4.1 too?
> 
> My take (but not definitive): if we have any CI setups that are testing
> RHEL 7 without software collections and/or EPEL, then save Python 2
> removal for 4.2 to give us time to update CI setups. But if all of our
> CI setups are already fine, and we clarify the docs, then I'm all for
> getting rid of Python 2 support in 4.1.

If we do this soon, CI system owners will have at least 9 weeks
to fix them before 4.1.0 is released.

> 
> Similarly, if we are going to outlaw in-tree builds, let's get that done
> in 4.1 instead of waiting yet another release.

I'm missing the context on this.  Is this from a separate discussion?

-- 
Eduardo



Re: [Qemu-devel] Deprecation policy and build dependencies

2019-06-05 Thread Eric Blake
On 6/5/19 3:13 PM, Eduardo Habkost wrote:

>> IOW, I don't think RHEL-7 support as a build platform blocks us from
>> dropping py2. We merely need to tweak our build platforms doc to clarify
>> our intent wrt add-on yum repos.
> 
> If we clarify the docs in QEMU 4.1, is there anything that
> prevents us from removing Python 2 support in QEMU 4.1 too?

My take (but not definitive): if we have any CI setups that are testing
RHEL 7 without software collections and/or EPEL, then save Python 2
removal for 4.2 to give us time to update CI setups. But if all of our
CI setups are already fine, and we clarify the docs, then I'm all for
getting rid of Python 2 support in 4.1.

Similarly, if we are going to outlaw in-tree builds, let's get that done
in 4.1 instead of waiting yet another release.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL SUBSYSTEM s390x 25/33] s390x/tcg: Implement VECTOR FP PERFORM SIGN OPERATION

2019-06-05 Thread David Hildenbrand
The only FP instruction we can implement without an helper.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c | 52 +
 2 files changed, 54 insertions(+)

diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index e86ade9e44..fa2e801747 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1240,6 +1240,8 @@
 F(0xe78f, VFMA,VRR_e, V,   0, 0, 0, 0, vfma, 0, IF_VEC)
 /* VECTOR FP MULTIPLY AND SUBTRACT */
 F(0xe78e, VFMS,VRR_e, V,   0, 0, 0, 0, vfma, 0, IF_VEC)
+/* VECTOR FP PERFORM SIGN OPERATION */
+F(0xe7cc, VFPSO,   VRR_a, V,   0, 0, 0, 0, vfpso, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index b624c7a8aa..9b8606ba25 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2727,3 +2727,55 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps 
*o)
0, fn);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfpso(DisasContext *s, DisasOps *o)
+{
+const uint8_t v1 = get_field(s->fields, v1);
+const uint8_t v2 = get_field(s->fields, v2);
+const uint8_t fpf = get_field(s->fields, m3);
+const uint8_t m4 = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+TCGv_i64 tmp;
+
+if (fpf != FPF_LONG || extract32(m4, 0, 3) || m5 > 2) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m4, 3, 1)) {
+tmp = tcg_temp_new_i64();
+read_vec_element_i64(tmp, v2, 0, ES_64);
+switch (m5) {
+case 0:
+/* sign bit is inverted (complement) */
+tcg_gen_xori_i64(tmp, tmp, 1ull << 63);
+break;
+case 1:
+/* sign bit is set to one (negative) */
+tcg_gen_ori_i64(tmp, tmp, 1ull << 63);
+break;
+case 2:
+/* sign bit is set to zero (positive) */
+tcg_gen_andi_i64(tmp, tmp, (1ull << 63) - 1);
+break;
+}
+write_vec_element_i64(tmp, v1, 0, ES_64);
+tcg_temp_free_i64(tmp);
+} else {
+switch (m5) {
+case 0:
+/* sign bit is inverted (complement) */
+gen_gvec_fn_2i(xori, ES_64, v1, v2, 1ull << 63);
+break;
+case 1:
+/* sign bit is set to one (negative) */
+gen_gvec_fn_2i(ori, ES_64, v1, v2, 1ull << 63);
+break;
+case 2:
+/* sign bit is set to zero (positive) */
+gen_gvec_fn_2i(andi, ES_64, v1, v2, (1ull << 63) - 1);
+break;
+}
+}
+return DISAS_NEXT;
+}
-- 
2.21.0




Re: [Qemu-devel] Qemu baseline requirements/portability?

2019-06-05 Thread H. Peter Anvin
On 6/5/19 12:55 PM, H. Peter Anvin wrote:
> Hi,
> 
> I am writing some code I'm hoping will be able to make it into Qemu, but I
> can't seem to find what the baseline portability requirements are.  I'm
> specifically wondering about newer POSIX features like openat(), which seems
> to be used in the 9p filesystem and nowhere else, and what version of glib one
> can rely on?
> 

Specifically, I'm trying to satisfy a 10-year-old request by me and others to
support composite initrd during Linux boot.

-hpa




[Qemu-devel] [PULL SUBSYSTEM s390x 17/33] s390x/tcg: Implement VECTOR FP CONVERT TO FIXED 64-BIT

2019-06-05 Thread David Hildenbrand
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 23 +++
 4 files changed, 30 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 6fd996e924..9893c677da 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -270,6 +270,8 @@ DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdlg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 465b36dd70..97c62a8af5 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1222,6 +1222,8 @@
 F(0xe7c3, VCDG,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR FP CONVERT FROM LOGICAL 64-BIT */
 F(0xe7c1, VCDLG,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP CONVERT TO FIXED 64-BIT */
+F(0xe7c2, VCGD,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index fa755cd1d6..a42de2ff01 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2660,6 +2660,9 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
 case 0xc1:
 fn = se ? gen_helper_gvec_vcdlg64s : gen_helper_gvec_vcdlg64;
 break;
+case 0xc2:
+fn = se ? gen_helper_gvec_vcgd64s : gen_helper_gvec_vcgd64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 181378e167..e7251aca04 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -323,3 +323,26 @@ void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vop64_2(v1, v2, env, true, XxC, erm, vcdlg64, GETPC());
 }
+
+static uint64_t vcgd64(uint64_t a, float_status *s)
+{
+return float64_to_int64(a, s);
+}
+
+void HELPER(gvec_vcgd64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, false, XxC, erm, vcgd64, GETPC());
+}
+
+void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, true, XxC, erm, vcgd64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 12/33] s390x/tcg: Implement VECTOR FP ADD

2019-06-05 Thread David Hildenbrand
1. We'll reuse op_vfa() for similar instructions later, prepare for
   that.
2. We'll reuse vop64_3() for other instructions later.
3. Take care of modifying the vector register only if no trap happened.
 - on traps, flags are not updated and no elements are modified
 - traps don't modify the fpc flags
 - without traps, all exceptions of all elements are merged
4. We'll reuse check_ieee_exc() later when we need the XxC flag.

We have to check for exceptions after processing each element.
Provide separate handlers for single/all element processing. We'll do
the same for all applicable FP instructions.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/Makefile.objs  |   1 +
 target/s390x/helper.h   |   4 ++
 target/s390x/insn-data.def  |   5 ++
 target/s390x/translate_vx.inc.c |  29 
 target/s390x/vec_fpu_helper.c   | 119 
 5 files changed, 158 insertions(+)
 create mode 100644 target/s390x/vec_fpu_helper.c

diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
index ffdd484ef0..3e2745594a 100644
--- a/target/s390x/Makefile.objs
+++ b/target/s390x/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += cpu.o cpu_models.o cpu_features.o gdbstub.o 
interrupt.o helper.o
 obj-$(CONFIG_TCG) += translate.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o crypto_helper.o
 obj-$(CONFIG_TCG) += vec_helper.o vec_int_helper.o vec_string_helper.o
+obj-$(CONFIG_TCG) += vec_fpu_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o
 obj-$(CONFIG_SOFTMMU) += sigp.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 5db67779d3..21658a2771 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -249,6 +249,10 @@ DEF_HELPER_6(gvec_vstrc_cc_rt8, void, ptr, cptr, cptr, 
cptr, env, i32)
 DEF_HELPER_6(gvec_vstrc_cc_rt16, void, ptr, cptr, cptr, cptr, env, i32)
 DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
 
+/* === Vector Floating-Point Instructions */
+DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
 DEF_HELPER_4(diag, void, env, i32, i32, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index a2969fab58..79892f6042 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1204,6 +1204,11 @@
 /* VECTOR STRING RANGE COMPARE */
 F(0xe78a, VSTRC,   VRR_d, V,   0, 0, 0, 0, vstrc, 0, IF_VEC)
 
+/* === Vector Floating-Point Instructions */
+
+/* VECTOR FP ADD */
+F(0xe7e3, VFA, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
+
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
 E(0xb250, CSP, RRE,   Z,   r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL, 
IF_PRIV)
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index f26ffa2895..44da9f2645 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -52,6 +52,11 @@
 #define ES_64   MO_64
 #define ES_128  4
 
+/* Floating-Point Format */
+#define FPF_SHORT   2
+#define FPF_LONG3
+#define FPF_EXT 4
+
 static inline bool valid_vec_element(uint8_t enr, TCGMemOp es)
 {
 return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
@@ -2538,3 +2543,27 @@ static DisasJumpType op_vstrc(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+const bool se = extract32(m5, 3, 1);
+gen_helper_gvec_3_ptr *fn;
+
+if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+switch (s->fields->op2) {
+case 0xe3:
+fn = se ? gen_helper_gvec_vfa64s : gen_helper_gvec_vfa64;
+break;
+default:
+g_assert_not_reached();
+}
+gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), cpu_env, 0, fn);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
new file mode 100644
index 00..c7db0791d7
--- /dev/null
+++ b/target/s390x/vec_fpu_helper.c
@@ -0,0 +1,119 @@
+/*
+ * QEMU TCG support -- s390x vector floating point instruction support
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ *   David Hildenbrand 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internal.h"
+#include "vec.h"
+#include "tcg_s390x.h"
+#include "tcg/tcg-gvec-desc.h"
+#include "exec/exec-all.h"
+#include 

[Qemu-devel] [PULL SUBSYSTEM s390x 19/33] s390x/tcg: Implement VECTOR FP DIVIDE

2019-06-05 Thread David Hildenbrand
We can reuse most of the infrastructure added for VECTOR FP ADD.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 17 +
 4 files changed, 24 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 9b9062970a..238bfa2509 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -274,6 +274,8 @@ DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfd64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index ed8b888d59..f9830deace 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1226,6 +1226,8 @@
 F(0xe7c2, VCGD,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR FP CONVERT TO LOGICAL 64-BIT */
 F(0xe7c0, VCLGD,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP DIVIDE */
+F(0xe7e5, VFD, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 0395d69968..9e55d4488b 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2560,6 +2560,9 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
 case 0xe3:
 fn = se ? gen_helper_gvec_vfa64s : gen_helper_gvec_vfa64;
 break;
+case 0xe5:
+fn = se ? gen_helper_gvec_vfd64s : gen_helper_gvec_vfd64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 09ef0abfb0..3c62eb5787 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -369,3 +369,20 @@ void HELPER(gvec_vclgd64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC());
 }
+
+static uint64_t vfd64(uint64_t a, uint64_t b, float_status *s)
+{
+return float64_div(a, b, s);
+}
+
+void HELPER(gvec_vfd64)(void *v1, const void *v2, const void *v3,
+CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, false, vfd64, GETPC());
+}
+
+void HELPER(gvec_vfd64s)(void *v1, const void *v2, const void *v3,
+ CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, true, vfd64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 24/33] s390x/tcg: Implement VECTOR FP MULTIPLY AND (ADD|SUBTRACT)

2019-06-05 Thread David Hildenbrand
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  4 +++
 target/s390x/insn-data.def  |  4 +++
 target/s390x/translate_vx.inc.c | 23 
 target/s390x/vec_fpu_helper.c   | 48 +
 4 files changed, 79 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 22e02a0178..bcaabb91a5 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -284,6 +284,10 @@ DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfm64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index e56059ac34..e86ade9e44 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1236,6 +1236,10 @@
 F(0xe7c5, VFLR,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR FP MULTIPLY */
 F(0xe7e7, VFM, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
+/* VECTOR FP MULTIPLY AND ADD */
+F(0xe78f, VFMA,VRR_e, V,   0, 0, 0, 0, vfma, 0, IF_VEC)
+/* VECTOR FP MULTIPLY AND SUBTRACT */
+F(0xe78e, VFMS,VRR_e, V,   0, 0, 0, 0, vfma, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index ae31a327cf..b624c7a8aa 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2704,3 +2704,26 @@ static DisasJumpType op_vfll(DisasContext *s, DisasOps 
*o)
0, fn);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
+{
+const uint8_t m5 = get_field(s->fields, m5);
+const uint8_t fpf = get_field(s->fields, m6);
+const bool se = extract32(m5, 3, 1);
+gen_helper_gvec_4_ptr *fn;
+
+if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (s->fields->op2 == 0x8f) {
+fn = se ? gen_helper_gvec_vfma64s : gen_helper_gvec_vfma64;
+} else {
+fn = se ? gen_helper_gvec_vfms64s : gen_helper_gvec_vfms64;
+}
+gen_gvec_4_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), get_field(s->fields, v4), cpu_env,
+   0, fn);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 57b7fe4aff..7993a6fafa 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -504,3 +504,51 @@ void HELPER(gvec_vfm64s)(void *v1, const void *v2, const 
void *v3,
 {
 vop64_3(v1, v2, v3, env, true, vfm64, GETPC());
 }
+
+static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+   const S390Vector *v4, CPUS390XState *env, bool s, int flags,
+   uintptr_t retaddr)
+{
+uint8_t vxc, vec_exc = 0;
+S390Vector tmp = {};
+int i;
+
+for (i = 0; i < 2; i++) {
+const uint64_t a = s390_vec_read_element64(v2, i);
+const uint64_t b = s390_vec_read_element64(v3, i);
+const uint64_t c = s390_vec_read_element64(v4, i);
+uint64_t ret = float64_muladd(a, b, c, flags, >fpu_status);
+
+s390_vec_write_element64(, i, ret);
+vxc = check_ieee_exc(env, i, false, _exc);
+if (s || vxc) {
+break;
+}
+}
+handle_ieee_exc(env, vxc, vec_exc, retaddr);
+*v1 = tmp;
+}
+
+void HELPER(gvec_vfma64)(void *v1, const void *v2, const void *v3,
+ const void *v4, CPUS390XState *env, uint32_t desc)
+{
+vfma64(v1, v2, v3, v4, env, false, 0, GETPC());
+}
+
+void HELPER(gvec_vfma64s)(void *v1, const void *v2, const void *v3,
+ const void *v4, CPUS390XState *env, uint32_t desc)
+{
+vfma64(v1, v2, v3, v4, env, true, 0, GETPC());
+}
+
+void HELPER(gvec_vfms64)(void *v1, const void *v2, const void *v3,
+ const void *v4, CPUS390XState *env, uint32_t desc)
+{
+vfma64(v1, v2, v3, v4, env, false, float_muladd_negate_c, GETPC());
+}
+
+void HELPER(gvec_vfms64s)(void *v1, const void *v2, const void *v3,
+ const void *v4, CPUS390XState *env, uint32_t desc)
+{
+vfma64(v1, v2, v3, v4, env, true, float_muladd_negate_c, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 27/33] s390x/tcg: Implement VECTOR FP SUBTRACT

2019-06-05 Thread David Hildenbrand
Similar to VECTOR FP ADD.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 17 +
 4 files changed, 24 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 23b37af1e4..c788fc1b7f 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -290,6 +290,8 @@ DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, 
cptr, cptr, cptr, env
 DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfs64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 354252d57c..4426f40250 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1244,6 +1244,8 @@
 F(0xe7cc, VFPSO,   VRR_a, V,   0, 0, 0, 0, vfpso, 0, IF_VEC)
 /* VECTOR FP SQUARE ROOT */
 F(0xe7ce, VFSQ,VRR_a, V,   0, 0, 0, 0, vfsq, 0, IF_VEC)
+/* VECTOR FP SUBTRACT */
+F(0xe7e2, VFS, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 75f3596c4b..c0a19aa9f3 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2566,6 +2566,9 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
 case 0xe7:
 fn = se ? gen_helper_gvec_vfm64s : gen_helper_gvec_vfm64;
 break;
+case 0xe2:
+fn = se ? gen_helper_gvec_vfs64s : gen_helper_gvec_vfs64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 18773eb559..ccdc975628 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -569,3 +569,20 @@ void HELPER(gvec_vfsq64s)(void *v1, const void *v2, 
CPUS390XState *env,
 {
 vop64_2(v1, v2, env, true, false, 0, vfsq64, GETPC());
 }
+
+static uint64_t vfs64(uint64_t a, uint64_t b, float_status *s)
+{
+return float64_sub(a, b, s);
+}
+
+void HELPER(gvec_vfs64)(void *v1, const void *v2, const void *v3,
+CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, false, vfs64, GETPC());
+}
+
+void HELPER(gvec_vfs64s)(void *v1, const void *v2, const void *v3,
+ CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, true, vfs64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 28/33] s390x/tcg: Implement VECTOR FP TEST DATA CLASS IMMEDIATE

2019-06-05 Thread David Hildenbrand
We can reuse float64_dcmask().

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c | 21 +++
 target/s390x/vec_fpu_helper.c   | 37 +
 4 files changed, 62 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index c788fc1b7f..e9aff83b05 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -292,6 +292,8 @@ DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfs64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
+DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 4426f40250..f421184fcd 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1246,6 +1246,8 @@
 F(0xe7ce, VFSQ,VRR_a, V,   0, 0, 0, 0, vfsq, 0, IF_VEC)
 /* VECTOR FP SUBTRACT */
 F(0xe7e2, VFS, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
+/* VECTOR FP TEST DATA CLASS IMMEDIATE */
+F(0xe74a, VFTCI,   VRI_e, V,   0, 0, 0, 0, vftci, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index c0a19aa9f3..69c675e411 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2801,3 +2801,24 @@ static DisasJumpType op_vfsq(DisasContext *s, DisasOps 
*o)
0, fn);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vftci(DisasContext *s, DisasOps *o)
+{
+const uint16_t i3 = get_field(s->fields, i3);
+const uint8_t fpf = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vftci64;
+
+if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m5, 3, 1)) {
+fn = gen_helper_gvec_vftci64s;
+}
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2), cpu_env,
+   i3, fn);
+set_cc_static(s);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index ccdc975628..a48bd704bc 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -586,3 +586,40 @@ void HELPER(gvec_vfs64s)(void *v1, const void *v2, const 
void *v3,
 {
 vop64_3(v1, v2, v3, env, true, vfs64, GETPC());
 }
+
+static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+   bool s, uint16_t i3)
+{
+int i, match = 0;
+
+for (i = 0; i < 2; i++) {
+float64 a = s390_vec_read_element64(v2, i);
+
+if (float64_dcmask(env, a) & i3) {
+match++;
+s390_vec_write_element64(v1, i, -1ull);
+} else {
+s390_vec_write_element64(v1, i, 0);
+}
+if (s) {
+break;
+}
+}
+
+if (match) {
+return s || match == 2 ? 0 : 1;
+}
+return 3;
+}
+
+void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+env->cc_op = vftci64(v1, v2, env, false, simd_data(desc));
+}
+
+void HELPER(gvec_vftci64s)(void *v1, const void *v2, CPUS390XState *env,
+   uint32_t desc)
+{
+env->cc_op = vftci64(v1, v2, env, true, simd_data(desc));
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 14/33] s390x/tcg: Implement VECTOR FP COMPARE (EQUAL|HIGH|HIGH OR EQUAL)

2019-06-05 Thread David Hildenbrand
Provide for all three instructions all four combinations of cc bit and
s bit.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  12 
 target/s390x/insn-data.def  |   6 ++
 target/s390x/translate_vx.inc.c |  51 
 target/s390x/vec_fpu_helper.c   | 104 
 4 files changed, 173 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index d34d6802a6..33d3bacf74 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -254,6 +254,18 @@ DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, 
cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
 DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vfce64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_5(gvec_vfce64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfce64s_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfch64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vfch64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_5(gvec_vfch64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfch64s_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfche64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vfche64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfche64s_cc, void, ptr, cptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index c45e101b10..446552f251 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1212,6 +1212,12 @@
 F(0xe7cb, WFC, VRR_a, V,   0, 0, 0, 0, wfc, 0, IF_VEC)
 /* VECTOR FP COMPARE AND SIGNAL SCALAR */
 F(0xe7ca, WFK, VRR_a, V,   0, 0, 0, 0, wfc, 0, IF_VEC)
+/* VECTOR FP COMPARE EQUAL */
+F(0xe7e8, VFCE,VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
+/* VECTOR FP COMPARE HIGH */
+F(0xe7eb, VFCH,VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
+/* VECTOR FP COMPARE HIGH OR EQUAL */
+F(0xe7ea, VFCHE,   VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 283e8aa07a..5571a71e1a 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2588,3 +2588,54 @@ static DisasJumpType op_wfc(DisasContext *s, DisasOps *o)
 set_cc_static(s);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfc(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+const uint8_t m6 = get_field(s->fields, m6);
+const bool se = extract32(m5, 3, 1);
+const bool cs = extract32(m6, 0, 1);
+gen_helper_gvec_3_ptr *fn;
+
+if (fpf != FPF_LONG || extract32(m5, 0, 3) || extract32(m6, 1, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (cs) {
+switch (s->fields->op2) {
+case 0xe8:
+fn = se ? gen_helper_gvec_vfce64s_cc : gen_helper_gvec_vfce64_cc;
+break;
+case 0xeb:
+fn = se ? gen_helper_gvec_vfch64s_cc : gen_helper_gvec_vfch64_cc;
+break;
+case 0xea:
+fn = se ? gen_helper_gvec_vfche64s_cc : gen_helper_gvec_vfche64_cc;
+break;
+default:
+g_assert_not_reached();
+}
+} else {
+switch (s->fields->op2) {
+case 0xe8:
+fn = se ? gen_helper_gvec_vfce64s : gen_helper_gvec_vfce64;
+break;
+case 0xeb:
+fn = se ? gen_helper_gvec_vfch64s : gen_helper_gvec_vfch64;
+break;
+case 0xea:
+fn = se ? gen_helper_gvec_vfche64s : gen_helper_gvec_vfche64;
+break;
+default:
+g_assert_not_reached();
+}
+}
+gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), cpu_env, 0, fn);
+if (cs) {
+set_cc_static(s);
+}
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index f9357d9221..e72500d4d5 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -149,3 +149,107 @@ void HELPER(gvec_wfk64)(const void *v1, const void *v2, 
CPUS390XState *env,
 {
 env->cc_op = wfc64(v1, v2, env, true, GETPC());
 }
+
+typedef int (*vfc64_fn)(float64 a, float64 b, float_status *status);
+static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+

[Qemu-devel] [PULL SUBSYSTEM s390x 06/33] s390x: Align vector registers to 16 bytes

2019-06-05 Thread David Hildenbrand
11e2bfef7990 ("tcg/i386: Use MOVDQA for TCG_TYPE_V128 load/store")
revealed that the vregs are not aligned to 16 bytes. Align them to
16 bytes, to avoid segfault'ing on x86.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7305cacc7b..1bed12b6c3 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -66,7 +66,7 @@ struct CPUS390XState {
  * The floating point registers are part of the vector registers.
  * vregs[0][0] -> vregs[15][0] are 16 floating point registers
  */
-CPU_DoubleU vregs[32][2];  /* vector registers */
+CPU_DoubleU vregs[32][2] QEMU_ALIGNED(16);  /* vector registers */
 uint32_t aregs[16];/* access registers */
 uint8_t riccb[64]; /* runtime instrumentation control */
 uint64_t gscb[4];  /* guarded storage control */
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 11/33] s390x/tcg: Export float_comp_to_cc() and float(32|64|128)_dcmask()

2019-06-05 Thread David Hildenbrand
Vector floating-point instructions will require these functions, so
allow to use them from other files.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/fpu_helper.c | 4 ++--
 target/s390x/internal.h   | 4 
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index 1be68bafea..d2c17ed942 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -112,7 +112,7 @@ static void handle_exceptions(CPUS390XState *env, bool XxC, 
uintptr_t retaddr)
 }
 }
 
-static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
+int float_comp_to_cc(CPUS390XState *env, int float_compare)
 {
 S390CPU *cpu = s390_env_get_cpu(env);
 
@@ -746,7 +746,7 @@ static inline uint16_t dcmask(int bit, bool neg)
 }
 
 #define DEF_FLOAT_DCMASK(_TYPE) \
-static uint16_t _TYPE##_dcmask(CPUS390XState *env, _TYPE f1)   \
+uint16_t _TYPE##_dcmask(CPUS390XState *env, _TYPE f1)  \
 {  \
 const bool neg = _TYPE##_is_neg(f1);   \
\
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 9893fc094b..c243fa725b 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -285,6 +285,10 @@ uint32_t set_cc_nz_f128(float128 v);
 uint8_t s390_softfloat_exc_to_ieee(unsigned int exc);
 int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3);
 void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode);
+int float_comp_to_cc(CPUS390XState *env, int float_compare);
+uint16_t float32_dcmask(CPUS390XState *env, float32 f1);
+uint16_t float64_dcmask(CPUS390XState *env, float64 f1);
+uint16_t float128_dcmask(CPUS390XState *env, float128 f1);
 
 
 /* gdbstub.c */
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 23/33] s390x/tcg: Implement VECTOR FP MULTIPLY

2019-06-05 Thread David Hildenbrand
Very similar to VECTOR FP DIVIDE.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 17 +
 4 files changed, 24 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 7526f8e8c6..22e02a0178 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -282,6 +282,8 @@ DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfm64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index f03914d528..e56059ac34 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1234,6 +1234,8 @@
 F(0xe7c4, VFLL,VRR_a, V,   0, 0, 0, 0, vfll, 0, IF_VEC)
 /* VECTOR LOAD ROUNDED */
 F(0xe7c5, VFLR,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP MULTIPLY */
+F(0xe7e7, VFM, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 73e1b1062a..ae31a327cf 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2563,6 +2563,9 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
 case 0xe5:
 fn = se ? gen_helper_gvec_vfd64s : gen_helper_gvec_vfd64;
 break;
+case 0xe7:
+fn = se ? gen_helper_gvec_vfm64s : gen_helper_gvec_vfm64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 764f7379da..57b7fe4aff 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -487,3 +487,20 @@ void HELPER(gvec_vflr64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vflr64(v1, v2, env, true, XxC, erm, GETPC());
 }
+
+static uint64_t vfm64(uint64_t a, uint64_t b, float_status *s)
+{
+return float64_mul(a, b, s);
+}
+
+void HELPER(gvec_vfm64)(void *v1, const void *v2, const void *v3,
+CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, false, vfm64, GETPC());
+}
+
+void HELPER(gvec_vfm64s)(void *v1, const void *v2, const void *v3,
+ CPUS390XState *env, uint32_t desc)
+{
+vop64_3(v1, v2, v3, env, true, vfm64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 32/33] s390x/tcg: Use tcg_gen_gvec_bitsel for VECTOR SELECT

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

This replaces the target-specific implementations for VSEL.

Signed-off-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/translate_vx.inc.c | 38 ++---
 1 file changed, 6 insertions(+), 32 deletions(-)

diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 69c675e411..7b1d31cba5 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -245,6 +245,9 @@ static void get_vec_element_ptr_i64(TCGv_ptr ptr, uint8_t 
reg, TCGv_i64 enr,
 #define gen_gvec_fn_3(fn, es, v1, v2, v3) \
 tcg_gen_gvec_##fn(es, vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
   vec_full_reg_offset(v3), 16, 16)
+#define gen_gvec_fn_4(fn, es, v1, v2, v3, v4) \
+tcg_gen_gvec_##fn(es, vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+  vec_full_reg_offset(v3), vec_full_reg_offset(v4), 16, 16)
 
 /*
  * Helper to carry out a 128 bit vector computation using 2 i64 values per
@@ -915,40 +918,11 @@ static DisasJumpType op_vsce(DisasContext *s, DisasOps *o)
 return DISAS_NEXT;
 }
 
-static void gen_sel_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c)
-{
-TCGv_i64 t = tcg_temp_new_i64();
-
-/* bit in c not set -> copy bit from b */
-tcg_gen_andc_i64(t, b, c);
-/* bit in c set -> copy bit from a */
-tcg_gen_and_i64(d, a, c);
-/* merge the results */
-tcg_gen_or_i64(d, d, t);
-tcg_temp_free_i64(t);
-}
-
-static void gen_sel_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b,
-TCGv_vec c)
-{
-TCGv_vec t = tcg_temp_new_vec_matching(d);
-
-tcg_gen_andc_vec(vece, t, b, c);
-tcg_gen_and_vec(vece, d, a, c);
-tcg_gen_or_vec(vece, d, d, t);
-tcg_temp_free_vec(t);
-}
-
 static DisasJumpType op_vsel(DisasContext *s, DisasOps *o)
 {
-static const GVecGen4 gvec_op = {
-.fni8 = gen_sel_i64,
-.fniv = gen_sel_vec,
-.prefer_i64 = TCG_TARGET_REG_BITS == 64,
-};
-
-gen_gvec_4(get_field(s->fields, v1), get_field(s->fields, v2),
-   get_field(s->fields, v3), get_field(s->fields, v4), _op);
+gen_gvec_fn_4(bitsel, ES_8, get_field(s->fields, v1),
+  get_field(s->fields, v4), get_field(s->fields, v2),
+  get_field(s->fields, v3));
 return DISAS_NEXT;
 }
 
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 10/33] s390x/tcg: Introduce tcg_s390_vector_exception()

2019-06-05 Thread David Hildenbrand
Handling is similar to data exceptions, however we can always store the
VXC into the lowore and the FPC:

z14 PoP, 6-20, "Vector-Exception Code"
When a vector-processing exception causes a pro-
gram interruption, a vector-exception code (VXC) is
stored at location 147, and zeros are stored at loca-
tions 144-146. The VXC is also placed in the DXC
field of the floating-point-control (FPC) register if bit
45 of control register 0 is one. When bit 45 of control
register 0 is zero and bit 46 of control register 0 is
one, the DXC field of the FPC register and the con-
tents of storage at location 147 are unpredictable.

Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.h |  1 +
 target/s390x/excp_helper.c | 15 +++
 target/s390x/tcg_s390x.h   |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 317a1377e6..4fc08a2c88 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -215,6 +215,7 @@ extern const struct VMStateDescription vmstate_s390_cpu;
 #define PGM_SPECIAL_OP  0x0013
 #define PGM_OPERAND 0x0015
 #define PGM_TRACE_TABLE 0x0016
+#define PGM_VECTOR_PROCESSING   0x001b
 #define PGM_SPACE_SWITCH0x001c
 #define PGM_HFP_SQRT0x001d
 #define PGM_PC_TRANS_SPEC   0x001f
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 85223d00c0..f21bcf79ae 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -62,6 +62,21 @@ void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState 
*env, uint32_t dxc,
 tcg_s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, ra);
 }
 
+void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
+ uintptr_t ra)
+{
+g_assert(vxc <= 0xff);
+#if !defined(CONFIG_USER_ONLY)
+/* Always store the VXC into the lowcore, without AFP it is undefined */
+stl_phys(CPU(s390_env_get_cpu(env))->as,
+ env->psa + offsetof(LowCore, data_exc_code), vxc);
+#endif
+
+/* Always store the VXC into the FPC, without AFP it is undefined */
+env->fpc = deposit32(env->fpc, 8, 8, vxc);
+tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ILEN_AUTO, ra);
+}
+
 void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
 {
 tcg_s390_data_exception(env, dxc, GETPC());
diff --git a/target/s390x/tcg_s390x.h b/target/s390x/tcg_s390x.h
index ab2c4ba703..2813f9d48e 100644
--- a/target/s390x/tcg_s390x.h
+++ b/target/s390x/tcg_s390x.h
@@ -18,5 +18,7 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState 
*env, uint32_t code,
   int ilen, uintptr_t ra);
 void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
uintptr_t ra);
+void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
+ uintptr_t ra);
 
 #endif /* TCG_S390X_H */
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 33/33] linux-user: elf: ELF_HWCAP for s390x

2019-06-05 Thread David Hildenbrand
Let's add all HWCAPs that we can support under TCG right now, when the
respective CPU facilities are enabled.

Cc: Riku Voipio 
Cc: Laurent Vivier 
Cc: Cornelia Huck 
Cc: Laurent Vivier 
Cc: Richard Henderson 
Acked-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 include/elf.h|  1 +
 linux-user/elfload.c | 28 
 2 files changed, 29 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index ea7708a4ea..3501e0c8d0 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -598,6 +598,7 @@ typedef struct {
 #define HWCAP_S390_ETF3EH   256
 #define HWCAP_S390_HIGH_GPRS512
 #define HWCAP_S390_TE   1024
+#define HWCAP_S390_VXRS 2048
 
 /* M68K specific definitions. */
 /* We use the top 24 bits to encode information about the
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a57b7049dd..5451d262ec 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1308,6 +1308,34 @@ static inline void init_thread(struct target_pt_regs 
*regs,
 #define ELF_DATA   ELFDATA2MSB
 #define ELF_ARCH   EM_S390
 
+#include "elf.h"
+
+#define ELF_HWCAP get_elf_hwcap()
+
+#define GET_FEATURE(_feat, _hwcap) \
+do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0)
+
+static uint32_t get_elf_hwcap(void)
+{
+/*
+ * Let's assume we always have esan3 and zarch.
+ * 31-bit processes can use 64-bit registers (high gprs).
+ */
+uint32_t hwcap = HWCAP_S390_ESAN3 | HWCAP_S390_ZARCH | 
HWCAP_S390_HIGH_GPRS;
+
+GET_FEATURE(S390_FEAT_STFLE, HWCAP_S390_STFLE);
+GET_FEATURE(S390_FEAT_MSA, HWCAP_S390_MSA);
+GET_FEATURE(S390_FEAT_LONG_DISPLACEMENT, HWCAP_S390_LDISP);
+GET_FEATURE(S390_FEAT_EXTENDED_IMMEDIATE, HWCAP_S390_EIMM);
+if (s390_has_feat(S390_FEAT_EXTENDED_TRANSLATION_3) &&
+s390_has_feat(S390_FEAT_ETF3_ENH)) {
+hwcap |= HWCAP_S390_ETF3EH;
+}
+GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS);
+
+return hwcap;
+}
+
 static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
 {
 regs->psw.addr = infop->entry;
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 03/33] s390x/tcg: Implement VECTOR FIND ELEMENT NOT EQUAL

2019-06-05 Thread David Hildenbrand
Similar to VECTOR FIND ELEMENT EQUAL. Core logic courtesy of Richard H.

Add s390_vec_read_element() that can deal with element sizes.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h|  6 +++
 target/s390x/insn-data.def   |  2 +
 target/s390x/translate_vx.inc.c  | 31 +
 target/s390x/vec.h   | 19 
 target/s390x/vec_string_helper.c | 74 
 5 files changed, 132 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index a1b169b666..fb50b404db 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -224,6 +224,12 @@ DEF_HELPER_FLAGS_4(gvec_vfee32, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
 DEF_HELPER_5(gvec_vfee_cc8, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfee_cc16, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfee_cc32, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfene8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfene16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfene32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_5(gvec_vfene_cc8, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfene_cc16, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfene_cc32, void, ptr, cptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index d8907ef6a5..d03c1ee0b3 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1197,6 +1197,8 @@
 F(0xe782, VFAE,VRR_b, V,   0, 0, 0, 0, vfae, 0, IF_VEC)
 /* VECTOR FIND ELEMENT EQUAL */
 F(0xe780, VFEE,VRR_b, V,   0, 0, 0, 0, vfee, 0, IF_VEC)
+/* VECTOR FIND ELEMENT NOT EQUAL */
+F(0xe781, VFENE,   VRR_b, V,   0, 0, 0, 0, vfene, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index b25afbc011..1ad0b62517 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2414,3 +2414,34 @@ static DisasJumpType op_vfee(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfene(DisasContext *s, DisasOps *o)
+{
+const uint8_t es = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+static gen_helper_gvec_3 * const g[3] = {
+gen_helper_gvec_vfene8,
+gen_helper_gvec_vfene16,
+gen_helper_gvec_vfene32,
+};
+static gen_helper_gvec_3_ptr * const g_cc[3] = {
+gen_helper_gvec_vfene_cc8,
+gen_helper_gvec_vfene_cc16,
+gen_helper_gvec_vfene_cc32,
+};
+
+if (es > ES_32 || m5 & ~0x3) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m5, 0, 1)) {
+gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), cpu_env, m5, g_cc[es]);
+set_cc_static(s);
+} else {
+gen_gvec_3_ool(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), m5, g[es]);
+}
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec.h b/target/s390x/vec.h
index 3313fb43ee..affc62874c 100644
--- a/target/s390x/vec.h
+++ b/target/s390x/vec.h
@@ -12,6 +12,8 @@
 #ifndef S390X_VEC_H
 #define S390X_VEC_H
 
+#include "tcg/tcg.h"
+
 typedef union S390Vector {
 uint64_t doubleword[2];
 uint32_t word[4];
@@ -70,6 +72,23 @@ static inline uint64_t s390_vec_read_element64(const 
S390Vector *v, uint8_t enr)
 return v->doubleword[enr];
 }
 
+static inline uint64_t s390_vec_read_element(const S390Vector *v, uint8_t enr,
+ uint8_t es)
+{
+switch (es) {
+case MO_8:
+return s390_vec_read_element8(v, enr);
+case MO_16:
+return s390_vec_read_element16(v, enr);
+case MO_32:
+return s390_vec_read_element32(v, enr);
+case MO_64:
+return s390_vec_read_element64(v, enr);
+default:
+g_assert_not_reached();
+}
+}
+
 static inline void s390_vec_write_element8(S390Vector *v, uint8_t enr,
uint8_t data)
 {
diff --git a/target/s390x/vec_string_helper.c b/target/s390x/vec_string_helper.c
index 05ad99e173..0ee3470112 100644
--- a/target/s390x/vec_string_helper.c
+++ b/target/s390x/vec_string_helper.c
@@ -27,6 +27,15 @@ static inline uint64_t zero_search(uint64_t a, uint64_t mask)
 return ~(((a & mask) + mask) | a | mask);
 }
 
+/*
+ * Returns a bit set in the MSB of each element that is not zero,
+ * as defined by the mask.
+ */
+static inline uint64_t nonzero_search(uint64_t a, uint64_t mask)
+{
+return (((a & mask) + mask) | a) & ~mask;
+}
+
 /*
  * Returns the byte offset for the first match, or 16 for no match.
  */
@@ -209,3 +218,68 @@ void 

[Qemu-devel] [PULL SUBSYSTEM s390x 31/33] s390x: Bump the "qemu" CPU model up to a stripped-down z13

2019-06-05 Thread David Hildenbrand
We don't care about the other two missing base features:
- S390_FEAT_DFP_PACKED_CONVERSION
- S390_FEAT_GROUP_GEN13_PTFF

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 hw/s390x/s390-virtio-ccw.c  |  2 ++
 target/s390x/cpu_models.c   |  4 ++--
 target/s390x/gen-features.c | 11 +++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index bbc6e8fa0b..4d643686cb 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -669,7 +669,9 @@ DEFINE_CCW_MACHINE(4_1, "4.1", true);
 
 static void ccw_machine_4_0_instance_options(MachineState *machine)
 {
+static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_0 };
 ccw_machine_4_1_instance_options(machine);
+s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
 }
 
 static void ccw_machine_4_0_class_options(MachineClass *mc)
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 21ea819483..b5d16e4c89 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -86,8 +86,8 @@ static S390CPUDef s390_cpu_defs[] = {
 CPUDEF_INIT(0x8562, 15, 1, 47, 0x0800U, "gen15b", "IBM 8562 GA1"),
 };
 
-#define QEMU_MAX_CPU_TYPE 0x2827
-#define QEMU_MAX_CPU_GEN 12
+#define QEMU_MAX_CPU_TYPE 0x2964
+#define QEMU_MAX_CPU_GEN 13
 #define QEMU_MAX_CPU_EC_GA 2
 static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
 static S390FeatBitmap qemu_max_cpu_feat;
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index a818c80332..dc320a06c2 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -689,7 +689,7 @@ static uint16_t qemu_V3_1[] = {
 S390_FEAT_MSA_EXT_4,
 };
 
-static uint16_t qemu_LATEST[] = {
+static uint16_t qemu_V4_0[] = {
 /*
  * Only BFP bits are implemented (HFP, DFP, PFPO and DIVIDE TO INTEGER not
  * implemented yet).
@@ -698,11 +698,13 @@ static uint16_t qemu_LATEST[] = {
 S390_FEAT_ZPCI,
 };
 
-/* add all new definitions before this point */
-static uint16_t qemu_MAX[] = {
-/* z13+ features */
+static uint16_t qemu_LATEST[] = {
 S390_FEAT_STFLE_53,
 S390_FEAT_VECTOR,
+};
+
+/* add all new definitions before this point */
+static uint16_t qemu_MAX[] = {
 /* generates a dependency warning, leave it out for now */
 S390_FEAT_MSA_EXT_5,
 };
@@ -821,6 +823,7 @@ static FeatGroupDefSpec FeatGroupDef[] = {
 static FeatGroupDefSpec QemuFeatDef[] = {
 QEMU_FEAT_INITIALIZER(V2_11),
 QEMU_FEAT_INITIALIZER(V3_1),
+QEMU_FEAT_INITIALIZER(V4_0),
 QEMU_FEAT_INITIALIZER(LATEST),
 QEMU_FEAT_INITIALIZER(MAX),
 };
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 20/33] s390x/tcg: Implement VECTOR LOAD FP INTEGER

2019-06-05 Thread David Hildenbrand
We can reuse most of the infrastructure introduced for
VECTOR FP CONVERT FROM FIXED 64-BIT and friends.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 23 +++
 4 files changed, 30 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 238bfa2509..10a9cb39b6 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -276,6 +276,8 @@ DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfd64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index f9830deace..f77aa41253 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1228,6 +1228,8 @@
 F(0xe7c0, VCLGD,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR FP DIVIDE */
 F(0xe7e5, VFD, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
+/* VECTOR LOAD FP INTEGER */
+F(0xe7c7, VFI, VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 9e55d4488b..59d8b971c0 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2669,6 +2669,9 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
 case 0xc0:
 fn = se ? gen_helper_gvec_vclgd64s : gen_helper_gvec_vclgd64;
 break;
+case 0xc7:
+fn = se ? gen_helper_gvec_vfi64s : gen_helper_gvec_vfi64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 3c62eb5787..bdcafc6738 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -386,3 +386,26 @@ void HELPER(gvec_vfd64s)(void *v1, const void *v2, const 
void *v3,
 {
 vop64_3(v1, v2, v3, env, true, vfd64, GETPC());
 }
+
+static uint64_t vfi64(uint64_t a, float_status *s)
+{
+return float64_round_to_int(a, s);
+}
+
+void HELPER(gvec_vfi64)(void *v1, const void *v2, CPUS390XState *env,
+uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, false, XxC, erm, vfi64, GETPC());
+}
+
+void HELPER(gvec_vfi64s)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, true, XxC, erm, vfi64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 30/33] s390x/tcg: We support the Vector Facility

2019-06-05 Thread David Hildenbrand
Let's add it to the max model, so we can enable it.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/gen-features.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index c346b76bdf..a818c80332 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -702,6 +702,7 @@ static uint16_t qemu_LATEST[] = {
 static uint16_t qemu_MAX[] = {
 /* z13+ features */
 S390_FEAT_STFLE_53,
+S390_FEAT_VECTOR,
 /* generates a dependency warning, leave it out for now */
 S390_FEAT_MSA_EXT_5,
 };
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 13/33] s390x/tcg: Implement VECTOR FP COMPARE (AND SIGNAL) SCALAR

2019-06-05 Thread David Hildenbrand
As far as I can see, there is only a tiny difference.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  4 
 target/s390x/translate_vx.inc.c | 21 +
 target/s390x/vec_fpu_helper.c   | 32 
 4 files changed, 59 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 21658a2771..d34d6802a6 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -252,6 +252,8 @@ DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, 
cptr, env, i32)
 /* === Vector Floating-Point Instructions */
 DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
+DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 79892f6042..c45e101b10 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1208,6 +1208,10 @@
 
 /* VECTOR FP ADD */
 F(0xe7e3, VFA, VRR_c, V,   0, 0, 0, 0, vfa, 0, IF_VEC)
+/* VECTOR FP COMPARE SCALAR */
+F(0xe7cb, WFC, VRR_a, V,   0, 0, 0, 0, wfc, 0, IF_VEC)
+/* VECTOR FP COMPARE AND SIGNAL SCALAR */
+F(0xe7ca, WFK, VRR_a, V,   0, 0, 0, 0, wfc, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 44da9f2645..283e8aa07a 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2567,3 +2567,24 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
get_field(s->fields, v3), cpu_env, 0, fn);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_wfc(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m3);
+const uint8_t m4 = get_field(s->fields, m4);
+
+if (fpf != FPF_LONG || m4) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (s->fields->op2 == 0xcb) {
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   cpu_env, 0, gen_helper_gvec_wfc64);
+} else {
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   cpu_env, 0, gen_helper_gvec_wfk64);
+}
+set_cc_static(s);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index c7db0791d7..f9357d9221 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -117,3 +117,35 @@ void HELPER(gvec_vfa64s)(void *v1, const void *v2, const 
void *v3,
 {
 vop64_3(v1, v2, v3, env, true, vfa64, GETPC());
 }
+
+static int wfc64(const S390Vector *v1, const S390Vector *v2,
+ CPUS390XState *env, bool signal, uintptr_t retaddr)
+{
+/* only the zero-indexed elements are compared */
+const float64 a = s390_vec_read_element64(v1, 0);
+const float64 b = s390_vec_read_element64(v2, 0);
+uint8_t vxc, vec_exc = 0;
+int cmp;
+
+if (signal) {
+cmp = float64_compare(a, b, >fpu_status);
+} else {
+cmp = float64_compare_quiet(a, b, >fpu_status);
+}
+vxc = check_ieee_exc(env, 0, false, _exc);
+handle_ieee_exc(env, vxc, vec_exc, retaddr);
+
+return float_comp_to_cc(env, cmp);
+}
+
+void HELPER(gvec_wfc64)(const void *v1, const void *v2, CPUS390XState *env,
+uint32_t desc)
+{
+env->cc_op = wfc64(v1, v2, env, false, GETPC());
+}
+
+void HELPER(gvec_wfk64)(const void *v1, const void *v2, CPUS390XState *env,
+uint32_t desc)
+{
+env->cc_op = wfc64(v1, v2, env, true, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 26/33] s390x/tcg: Implement VECTOR FP SQUARE ROOT

2019-06-05 Thread David Hildenbrand
Simulate XxC=0 and ERM=0 (current mode), so we can use the existing
helper function.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c | 19 +++
 target/s390x/vec_fpu_helper.c   | 17 +
 4 files changed, 40 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index bcaabb91a5..23b37af1e4 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -288,6 +288,8 @@ DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, 
cptr, cptr, cptr, env
 DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
 DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
 DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, 
env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index fa2e801747..354252d57c 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1242,6 +1242,8 @@
 F(0xe78e, VFMS,VRR_e, V,   0, 0, 0, 0, vfma, 0, IF_VEC)
 /* VECTOR FP PERFORM SIGN OPERATION */
 F(0xe7cc, VFPSO,   VRR_a, V,   0, 0, 0, 0, vfpso, 0, IF_VEC)
+/* VECTOR FP SQUARE ROOT */
+F(0xe7ce, VFSQ,VRR_a, V,   0, 0, 0, 0, vfsq, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 9b8606ba25..75f3596c4b 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2779,3 +2779,22 @@ static DisasJumpType op_vfpso(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfsq(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m3);
+const uint8_t m4 = get_field(s->fields, m4);
+gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vfsq64;
+
+if (fpf != FPF_LONG || extract32(m4, 0, 3)) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m4, 3, 1)) {
+fn = gen_helper_gvec_vfsq64s;
+}
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2), cpu_env,
+   0, fn);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 7993a6fafa..18773eb559 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -552,3 +552,20 @@ void HELPER(gvec_vfms64s)(void *v1, const void *v2, const 
void *v3,
 {
 vfma64(v1, v2, v3, v4, env, true, float_muladd_negate_c, GETPC());
 }
+
+static uint64_t vfsq64(uint64_t a, float_status *s)
+{
+return float64_sqrt(a, s);
+}
+
+void HELPER(gvec_vfsq64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+vop64_2(v1, v2, env, false, false, 0, vfsq64, GETPC());
+}
+
+void HELPER(gvec_vfsq64s)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+vop64_2(v1, v2, env, true, false, 0, vfsq64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 18/33] s390x/tcg: Implement VECTOR FP CONVERT TO LOGICAL 64-BIT

2019-06-05 Thread David Hildenbrand
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c |  3 +++
 target/s390x/vec_fpu_helper.c   | 23 +++
 4 files changed, 30 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 9893c677da..9b9062970a 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -272,6 +272,8 @@ DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, 
cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcdlg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 97c62a8af5..ed8b888d59 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1224,6 +1224,8 @@
 F(0xe7c1, VCDLG,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 /* VECTOR FP CONVERT TO FIXED 64-BIT */
 F(0xe7c2, VCGD,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP CONVERT TO LOGICAL 64-BIT */
+F(0xe7c0, VCLGD,   VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index a42de2ff01..0395d69968 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2663,6 +2663,9 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
 case 0xc2:
 fn = se ? gen_helper_gvec_vcgd64s : gen_helper_gvec_vcgd64;
 break;
+case 0xc0:
+fn = se ? gen_helper_gvec_vclgd64s : gen_helper_gvec_vclgd64;
+break;
 default:
 g_assert_not_reached();
 }
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index e7251aca04..09ef0abfb0 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -346,3 +346,26 @@ void HELPER(gvec_vcgd64s)(void *v1, const void *v2, 
CPUS390XState *env,
 
 vop64_2(v1, v2, env, true, XxC, erm, vcgd64, GETPC());
 }
+
+static uint64_t vclgd64(uint64_t a, float_status *s)
+{
+return float64_to_uint64(a, s);
+}
+
+void HELPER(gvec_vclgd64)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, false, XxC, erm, vclgd64, GETPC());
+}
+
+void HELPER(gvec_vclgd64s)(void *v1, const void *v2, CPUS390XState *env,
+   uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC());
+}
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 15/33] s390x/tcg: Implement VECTOR FP CONVERT FROM FIXED 64-BIT

2019-06-05 Thread David Hildenbrand
1. We'll reuse op_vcdg() for similar instructions later, prepare for
   that.
2. We'll reuse vop64_2() later for other instructions.

We have to mangle the erm (effective rounding mode) and the m4 into
the simd_data(), and properly unmangle them again.

Make sure to restore the erm before triggering an exception.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h   |  2 ++
 target/s390x/insn-data.def  |  2 ++
 target/s390x/translate_vx.inc.c | 25 ++
 target/s390x/vec_fpu_helper.c   | 47 +
 4 files changed, 76 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 33d3bacf74..a60f4c49fc 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -266,6 +266,8 @@ DEF_HELPER_FLAGS_5(gvec_vfche64, TCG_CALL_NO_WG, void, ptr, 
cptr, cptr, env, i32
 DEF_HELPER_FLAGS_5(gvec_vfche64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, 
i32)
 DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfche64s_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vcdg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 446552f251..d3386024c8 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1218,6 +1218,8 @@
 F(0xe7eb, VFCH,VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
 /* VECTOR FP COMPARE HIGH OR EQUAL */
 F(0xe7ea, VFCHE,   VRR_c, V,   0, 0, 0, 0, vfc, 0, IF_VEC)
+/* VECTOR FP CONVERT FROM FIXED 64-BIT */
+F(0xe7c3, VCDG,VRR_a, V,   0, 0, 0, 0, vcdg, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 5571a71e1a..6741b707cc 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2639,3 +2639,28 @@ static DisasJumpType op_vfc(DisasContext *s, DisasOps *o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
+{
+const uint8_t fpf = get_field(s->fields, m3);
+const uint8_t m4 = get_field(s->fields, m4);
+const uint8_t erm = get_field(s->fields, m5);
+const bool se = extract32(m4, 3, 1);
+gen_helper_gvec_2_ptr *fn;
+
+if (fpf != FPF_LONG || extract32(m4, 0, 2) || erm > 7 || erm == 2) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+switch (s->fields->op2) {
+case 0xc3:
+fn = se ? gen_helper_gvec_vcdg64s : gen_helper_gvec_vcdg64;
+break;
+default:
+g_assert_not_reached();
+}
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2), cpu_env,
+   deposit32(m4, 4, 4, erm), fn);
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index e72500d4d5..53430c7843 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -78,6 +78,30 @@ static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, 
uint8_t vec_exc,
 }
 }
 
+typedef uint64_t (*vop64_2_fn)(uint64_t a, float_status *s);
+static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
+uintptr_t retaddr)
+{
+uint8_t vxc, vec_exc = 0;
+S390Vector tmp = {};
+int i, old_mode;
+
+old_mode = s390_swap_bfp_rounding_mode(env, erm);
+for (i = 0; i < 2; i++) {
+const uint64_t a = s390_vec_read_element64(v2, i);
+
+s390_vec_write_element64(, i, fn(a, >fpu_status));
+vxc = check_ieee_exc(env, i, XxC, _exc);
+if (s || vxc) {
+break;
+}
+}
+s390_restore_bfp_rounding_mode(env, old_mode);
+handle_ieee_exc(env, vxc, vec_exc, retaddr);
+*v1 = tmp;
+}
+
 typedef uint64_t (*vop64_3_fn)(uint64_t a, uint64_t b, float_status *s);
 static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
 CPUS390XState *env, bool s, vop64_3_fn fn,
@@ -253,3 +277,26 @@ void HELPER(gvec_vfche64s_cc)(void *v1, const void *v2, 
const void *v3,
 {
 env->cc_op = vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC());
 }
+
+static uint64_t vcdg64(uint64_t a, float_status *s)
+{
+return int64_to_float64(a, s);
+}
+
+void HELPER(gvec_vcdg64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 4);
+const bool XxC = extract32(simd_data(desc), 2, 1);
+
+vop64_2(v1, v2, env, false, XxC, erm, vcdg64, GETPC());
+}
+
+void HELPER(gvec_vcdg64s)(void *v1, const void *v2, CPUS390XState *env,
+  uint32_t desc)
+{
+const uint8_t erm = extract32(simd_data(desc), 4, 

[Qemu-devel] [PULL SUBSYSTEM s390x 05/33] s390x/tcg: Implement VECTOR STRING RANGE COMPARE

2019-06-05 Thread David Hildenbrand
Unfortunately, there is no easy way to avoid looping over all elements
in v2. Provide specialized variants for !cc,!rt/!cc,rt/cc,!rt/cc,rt and
all element types. Especially for different values of rt, the compiler
might be able to optimize the code a lot.

Add s390_vec_write_element().

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h|  12 +++
 target/s390x/insn-data.def   |   2 +
 target/s390x/translate_vx.inc.c  |  59 +
 target/s390x/vec.h   |  21 +
 target/s390x/vec_string_helper.c | 143 +++
 5 files changed, 237 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 1f9f0b463b..5db67779d3 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -236,6 +236,18 @@ DEF_HELPER_FLAGS_3(gvec_vistr32, TCG_CALL_NO_RWG, void, 
ptr, cptr, i32)
 DEF_HELPER_4(gvec_vistr_cc8, void, ptr, cptr, env, i32)
 DEF_HELPER_4(gvec_vistr_cc16, void, ptr, cptr, env, i32)
 DEF_HELPER_4(gvec_vistr_cc32, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc_rt8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
cptr, i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc_rt16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
cptr, i32)
+DEF_HELPER_FLAGS_5(gvec_vstrc_rt32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, 
cptr, i32)
+DEF_HELPER_6(gvec_vstrc_cc8, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_6(gvec_vstrc_cc16, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_6(gvec_vstrc_cc32, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_6(gvec_vstrc_cc_rt8, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_6(gvec_vstrc_cc_rt16, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index b4a6b59608..a2969fab58 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1201,6 +1201,8 @@
 F(0xe781, VFENE,   VRR_b, V,   0, 0, 0, 0, vfene, 0, IF_VEC)
 /* VECTOR ISOLATE STRING */
 F(0xe75c, VISTR,   VRR_a, V,   0, 0, 0, 0, vistr, 0, IF_VEC)
+/* VECTOR STRING RANGE COMPARE */
+F(0xe78a, VSTRC,   VRR_d, V,   0, 0, 0, 0, vstrc, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 08a62eab52..f26ffa2895 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -217,6 +217,10 @@ static void get_vec_element_ptr_i64(TCGv_ptr ptr, uint8_t 
reg, TCGv_i64 enr,
 tcg_gen_gvec_4_ool(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
vec_full_reg_offset(v3), vec_full_reg_offset(v4), \
16, 16, data, fn)
+#define gen_gvec_4_ptr(v1, v2, v3, v4, ptr, data, fn) \
+tcg_gen_gvec_4_ptr(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+   vec_full_reg_offset(v3), vec_full_reg_offset(v4), \
+   ptr, 16, 16, data, fn)
 #define gen_gvec_dup_i64(es, v1, c) \
 tcg_gen_gvec_dup_i64(es, vec_full_reg_offset(v1), 16, 16, c)
 #define gen_gvec_mov(v1, v2) \
@@ -2479,3 +2483,58 @@ static DisasJumpType op_vistr(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vstrc(DisasContext *s, DisasOps *o)
+{
+const uint8_t es = get_field(s->fields, m5);
+const uint8_t m6 = get_field(s->fields, m6);
+static gen_helper_gvec_4 * const g[3] = {
+gen_helper_gvec_vstrc8,
+gen_helper_gvec_vstrc16,
+gen_helper_gvec_vstrc32,
+};
+static gen_helper_gvec_4 * const g_rt[3] = {
+gen_helper_gvec_vstrc_rt8,
+gen_helper_gvec_vstrc_rt16,
+gen_helper_gvec_vstrc_rt32,
+};
+static gen_helper_gvec_4_ptr * const g_cc[3] = {
+gen_helper_gvec_vstrc_cc8,
+gen_helper_gvec_vstrc_cc16,
+gen_helper_gvec_vstrc_cc32,
+};
+static gen_helper_gvec_4_ptr * const g_cc_rt[3] = {
+gen_helper_gvec_vstrc_cc_rt8,
+gen_helper_gvec_vstrc_cc_rt16,
+gen_helper_gvec_vstrc_cc_rt32,
+};
+
+if (es > ES_32) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m6, 0, 1)) {
+if (extract32(m6, 2, 1)) {
+gen_gvec_4_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), get_field(s->fields, v4),
+   cpu_env, m6, g_cc_rt[es]);
+} else {
+gen_gvec_4_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, 

[Qemu-devel] [PULL SUBSYSTEM s390x 08/33] s390x/tcg: Fix max_byte detection for stfle

2019-06-05 Thread David Hildenbrand
used_stfl_bytes is 0, before initialized via prepare_stfl() on the
first invocation. We have to move the calculation of max_bytes after
prepare_stfl().

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/misc_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index ee67c1fa0c..34476134a4 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -669,7 +669,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
 {
 const uintptr_t ra = GETPC();
 const int count_bytes = ((env->regs[0] & 0xff) + 1) * 8;
-const int max_bytes = ROUND_UP(used_stfl_bytes, 8);
+int max_bytes;
 int i;
 
 if (addr & 0x7) {
@@ -677,6 +677,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
 }
 
 prepare_stfl();
+max_bytes = ROUND_UP(used_stfl_bytes, 8);
 for (i = 0; i < count_bytes; ++i) {
 cpu_stb_data_ra(env, addr + i, stfl_bytes[i], ra);
 }
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 29/33] s390x/tcg: Allow linux-user to use vector instructions

2019-06-05 Thread David Hildenbrand
Once we unlock S390_FEAT_VECTOR for TCG, we want linux-user to be
able to make use of it.

Reviewed-by: Richard Henderson 
Reviewed-by: Laurent Vivier 
Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index b1df63d82c..6af1a1530f 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -145,6 +145,9 @@ static void s390_cpu_full_reset(CPUState *s)
 #if defined(CONFIG_USER_ONLY)
 /* user mode should always be allowed to use the full FPU */
 env->cregs[0] |= CR0_AFP;
+if (s390_has_feat(S390_FEAT_VECTOR)) {
+env->cregs[0] |= CR0_VECTOR;
+}
 #endif
 
 /* architectured initial value for Breaking-Event-Address register */
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 09/33] s390x/tcg: Store only the necessary amount of doublewords for STFLE

2019-06-05 Thread David Hildenbrand
The PoP (z14, 7-382) says:
Doublewords to the right of the doubleword in which the
highest-numbered facility bit is assigned for a model
may or may not be stored.

However, stack protection in certain binaries can't deal with that.
"gzip" example code:

f1b4:   a7 08 00 03 lhi %r0,3
f1b8:   b2 b0 f0 a0 stfle   160(%r15)
f1bc:   e3 20 f0 b2 00 90   llgc%r2,178(%r15)
f1c2:   c0 2b 00 00 00 01   nilf%r2,1
f1c8:   b2 4f 00 10 ear %r1,%a0
f1cc:   b9 14 00 22 lgfr%r2,%r2
f1d0:   eb 11 00 20 00 0d   sllg%r1,%r1,32
f1d6:   b2 4f 00 11 ear %r1,%a1
f1da:   d5 07 f0 b8 10 28   clc 184(8,%r15),40(%r1)
f1e0:   a7 74 00 06 jne f1ec 
f1e4:   eb ef f1 30 00 04   lmg %r14,%r15,304(%r15)
f1ea:   07 fe   br  %r14
f1ec:   c0 e5 ff ff 9d 6e   brasl   %r14,2cc8 <__stack_chk_fail@plt>

In QEMU, we currently have:
max_bytes = 24
the code asks for (3 + 1) doublewords == 32 bytes.

If we write 32 bytes instead of only 24, and return "2 + 1" doublewords
("one less than the number of doulewords needed to contain all of the
 facility bits"), the example code detects a stack corruption.

In my opinion, the code is wrong. However, it seems to work fine on
real machines. So let's limit storing to the minimum of the requested
and the maximum doublewords.

Cc: Stefan Liebler 
Cc: Andreas Krebbel 
Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/misc_helper.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index 34476134a4..10aa617cf9 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -678,7 +678,13 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
 
 prepare_stfl();
 max_bytes = ROUND_UP(used_stfl_bytes, 8);
-for (i = 0; i < count_bytes; ++i) {
+
+/*
+ * The PoP says that doublewords beyond the highest-numbered facility
+ * bit may or may not be stored.  However, existing hardware appears to
+ * not store the words, and existing software depend on that.
+ */
+for (i = 0; i < MIN(count_bytes, max_bytes); ++i) {
 cpu_stb_data_ra(env, addr + i, stfl_bytes[i], ra);
 }
 
-- 
2.21.0




[Qemu-devel] [PULL SUBSYSTEM s390x 02/33] s390x/tcg: Implement VECTOR FIND ELEMENT EQUAL

2019-06-05 Thread David Hildenbrand
Core logic courtesy of Richard H.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h|  6 
 target/s390x/insn-data.def   |  2 ++
 target/s390x/translate_vx.inc.c  | 31 +
 target/s390x/vec_string_helper.c | 57 
 4 files changed, 96 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index c45328cf73..a1b169b666 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -218,6 +218,12 @@ DEF_HELPER_FLAGS_4(gvec_vfae32, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
 DEF_HELPER_5(gvec_vfae_cc8, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfae_cc16, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfae_cc32, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfee8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfee16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfee32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_5(gvec_vfee_cc8, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfee_cc16, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfee_cc32, void, ptr, cptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 070ce2a471..d8907ef6a5 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1195,6 +1195,8 @@
 
 /* VECTOR FIND ANY ELEMENT EQUAL */
 F(0xe782, VFAE,VRR_b, V,   0, 0, 0, 0, vfae, 0, IF_VEC)
+/* VECTOR FIND ELEMENT EQUAL */
+F(0xe780, VFEE,VRR_b, V,   0, 0, 0, 0, vfee, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index ebd7a877f1..b25afbc011 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2383,3 +2383,34 @@ static DisasJumpType op_vfae(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfee(DisasContext *s, DisasOps *o)
+{
+const uint8_t es = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+static gen_helper_gvec_3 * const g[3] = {
+gen_helper_gvec_vfee8,
+gen_helper_gvec_vfee16,
+gen_helper_gvec_vfee32,
+};
+static gen_helper_gvec_3_ptr * const g_cc[3] = {
+gen_helper_gvec_vfee_cc8,
+gen_helper_gvec_vfee_cc16,
+gen_helper_gvec_vfee_cc32,
+};
+
+if (es > ES_32 || m5 & ~0x3) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m5, 0, 1)) {
+gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), cpu_env, m5, g_cc[es]);
+set_cc_static(s);
+} else {
+gen_gvec_3_ool(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), m5, g[es]);
+}
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_string_helper.c b/target/s390x/vec_string_helper.c
index 56dc89c824..05ad99e173 100644
--- a/target/s390x/vec_string_helper.c
+++ b/target/s390x/vec_string_helper.c
@@ -152,3 +152,60 @@ void HELPER(gvec_vfae_cc##BITS)(void *v1, const void *v2, 
const void *v3,  \
 DEF_VFAE_CC_HELPER(8)
 DEF_VFAE_CC_HELPER(16)
 DEF_VFAE_CC_HELPER(32)
+
+static int vfee(void *v1, const void *v2, const void *v3, bool zs, uint8_t es)
+{
+const uint64_t mask = get_element_lsbs_mask(es);
+uint64_t a0, a1, b0, b1, e0, e1, z0, z1;
+uint64_t first_zero = 16;
+uint64_t first_equal;
+
+a0 = s390_vec_read_element64(v2, 0);
+a1 = s390_vec_read_element64(v2, 1);
+b0 = s390_vec_read_element64(v3, 0);
+b1 = s390_vec_read_element64(v3, 1);
+e0 = zero_search(a0 ^ b0, mask);
+e1 = zero_search(a1 ^ b1, mask);
+first_equal = match_index(e0, e1);
+
+if (zs) {
+z0 = zero_search(a0, mask);
+z1 = zero_search(a1, mask);
+first_zero = match_index(z0, z1);
+}
+
+s390_vec_write_element64(v1, 0, MIN(first_equal, first_zero));
+s390_vec_write_element64(v1, 1, 0);
+if (first_zero == 16 && first_equal == 16) {
+return 3; /* no match */
+} else if (first_zero == 16) {
+return 1; /* matching elements, no match for zero */
+} else if (first_equal < first_zero) {
+return 2; /* matching elements before match for zero */
+}
+return 0; /* match for zero */
+}
+
+#define DEF_VFEE_HELPER(BITS)  
\
+void HELPER(gvec_vfee##BITS)(void *v1, const void *v2, const void *v3, 
\
+ uint32_t desc)
\
+{  
\
+const bool zs = extract32(simd_data(desc), 1, 1);  
\
+  

[Qemu-devel] [PULL SUBSYSTEM s390x 07/33] s390x: Use uint64_t for vector registers

2019-06-05 Thread David Hildenbrand
CPU_DoubleU is primarily used to reinterpret between integer and floats.
We don't really need this functionality. So let's just keep it simple
and use an uint64_t.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 linux-user/s390x/signal.c  |   4 +-
 target/s390x/arch_dump.c   |   8 +--
 target/s390x/cpu.h |   4 +-
 target/s390x/excp_helper.c |   6 +-
 target/s390x/gdbstub.c |  16 ++---
 target/s390x/helper.c  |  10 +--
 target/s390x/kvm.c |  16 ++---
 target/s390x/machine.c | 128 ++---
 target/s390x/translate.c   |   2 +-
 9 files changed, 97 insertions(+), 97 deletions(-)

diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c
index 3d3cb67bbe..ecfa2a14a9 100644
--- a/linux-user/s390x/signal.c
+++ b/linux-user/s390x/signal.c
@@ -123,7 +123,7 @@ static void save_sigregs(CPUS390XState *env, target_sigregs 
*sregs)
  */
 //save_fp_regs(>thread.fp_regs); FIXME
 for (i = 0; i < 16; i++) {
-__put_user(get_freg(env, i)->ll, >fpregs.fprs[i]);
+__put_user(*get_freg(env, i), >fpregs.fprs[i]);
 }
 }
 
@@ -254,7 +254,7 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc)
 __get_user(env->aregs[i], >regs.acrs[i]);
 }
 for (i = 0; i < 16; i++) {
-__get_user(get_freg(env, i)->ll, >fpregs.fprs[i]);
+__get_user(*get_freg(env, i), >fpregs.fprs[i]);
 }
 
 return err;
diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index c9ef0a6e60..50fa0ae4b6 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -104,7 +104,7 @@ static void s390x_write_elf64_fpregset(Note *note, S390CPU 
*cpu, int id)
 note->hdr.n_type = cpu_to_be32(NT_FPREGSET);
 note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc);
 for (i = 0; i <= 15; i++) {
-note->contents.fpregset.fprs[i] = cpu_to_be64(get_freg(cs, i)->ll);
+note->contents.fpregset.fprs[i] = cpu_to_be64(*get_freg(cs, i));
 }
 }
 
@@ -114,7 +114,7 @@ static void s390x_write_elf64_vregslo(Note *note, S390CPU 
*cpu,  int id)
 
 note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_LOW);
 for (i = 0; i <= 15; i++) {
-note->contents.vregslo.vregs[i] = cpu_to_be64(cpu->env.vregs[i][1].ll);
+note->contents.vregslo.vregs[i] = cpu_to_be64(cpu->env.vregs[i][1]);
 }
 }
 
@@ -127,8 +127,8 @@ static void s390x_write_elf64_vregshi(Note *note, S390CPU 
*cpu, int id)
 
 note->hdr.n_type = cpu_to_be32(NT_S390_VXRS_HIGH);
 for (i = 0; i <= 15; i++) {
-temp_vregshi->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i + 16][0].ll);
-temp_vregshi->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i + 16][1].ll);
+temp_vregshi->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i + 16][0]);
+temp_vregshi->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i + 16][1]);
 }
 }
 
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 1bed12b6c3..317a1377e6 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -66,7 +66,7 @@ struct CPUS390XState {
  * The floating point registers are part of the vector registers.
  * vregs[0][0] -> vregs[15][0] are 16 floating point registers
  */
-CPU_DoubleU vregs[32][2] QEMU_ALIGNED(16);  /* vector registers */
+uint64_t vregs[32][2] QEMU_ALIGNED(16);  /* vector registers */
 uint32_t aregs[16];/* access registers */
 uint8_t riccb[64]; /* runtime instrumentation control */
 uint64_t gscb[4];  /* guarded storage control */
@@ -153,7 +153,7 @@ struct CPUS390XState {
 
 };
 
-static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr)
+static inline uint64_t *get_freg(CPUS390XState *cs, int nr)
 {
 return >vregs[nr][0];
 }
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 3a467b72c5..85223d00c0 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -390,8 +390,8 @@ static int mchk_store_vregs(CPUS390XState *env, uint64_t 
mcesao)
 }
 
 for (i = 0; i < 32; i++) {
-sa->vregs[i][0] = cpu_to_be64(env->vregs[i][0].ll);
-sa->vregs[i][1] = cpu_to_be64(env->vregs[i][1].ll);
+sa->vregs[i][0] = cpu_to_be64(env->vregs[i][0]);
+sa->vregs[i][1] = cpu_to_be64(env->vregs[i][1]);
 }
 
 cpu_physical_memory_unmap(sa, len, 1, len);
@@ -429,7 +429,7 @@ static void do_mchk_interrupt(CPUS390XState *env)
 lowcore->ar_access_id = 1;
 
 for (i = 0; i < 16; i++) {
-lowcore->floating_pt_save_area[i] = cpu_to_be64(get_freg(env, i)->ll);
+lowcore->floating_pt_save_area[i] = cpu_to_be64(*get_freg(env, i));
 lowcore->gpregs_save_area[i] = cpu_to_be64(env->regs[i]);
 lowcore->access_regs_save_area[i] = cpu_to_be32(env->aregs[i]);
 lowcore->cregs_save_area[i] = cpu_to_be64(env->cregs[i]);
diff --git a/target/s390x/gdbstub.c b/target/s390x/gdbstub.c
index df147596ce..9cfd8fe3e0 100644
--- a/target/s390x/gdbstub.c
+++ b/target/s390x/gdbstub.c
@@ -116,7 +116,7 @@ 

[Qemu-devel] [PULL SUBSYSTEM s390x 01/33] s390x/tcg: Implement VECTOR FIND ANY ELEMENT EQUAL

2019-06-05 Thread David Hildenbrand
Complicated stuff. Provide two different helpers for CC an !CC handling.
We might want to add more helpers later.

zero_search() and match_index() are courtesy of Richard H.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/Makefile.objs   |   2 +-
 target/s390x/helper.h|   8 ++
 target/s390x/insn-data.def   |   5 +
 target/s390x/translate_vx.inc.c  |  30 ++
 target/s390x/vec_string_helper.c | 154 +++
 5 files changed, 198 insertions(+), 1 deletion(-)
 create mode 100644 target/s390x/vec_string_helper.c

diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
index 0316457880..ffdd484ef0 100644
--- a/target/s390x/Makefile.objs
+++ b/target/s390x/Makefile.objs
@@ -1,7 +1,7 @@
 obj-y += cpu.o cpu_models.o cpu_features.o gdbstub.o interrupt.o helper.o
 obj-$(CONFIG_TCG) += translate.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o crypto_helper.o
-obj-$(CONFIG_TCG) += vec_helper.o vec_int_helper.o
+obj-$(CONFIG_TCG) += vec_helper.o vec_int_helper.o vec_string_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o
 obj-$(CONFIG_SOFTMMU) += sigp.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 7755a96c33..c45328cf73 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -211,6 +211,14 @@ DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
 DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
 DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
 
+/* === Vector String Instructions === */
+DEF_HELPER_FLAGS_4(gvec_vfae8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfae16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_FLAGS_4(gvec_vfae32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
+DEF_HELPER_5(gvec_vfae_cc8, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfae_cc16, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfae_cc32, void, ptr, cptr, cptr, env, i32)
+
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
 DEF_HELPER_4(diag, void, env, i32, i32, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index e61475bdc4..070ce2a471 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1191,6 +1191,11 @@
 /* VECTOR TEST UNDER MASK */
 F(0xe7d8, VTM, VRR_a, V,   0, 0, 0, 0, vtm, 0, IF_VEC)
 
+/* === Vector String Instructions === */
+
+/* VECTOR FIND ANY ELEMENT EQUAL */
+F(0xe782, VFAE,VRR_b, V,   0, 0, 0, 0, vfae, 0, IF_VEC)
+
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
 E(0xb250, CSP, RRE,   Z,   r1_32u, ra2, r1_P, 0, csp, 0, MO_TEUL, 
IF_PRIV)
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 7e0bfcb190..ebd7a877f1 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -2353,3 +2353,33 @@ static DisasJumpType op_vtm(DisasContext *s, DisasOps *o)
 set_cc_static(s);
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vfae(DisasContext *s, DisasOps *o)
+{
+const uint8_t es = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+static gen_helper_gvec_3 * const g[3] = {
+gen_helper_gvec_vfae8,
+gen_helper_gvec_vfae16,
+gen_helper_gvec_vfae32,
+};
+static gen_helper_gvec_3_ptr * const g_cc[3] = {
+gen_helper_gvec_vfae_cc8,
+gen_helper_gvec_vfae_cc16,
+gen_helper_gvec_vfae_cc32,
+};
+if (es > ES_32) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m5, 0, 1)) {
+gen_gvec_3_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), cpu_env, m5, g_cc[es]);
+set_cc_static(s);
+} else {
+gen_gvec_3_ool(get_field(s->fields, v1), get_field(s->fields, v2),
+   get_field(s->fields, v3), m5, g[es]);
+}
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_string_helper.c b/target/s390x/vec_string_helper.c
new file mode 100644
index 00..56dc89c824
--- /dev/null
+++ b/target/s390x/vec_string_helper.c
@@ -0,0 +1,154 @@
+/*
+ * QEMU TCG support -- s390x vector string instruction support
+ *
+ * Copyright (C) 2019 Red Hat Inc
+ *
+ * Authors:
+ *   David Hildenbrand 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "internal.h"
+#include "vec.h"
+#include "tcg/tcg.h"
+#include "tcg/tcg-gvec-desc.h"
+#include "exec/helper-proto.h"
+
+/*
+ * Returns a bit set in the MSB of each element that is zero,
+ * as defined by the mask.
+ */
+static inline uint64_t zero_search(uint64_t a, uint64_t mask)
+{
+

[Qemu-devel] [PULL SUBSYSTEM s390x 04/33] s390x/tcg: Implement VECTOR ISOLATE STRING

2019-06-05 Thread David Hildenbrand
Logic mostly courtesy of Richard H.

Reviewed-by: Richard Henderson 
Signed-off-by: David Hildenbrand 
---
 target/s390x/helper.h|  6 +
 target/s390x/insn-data.def   |  2 ++
 target/s390x/translate_vx.inc.c  | 34 
 target/s390x/vec_string_helper.c | 45 
 4 files changed, 87 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index fb50b404db..1f9f0b463b 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -230,6 +230,12 @@ DEF_HELPER_FLAGS_4(gvec_vfene32, TCG_CALL_NO_RWG, void, 
ptr, cptr, cptr, i32)
 DEF_HELPER_5(gvec_vfene_cc8, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfene_cc16, void, ptr, cptr, cptr, env, i32)
 DEF_HELPER_5(gvec_vfene_cc32, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_3(gvec_vistr8, TCG_CALL_NO_RWG, void, ptr, cptr, i32)
+DEF_HELPER_FLAGS_3(gvec_vistr16, TCG_CALL_NO_RWG, void, ptr, cptr, i32)
+DEF_HELPER_FLAGS_3(gvec_vistr32, TCG_CALL_NO_RWG, void, ptr, cptr, i32)
+DEF_HELPER_4(gvec_vistr_cc8, void, ptr, cptr, env, i32)
+DEF_HELPER_4(gvec_vistr_cc16, void, ptr, cptr, env, i32)
+DEF_HELPER_4(gvec_vistr_cc32, void, ptr, cptr, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index d03c1ee0b3..b4a6b59608 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1199,6 +1199,8 @@
 F(0xe780, VFEE,VRR_b, V,   0, 0, 0, 0, vfee, 0, IF_VEC)
 /* VECTOR FIND ELEMENT NOT EQUAL */
 F(0xe781, VFENE,   VRR_b, V,   0, 0, 0, 0, vfene, 0, IF_VEC)
+/* VECTOR ISOLATE STRING */
+F(0xe75c, VISTR,   VRR_a, V,   0, 0, 0, 0, vistr, 0, IF_VEC)
 
 #ifndef CONFIG_USER_ONLY
 /* COMPARE AND SWAP AND PURGE */
diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
index 1ad0b62517..08a62eab52 100644
--- a/target/s390x/translate_vx.inc.c
+++ b/target/s390x/translate_vx.inc.c
@@ -188,6 +188,9 @@ static void get_vec_element_ptr_i64(TCGv_ptr ptr, uint8_t 
reg, TCGv_i64 enr,
 #define gen_gvec_2s(v1, v2, c, gen) \
 tcg_gen_gvec_2s(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
 16, 16, c, gen)
+#define gen_gvec_2_ool(v1, v2, data, fn) \
+tcg_gen_gvec_2_ool(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
+   16, 16, data, fn)
 #define gen_gvec_2i_ool(v1, v2, c, data, fn) \
 tcg_gen_gvec_2i_ool(vec_full_reg_offset(v1), vec_full_reg_offset(v2), \
 c, 16, 16, data, fn)
@@ -2445,3 +2448,34 @@ static DisasJumpType op_vfene(DisasContext *s, DisasOps 
*o)
 }
 return DISAS_NEXT;
 }
+
+static DisasJumpType op_vistr(DisasContext *s, DisasOps *o)
+{
+const uint8_t es = get_field(s->fields, m4);
+const uint8_t m5 = get_field(s->fields, m5);
+static gen_helper_gvec_2 * const g[3] = {
+gen_helper_gvec_vistr8,
+gen_helper_gvec_vistr16,
+gen_helper_gvec_vistr32,
+};
+static gen_helper_gvec_2_ptr * const g_cc[3] = {
+gen_helper_gvec_vistr_cc8,
+gen_helper_gvec_vistr_cc16,
+gen_helper_gvec_vistr_cc32,
+};
+
+if (es > ES_32 || m5 & ~0x1) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
+
+if (extract32(m5, 0, 1)) {
+gen_gvec_2_ptr(get_field(s->fields, v1), get_field(s->fields, v2),
+   cpu_env, 0, g_cc[es]);
+set_cc_static(s);
+} else {
+gen_gvec_2_ool(get_field(s->fields, v1), get_field(s->fields, v2), 0,
+   g[es]);
+}
+return DISAS_NEXT;
+}
diff --git a/target/s390x/vec_string_helper.c b/target/s390x/vec_string_helper.c
index 0ee3470112..6bafa23bd7 100644
--- a/target/s390x/vec_string_helper.c
+++ b/target/s390x/vec_string_helper.c
@@ -283,3 +283,48 @@ void HELPER(gvec_vfene_cc##BITS)(void *v1, const void *v2, 
const void *v3, \
 DEF_VFENE_CC_HELPER(8)
 DEF_VFENE_CC_HELPER(16)
 DEF_VFENE_CC_HELPER(32)
+
+static int vistr(void *v1, const void *v2, uint8_t es)
+{
+const uint64_t mask = get_element_lsbs_mask(es);
+uint64_t a0 = s390_vec_read_element64(v2, 0);
+uint64_t a1 = s390_vec_read_element64(v2, 1);
+uint64_t z;
+int cc = 3;
+
+z = zero_search(a0, mask);
+if (z) {
+a0 &= ~(-1ull >> clz64(z));
+a1 = 0;
+cc = 0;
+} else {
+z = zero_search(a1, mask);
+if (z) {
+a1 &= ~(-1ull >> clz64(z));
+cc = 0;
+}
+}
+
+s390_vec_write_element64(v1, 0, a0);
+s390_vec_write_element64(v1, 1, a1);
+return cc;
+}
+
+#define DEF_VISTR_HELPER(BITS) 
\
+void HELPER(gvec_vistr##BITS)(void *v1, const void *v2, uint32_t desc) 
\
+{  
\
+vistr(v1, v2, MO_##BITS);  
\
+}
+DEF_VISTR_HELPER(8)

  1   2   3   4   >