Re: [PATCH] spapr/xive: Allocate IPIs from the vCPU contexts

2020-08-15 Thread David Gibson
On Fri, Aug 14, 2020 at 05:08:13PM +0200, Cédric Le Goater wrote:
> 
> This works as expected with a 128 vCPUs guest with pinned vcpus. The
> first 64 IPIs are allocated on the first chip and the remaining 64
> on the second chip.
> 
> Still, this is more an RFC. We have time before the end of the merge
> window.

It looks reasonable to me.  AFAICT it makes things better than they
were, and even if we can improve it further, that won't break
migration or other interfaces we need to preserve.

> 
> Thanks,
> 
> C.  
> 
> 
> On 8/14/20 5:03 PM, Cédric Le Goater wrote:
> > When QEMU switches to the XIVE interrupt mode, it performs a
> > kvmppc_xive_source_reset() which creates all the guest interrupts at
> > the level of the KVM device. These interrupts are backed by real HW
> > interrupts from the IPI interrupt pool of the XIVE controller.
> > 
> > Currently, this is done from the QEMU main thread, which results in
> > allocating all interrupts from the chip on which QEMU is running. IPIs
> > are not distributed across the system and the load is not well
> > balanced across the interrupt controllers.
> > 
> > Change the vCPU IPI allocation to run from the vCPU context in order
> > to allocate the associated XIVE IPI interrupt on the chip on which the
> > vCPU is running. This gives a chance to a better distribution of the
> > IPIs when the guest has a lot of vCPUs. When the vCPUs are pinned, it
> > makes the IPI local to the chip of the vCPU which reduces rerouting
> > between interrupt controllers and gives better performance.
> > 
> > This is only possible for running vCPUs. The IPIs of hot plugable
> > vCPUs will still be allocated in the context of the QEMU main thread.
> > 
> > Device interrupts are treated the same. To improve placement, we would
> > need some information on the chip owning the virtual source or HW
> > source in case of passthrough. This requires changes in PAPR.
> > 
> > Signed-off-by: Cédric Le Goater 
> > ---
> >  hw/intc/spapr_xive_kvm.c | 50 
> >  1 file changed, 50 insertions(+)
> > 
> > diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> > index c6958f2da218..553fd7fd8f56 100644
> > --- a/hw/intc/spapr_xive_kvm.c
> > +++ b/hw/intc/spapr_xive_kvm.c
> > @@ -223,6 +223,47 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t 
> > lisn, Error **errp)
> >NULL, true, errp);
> >  }
> >  
> > +/*
> > + * Allocate the IPIs from the vCPU context. This will allocate the
> > + * XIVE IPI interrupt on the chip on which the vCPU is running. This
> > + * gives a better distribution of IPIs when the guest has a lot of
> > + * vCPUs. When the vCPU are pinned, the IPIs are local which reduces
> > + * rerouting between interrupt controllers and gives better
> > + * performance.
> > + */
> > +typedef struct {
> > +SpaprXive *xive;
> > +int ipi;
> > +Error *err;
> > +int rc;
> > +} XiveInitIPI;
> > +
> > +static void kvmppc_xive_reset_ipi_on_cpu(CPUState *cs, run_on_cpu_data arg)
> > +{
> > +XiveInitIPI *s = arg.host_ptr;
> > +uint64_t state = 0;
> > +
> > +s->rc = kvm_device_access(s->xive->fd, KVM_DEV_XIVE_GRP_SOURCE, s->ipi,
> > +  &state, true, &s->err);
> > +}
> > +
> > +static int kvmppc_xive_reset_ipi(SpaprXive *xive, int ipi, Error **errp)
> > +{
> > +PowerPCCPU *cpu = spapr_find_cpu(ipi);
> > +XiveInitIPI s = {
> > +.xive = xive,
> > +.ipi  = ipi,
> > +.err  = NULL,
> > +.rc   = 0,
> > +};
> > +
> > +run_on_cpu(CPU(cpu), kvmppc_xive_reset_ipi_on_cpu, 
> > RUN_ON_CPU_HOST_PTR(&s));
> > +if (s.err) {
> > +error_propagate(errp, s.err);
> > +}
> > +return s.rc;
> > +}
> > +
> >  /*
> >   * At reset, the interrupt sources are simply created and MASKED. We
> >   * only need to inform the KVM XIVE device about their type: LSI or
> > @@ -230,11 +271,20 @@ void kvmppc_xive_sync_source(SpaprXive *xive, 
> > uint32_t lisn, Error **errp)
> >   */
> >  int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
> >  {
> > +MachineState *machine = MACHINE(qdev_get_machine());
> >  SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
> >  uint64_t state = 0;
> >  
> >  assert(xive->fd != -1);
> >  
> > +/*
> > + * IPIs are special. Allocate the IPIs from the vCPU context for
> > + * those running. Hotplugged CPUs will the QEMU context.
> > + */
> > +if (srcno < machine->smp.cpus) {
> > +return kvmppc_xive_reset_ipi(xive, srcno, errp);
> > +}
> > +
> >  if (xive_source_irq_is_lsi(xsrc, srcno)) {
> >  state |= KVM_XIVE_LEVEL_SENSITIVE;
> >  if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) {
> > 
> 

-- 
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


s

[PATCH v4] qapi/opts-visitor: Fixed fallthrough compiler warning

2020-08-15 Thread Rohit Shinde
Added fallthrough comment on line 270 to fix compiler warning

Signed-off-by: Rohit Shinde 
---
 qapi/opts-visitor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 43cf60d3a0..3422ff265e 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -266,7 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
 }
 ov->list_mode = LM_IN_PROGRESS;
 /* range has been completed, fall through in order to pop option */
-__attribute__((fallthrough));
+/* fallthrough */
 
 case LM_IN_PROGRESS: {
 const QemuOpt *opt;
-- 
2.25.1




Re: [RFC v3 26/71] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns

2020-08-15 Thread Frank Chang
On Sat, Aug 15, 2020 at 1:29 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 8/14/20 7:52 PM, Frank Chang wrote:
> > probe_pages(env, base + stride * i, nf * esz, ra, access_type);
> > and
> > target_ulong addr = base + stride * i + k * esz;
> >
> > If we pass ctzl(sizeof(type)) in GEN_VEXT_LD_STRIDE(),
> > I would still have to do: (1 << esz) to get the correct element size in
> the
> > above calculations.
> > Would it eliminate the performance gain we have in vext_max_elems()
> instead?
>
> Well, no, it will improve performance, because you'll write
>
>   addr = base + stride * i + (k << esz)
>
> I.e. strength-reduce the multiply to a shift.
>
>
This works like a charm.
Thanks for the advice.

Frank Chang



> r~
>
>


Re: [PATCH 12/12] test-util-sockets: Fix a memleak in test_socket_unix_abstract_good

2020-08-15 Thread Pan Nengyuan



On 2020/8/14 22:50, Li Qiang wrote:
> Pan Nengyuan  于2020年8月14日周五 下午6:18写道:
>>
>> Fix a memleak in test_socket_unix_abstract_good().
>>
>> Reported-by: Euler Robot 
>> Signed-off-by: Pan Nengyuan 
>> ---
> 
> Hi Nengyuan,
> I have sent this two month ago:
> -->https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg00809.html
> 
> seems the maintainer forget to push it to upstream.

Yes, it's the same. Let's ignore this one.

Thanks.

> 
> Thanks,
> Li Qiang
> 
> 
>>  tests/test-util-sockets.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
>> index 261dc48c03..5c4204a130 100644
>> --- a/tests/test-util-sockets.c
>> +++ b/tests/test-util-sockets.c
>> @@ -312,6 +312,7 @@ static void test_socket_unix_abstract_good(void)
>>  g_thread_join(cli);
>>  g_thread_join(serv);
>>
>> +g_rand_free(r);
>>  g_free(abstract_sock_name);
>>  }
>>  #endif
>> --
>> 2.18.2
>>
>>




Re: [PATCH v2 00/10] *** A Method for evaluating dirty page rate ***

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1597458180-16945-1-git-send-email-zhengch...@huawei.com/



Hi,

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

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

  TESTcheck-unit: tests/test-char
Unexpected error in object_property_try_add() at 
/tmp/qemu-test/src/qom/object.c:1181:
attempt to add duplicate property 'serial-id' to object (type 'container')
ERROR test-char - too few tests run (expected 38, got 9)
make: *** [check-unit] Error 1
make: *** Waiting for unfinished jobs
  TESTcheck-qtest-x86_64: tests/qtest/hd-geo-test
qemu-system-aarch64: -accel kvm: invalid accelerator kvm
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=d30e4f11da184f32a6a18e98d408d1d3', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-27geyh53/src/docker-src.2020-08-15-14.38.06.8943:/var/tmp/qemu:z,ro',
 'qemu/centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=d30e4f11da184f32a6a18e98d408d1d3
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-27geyh53/src'
make: *** [docker-run-test-quick@centos7] Error 2

real12m9.637s
user0m9.264s


The full log is available at
http://patchew.org/logs/1597458180-16945-1-git-send-email-zhengch...@huawei.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v2 00/10] *** A Method for evaluating dirty page rate ***

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1597458180-16945-1-git-send-email-zhengch...@huawei.com/



Hi,

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

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  qapi/qapi-commands-trace.o
  CC  qapi/qapi-commands-ui.o
/tmp/qemu-test/src/migration/dirtyrate.c: In function 'get_ramblock_vfn_hash':
/tmp/qemu-test/src/migration/dirtyrate.c:148:33: error: passing argument 5 of 
'qcrypto_hash_bytesv' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
  148 | md, &qcrypto_hash_len, NULL) < 0) {
  | ^
  | |
---
   72 | size_t *resultlen,
  | ^
cc1: all warnings being treated as errors
make: *** [/tmp/qemu-test/src/rules.mak:69: migration/dirtyrate.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 709, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=8329e3f2f3674af4b07ce49b1f62baa7', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-5wne06va/src/docker-src.2020-08-15-14.33.44.2906:/var/tmp/qemu:z,ro',
 'qemu/fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=8329e3f2f3674af4b07ce49b1f62baa7
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-5wne06va/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real2m56.036s
user0m9.525s


The full log is available at
http://patchew.org/logs/1597458180-16945-1-git-send-email-zhengch...@huawei.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v2 00/10] *** A Method for evaluating dirty page rate ***

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1597458180-16945-1-git-send-email-zhengch...@huawei.com/



Hi,

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

Type: series
Message-id: 1597458180-16945-1-git-send-email-zhengch...@huawei.com
Subject: [PATCH v2 00/10] *** A Method for evaluating dirty page rate ***

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
9895a95 migration/dirtyrate: Implement 
qmp_cal_dirty_rate()/qmp_get_dirty_rate() function
b1e62b0 migration/dirtyrate: Implement calculate_dirtyrate() function
422368f migration/dirtyrate: Implement get_sample_page_period() and 
block_sample_page_period()
b83696a migration/dirtyrate: skip sampling ramblock with size below 
MIN_RAMBLOCK_SIZE
1e807c0 migration/dirtyrate: Compare page hash results for recorded sampled page
383d30a migration/dirtyrate: Record hash results for each sampled page
95a361f migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h
07d224f migration/dirtyrate: Add dirtyrate statistics series functions
dfd9476 migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info
1b3ba07 migration/dirtyrate: Add get_dirtyrate_thread() function

=== OUTPUT BEGIN ===
1/10 Checking commit 1b3ba075587a (migration/dirtyrate: Add 
get_dirtyrate_thread() function)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#26: 
new file mode 100644

total: 0 errors, 1 warnings, 115 lines checked

Patch 1/10 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/10 Checking commit dfd947626dc5 (migration/dirtyrate: Add RamlockDirtyInfo to 
store sampled page info)
3/10 Checking commit 07d224f2772b (migration/dirtyrate: Add dirtyrate 
statistics series functions)
4/10 Checking commit 95a361f00817 (migration/dirtyrate: move 
RAMBLOCK_FOREACH_MIGRATABLE into ram.h)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#62: FILE: migration/ram.h:42:
+#define RAMBLOCK_FOREACH_NOT_IGNORED(block)\
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (ramblock_is_ignored(block)) {} else

ERROR: trailing statements should be on next line
#64: FILE: migration/ram.h:44:
+if (ramblock_is_ignored(block)) {} else

ERROR: Macros with multiple statements should be enclosed in a do - while loop
#66: FILE: migration/ram.h:46:
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (!qemu_ram_is_migratable(block)) {} else

ERROR: trailing statements should be on next line
#68: FILE: migration/ram.h:48:
+if (!qemu_ram_is_migratable(block)) {} else

ERROR: braces {} are necessary for all arms of this statement
#68: FILE: migration/ram.h:48:
+if (!qemu_ram_is_migratable(block)) {} else
[...]
+if (!qemu_ram_is_migratable(block)) {} else
[...]

total: 5 errors, 0 warnings, 45 lines checked

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

5/10 Checking commit 383d30ad41de (migration/dirtyrate: Record hash results for 
each sampled page)
WARNING: line over 80 characters
#33: FILE: migration/dirtyrate.c:79:
+static int get_ramblock_vfn_hash(struct RamblockDirtyInfo *info, unsigned long 
vfn,

ERROR: "foo* bar" should be "foo *bar"
#59: FILE: migration/dirtyrate.c:105:
+GRand* rand = g_rand_new();

ERROR: line over 90 characters
#69: FILE: migration/dirtyrate.c:115:
+info->hash_result = g_try_malloc0_n(sample_pages_count, sizeof(uint8_t) * 
qcrypto_hash_len);

WARNING: line over 80 characters
#75: FILE: migration/dirtyrate.c:121:
+info->sample_page_vfn = g_try_malloc0_n(sample_pages_count, 
sizeof(unsigned long));

WARNING: line over 80 characters
#84: FILE: migration/dirtyrate.c:130:
+info->sample_page_vfn[i] = g_rand_int_range(rand, 0, 
info->ramblock_pages - 1);

WARNING: line over 80 characters
#97: FILE: migration/dirtyrate.c:143:
+static void get_ramblock_dirty_info(RAMBlock *block, struct RamblockDirtyInfo 
*info,

ERROR: line over 90 characters
#103: FILE: migration/dirtyrate.c:149:
+info->sample_pages_count = (qemu_ram_get_used_length(block) * 
sample_pages_per_gigabytes) >> 30;

ERROR: braces {} are necessary for all arms of this statement
#126: FILE: migration/dirtyrate.c:172:
+if (!block_dinfo)
[...]

ERROR: line over 90 characters
#137: FILE: migration/dirtyrate.c:183:
+ struct RamblockDirtyInfo **block_dinfo, 
int *block_index)

ERROR: braces {} are necessary for all arms of this statement
#

Re: [RFC 5/9] target/arm: introduce CPU feature dependency mechanism

2020-08-15 Thread Peng Liang
On 8/13/2020 8:48 PM, Andrew Jones wrote:
> On Thu, Aug 13, 2020 at 06:26:53PM +0800, Peng Liang wrote:
>> Some CPU features are dependent on other CPU features.  For example,
>> ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same
>> value, which means FP and ADVSIMD are dependent on each other, FPHP and
>> ADVSIMDHP are dependent on each other.
>>
>> This commit introduces a mechanism for CPU feature dependency in
>> AArch64.  We build a directed graph from the CPU feature dependency
>> relationship, each edge from->to means the `to` CPU feature is dependent
>> on the `from` CPU feature.  And we will automatically enable/disable CPU
>> feature according to the directed graph.
>>
>> For example, a, b, and c CPU features are in relationship a->b->c, which
>> means c is dependent on b and b is dependent on a.  If c is enabled by
>> user, then a and b is enabled automatically.  And if a is disabled by
>> user, then b and c is disabled automatically.
> 
> And what if a is mutually exclusive with b? I.e. a and b can both be
> disabled, but only a or b may be enabled.
> 
> Thanks,
> drew
> 
> .
> 

Currently, a and b will be both enabled or disabled.  For example, a and b are
in relationship a->b, which means b is dependent on a.  If -cpu host,a=off,b=on,
then both a and b are enabled.  If -cpu host,b=on,a=off, then both a and b are
disabled.  Maybe we should report an error to user in this scenario?

Thanks,
Peng



Re: [RFC 2/9] target/arm: parse cpu feature related options

2020-08-15 Thread Peng Liang
On 8/13/2020 8:21 PM, Andrew Jones wrote:
> On Thu, Aug 13, 2020 at 06:26:50PM +0800, Peng Liang wrote:
>> The implementation of CPUClass::parse_features only supports CPU
>> features in "feature=value" format.  However, libvirt maybe send us a
>> CPU feature string in "+feature/-feature" format. 
> 
> Why would libvirt do that? If we have a boolean feature, then I'd think
> libvirt should be capable of sending feature=on/off just as easily as a
> +/-feature. Indeed libvirt seems to do the right thing with all the
> CPU features we already have: pmu, sve*, ...
> 
> Thanks,
> drew
> 
> .
> 

Libvirt before d47db7b16dd5422c7e487c8c8ee5b181a2f9cd66 ("qemu: command:
Support new cpu feature argument syntax") will send +/-feature.  Does QEMU
need to support it?  If not, I'll remote it.

Thanks,
Peng



Re: [RFC 7/9] target/arm: Add CPU features to query-cpu-model-expansion

2020-08-15 Thread Peng Liang
On 8/13/2020 8:56 PM, Andrew Jones wrote:
> On Thu, Aug 13, 2020 at 06:26:55PM +0800, Peng Liang wrote:
>> Add CPU features to the result of query-cpu-model-expansion so that
>> other applications (such as libvirt) can know the supported CPU
>> features.
>>
>> Signed-off-by: zhanghailiang 
>> Signed-off-by: Peng Liang 
>> ---
>>  target/arm/cpu.c | 41 +
>>  target/arm/cpu.h |  2 ++
>>  target/arm/monitor.c |  2 ++
>>  3 files changed, 45 insertions(+)
>>
>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>> index 3fc54cb3a4..0f620e8afe 100644
>> --- a/target/arm/cpu.c
>> +++ b/target/arm/cpu.c
>> @@ -25,6 +25,8 @@
>>  #include "qemu/module.h"
>>  #include "qapi/error.h"
>>  #include "qapi/visitor.h"
>> +#include "qapi/qmp/qdict.h"
>> +#include "qom/qom-qobject.h"
>>  #include "cpu.h"
>>  #include "internals.h"
>>  #include "exec/exec-all.h"
>> @@ -1515,6 +1517,45 @@ static const CPUFeatureDep feature_dependencies[] = {
>>  },
>>  };
>>  
>> +static char *strtolower(char *src)
>> +{
>> +char *start = src;
>> +
>> +for (; *src; ++src) {
>> +*src = tolower(*src);
>> +}
>> +
>> +return start;
>> +}
> 
> Shouldn't need this. The CPU property names should already be lowercase.
> 

For convenience, we use the field part defined in FIELD macro as the name of
a CPU feature.  So, the names of CPU features are upper...

>> +
>> +void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features)
>> +{
>> +Object *obj = OBJECT(cpu);
>> +const char *name;
>> +ObjectProperty *prop;
>> +bool is_32bit = !arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
>> +int i;
>> +
>> +for (i = 0; i < ARRAY_SIZE(cpu_features); ++i) {
>> +if (is_32bit != cpu_features[i].is_32bit) {
>> +continue;
>> +}
>> +
>> +name = cpu_features[i].name;
>> +prop = object_property_find(obj, name, NULL);
>> +if (prop) {
>> +QObject *value;
>> +g_autofree char *tmp;
>> +
>> +assert(prop->get);
>> +value = object_property_get_qobject(obj, name, &error_abort);
>> +tmp = strtolower(g_strdup(name));
>> +
>> +qdict_put_obj(features, tmp, value);
>> +}
>> +}
>> +}
>> +
>>  static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
>>   void *opaque, Error **errp)
>>  {
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index 5d8074d03b..da68b7f8f4 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -3933,4 +3933,6 @@ static inline bool isar_feature_any_tts2uxn(const 
>> ARMISARegisters *id)
>>  #define cpu_isar_feature(name, cpu) \
>>  ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
>>  
>> +void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features);
>> +
>>  #endif
>> diff --git a/target/arm/monitor.c b/target/arm/monitor.c
>> index ba6e01abd0..f8eb29efec 100644
>> --- a/target/arm/monitor.c
>> +++ b/target/arm/monitor.c
>> @@ -225,6 +225,8 @@ CpuModelExpansionInfo 
>> *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>>  }
>>  }
>>  
>> +arm_cpu_features_to_dict(ARM_CPU(obj), qdict_out);
> 
> Since nobody is looking for these features in qdict_in, then none
> of these features can be changed by QMP user. How does the QMP
> user probe whether or not the feature will work when enabled?
> 
> Thanks,
> drew
> 

My fault, I'll correct it.

Thanks,
Peng

>> +
>>  if (!qdict_size(qdict_out)) {
>>  qobject_unref(qdict_out);
>>  } else {
>> -- 
>> 2.18.4
>>
> 
> .
> 




Re: [RFC 6/9] target/arm: introduce KVM_CAP_ARM_CPU_FEATURE

2020-08-15 Thread Peng Liang
On 8/13/2020 7:00 PM, Cornelia Huck wrote:
> On Thu, 13 Aug 2020 18:26:54 +0800
> Peng Liang  wrote:
> 
>> Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set
>> CPU features in ARM.
>>
>> Signed-off-by: zhanghailiang 
>> Signed-off-by: Peng Liang 
>> ---
>>  linux-headers/linux/kvm.h |  1 +
>>  target/arm/cpu.c  |  5 +
>>  target/arm/kvm64.c| 14 ++
>>  target/arm/kvm_arm.h  |  7 +++
>>  4 files changed, 27 insertions(+)
>>
>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
>> index a28c366737..0b83d2b4bb 100644
>> --- a/linux-headers/linux/kvm.h
>> +++ b/linux-headers/linux/kvm.h
>> @@ -1031,6 +1031,7 @@ struct kvm_ppc_resize_hpt {
>>  #define KVM_CAP_PPC_SECURE_GUEST 181
>>  #define KVM_CAP_HALT_POLL 182
>>  #define KVM_CAP_ASYNC_PF_INT 183
>> +#define KVM_CAP_ARM_CPU_FEATURE 187
>>  
>>  #ifdef KVM_CAP_IRQ_ROUTING
> 
> Please split out this header update into a separate patch so that it
> can be replaced by a proper headers update once the kernel code has been
> included.
> 
> .
> 
Sorry, I'll split out it.



[PATCH v2 00/10] *** A Method for evaluating dirty page rate ***

2020-08-15 Thread Chuan Zheng
v1 -> v2:
use g_rand_new() to generate rand_buf
move RAMBLOCK_FOREACH_MIGRATABLE into migration/ram.h
add skip_sample_ramblock to filter sampled ramblock
fix multi-numa vm coredump when query dirtyrate
rename qapi interface and rename some structures and functions
succeed to compile by appling each patch
add test for migrating vm

Sometimes it is neccessary to evaluate dirty page rate before migration.
Users could decide whether to proceed migration based on the evaluation
in case of vm performance loss due to heavy workload.
Unlikey simulating dirtylog sync which could do harm on runnning vm,
we provide a sample-hash method to compare hash results for samping page.
In this way, it would have hardly no impact on vm performance.

Evaluate the dirtypage rate both on running and migration vm.
The VM specifications for migration are as follows:
- VM use 4-K page;
- the number of VCPU is 32;
- the total memory is 32Gigabit;
- use 'mempress' tool to pressurize VM(mempress 4096 1024);
- migration bandwidth is 1GB/s


|  |  running  |  migrating 
   |

| no mempress  |   4MB/s   |  8MB/s  (migrated success) 
   |

| mempress 4096 1024   |  1188MB/s |   536MB/s ~ 1044MB/s (cpu throttle 
triggered) |

| mempress 4096 4096   |  4152MB/s | 608MB/s ~ 4125MB/s (migation failed)   
   |


Test dirtyrate by qmp command like this:
1.  virsh qemu-monitor-command [vmname] '{"execute":"calc-dirty-rate", 
"arguments": {"calc-time": [sleep-time]}}'; 
2.  sleep specific time which is a bit larger than sleep-time
3.  virsh qemu-monitor-command [vmname] '{"execute":"query-dirty-rate"}'

Further test dirtyrate by libvirt api like this:
virsh getdirtyrate [vmname] [sleep-time]

Zheng Chuan (10):
  migration/dirtyrate: Add get_dirtyrate_thread() function
  migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info
  migration/dirtyrate: Add dirtyrate statistics series functions
  migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h
  migration/dirtyrate: Record hash results for each sampled page
  migration/dirtyrate: Compare page hash results for recorded sampled
page
  migration/dirtyrate: skip sampling ramblock with size below
MIN_RAMBLOCK_SIZE
  migration/dirtyrate: Implement get_sample_page_period() and
block_sample_page_period()
  migration/dirtyrate: Implement calculate_dirtyrate() function
  migration/dirtyrate: Implement
qmp_cal_dirty_rate()/qmp_get_dirty_rate() function

 migration/Makefile.objs |   1 +
 migration/dirtyrate.c   | 448 
 migration/dirtyrate.h   |  86 ++
 migration/ram.c |  11 +-
 migration/ram.h |  10 ++
 qapi/migration.json |  42 +
 6 files changed, 588 insertions(+), 10 deletions(-)
 create mode 100644 migration/dirtyrate.c
 create mode 100644 migration/dirtyrate.h

-- 
1.8.3.1




[PATCH v2 04/10] migration/dirtyrate: move RAMBLOCK_FOREACH_MIGRATABLE into ram.h

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

RAMBLOCK_FOREACH_MIGRATABLE is need in dirtyrate measure,
move the existing definition up into migration/ram.h

Signed-off-by: Zheng Chuan 
---
 migration/dirtyrate.c |  1 +
 migration/ram.c   | 11 +--
 migration/ram.h   | 10 ++
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 8708090..c4304ef 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -21,6 +21,7 @@
 #include "qemu/rcu_queue.h"
 #include "qapi/qapi-commands-migration.h"
 #include "migration.h"
+#include "ram.h"
 #include "dirtyrate.h"
 
 CalculatingDirtyRateState CalculatingState = CAL_DIRTY_RATE_INIT;
diff --git a/migration/ram.c b/migration/ram.c
index 76d4fee..37ef0da 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -158,21 +158,12 @@ out:
 return ret;
 }
 
-static bool ramblock_is_ignored(RAMBlock *block)
+bool ramblock_is_ignored(RAMBlock *block)
 {
 return !qemu_ram_is_migratable(block) ||
(migrate_ignore_shared() && qemu_ram_is_shared(block));
 }
 
-/* Should be holding either ram_list.mutex, or the RCU lock. */
-#define RAMBLOCK_FOREACH_NOT_IGNORED(block)\
-INTERNAL_RAMBLOCK_FOREACH(block)   \
-if (ramblock_is_ignored(block)) {} else
-
-#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
-INTERNAL_RAMBLOCK_FOREACH(block)   \
-if (!qemu_ram_is_migratable(block)) {} else
-
 #undef RAMBLOCK_FOREACH
 
 int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque)
diff --git a/migration/ram.h b/migration/ram.h
index 2eeaacf..011e854 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -37,6 +37,16 @@ extern MigrationStats ram_counters;
 extern XBZRLECacheStats xbzrle_counters;
 extern CompressionStats compression_counters;
 
+bool ramblock_is_ignored(RAMBlock *block);
+/* Should be holding either ram_list.mutex, or the RCU lock. */
+#define RAMBLOCK_FOREACH_NOT_IGNORED(block)\
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (ramblock_is_ignored(block)) {} else
+
+#define RAMBLOCK_FOREACH_MIGRATABLE(block) \
+INTERNAL_RAMBLOCK_FOREACH(block)   \
+if (!qemu_ram_is_migratable(block)) {} else
+
 int xbzrle_cache_resize(int64_t new_size, Error **errp);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);
-- 
1.8.3.1




[PATCH v2 08/10] migration/dirtyrate: Implement get_sample_page_period() and block_sample_page_period()

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Implement get_sample_page_period() and set_sample_page_period() to
sleep specific time between sample actions.

Signed-off-by: Zheng Chuan 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 23 +++
 migration/dirtyrate.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 3dc9feb..54b832a 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -28,6 +28,29 @@ CalculatingDirtyRateState CalculatingState = 
CAL_DIRTY_RATE_INIT;
 static unsigned long int qcrypto_hash_len = QCRYPTO_HASH_LEN;
 static struct DirtyRateStat dirty_stat;
 
+static int64_t set_sample_page_period(int64_t msec, int64_t initial_time)
+{
+int64_t current_time;
+
+current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+if ((current_time - initial_time) >= msec) {
+msec = current_time - initial_time;
+} else {
+g_usleep((msec + initial_time - current_time) * 1000);
+}
+
+return msec;
+}
+
+static int64_t get_sample_page_period(int64_t sec)
+{
+if (sec <= MIN_FETCH_DIRTYRATE_TIME_SEC || sec > 
MAX_FETCH_DIRTYRATE_TIME_SEC) {
+sec = DEFAULT_FETCH_DIRTYRATE_TIME_SEC;
+}
+
+return sec;
+}
+
 static int dirty_rate_set_state(int new_state)
 {
 int old_state = CalculatingState;
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index fce2e3b..86d8fa0 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -38,6 +38,8 @@
 
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
+#define MIN_FETCH_DIRTYRATE_TIME_SEC  0
+#define MAX_FETCH_DIRTYRATE_TIME_SEC  60
 
 struct DirtyRateConfig {
 uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
-- 
1.8.3.1




[PATCH v2 01/10] migration/dirtyrate: Add get_dirtyrate_thread() function

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Add get_dirtyrate_thread() functions

Signed-off-by: Zheng Chuan 
Signed-off-by: YanYing Zhuang 
---
 migration/Makefile.objs |  1 +
 migration/dirtyrate.c   | 64 +
 migration/dirtyrate.h   | 44 ++
 3 files changed, 109 insertions(+)
 create mode 100644 migration/dirtyrate.c
 create mode 100644 migration/dirtyrate.h

diff --git a/migration/Makefile.objs b/migration/Makefile.objs
index 0fc619e..12ae98c 100644
--- a/migration/Makefile.objs
+++ b/migration/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-y += qemu-file.o global_state.o
 common-obj-y += qemu-file-channel.o
 common-obj-y += xbzrle.o postcopy-ram.o
 common-obj-y += qjson.o
+common-obj-y += dirtyrate.o
 common-obj-y += block-dirty-bitmap.o
 common-obj-y += multifd.o
 common-obj-y += multifd-zlib.o
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
new file mode 100644
index 000..bb0ebe9
--- /dev/null
+++ b/migration/dirtyrate.c
@@ -0,0 +1,64 @@
+/*
+ * Dirtyrate implement code
+ *
+ * Copyright (c) 2017-2020 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Authors:
+ *  Chuan Zheng 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hash.h"
+#include "crypto/random.h"
+#include "qemu/config-file.h"
+#include "exec/memory.h"
+#include "exec/ramblock.h"
+#include "exec/target_page.h"
+#include "qemu/rcu_queue.h"
+#include "qapi/qapi-commands-migration.h"
+#include "migration.h"
+#include "dirtyrate.h"
+
+CalculatingDirtyRateState CalculatingState = CAL_DIRTY_RATE_INIT;
+
+static int dirty_rate_set_state(int new_state)
+{
+int old_state = CalculatingState;
+
+if (new_state == old_state) {
+return -1;
+}
+
+if (atomic_cmpxchg(&CalculatingState, old_state, new_state) != old_state) {
+return -1;
+}
+
+return 0;
+}
+
+static void calculate_dirtyrate(struct DirtyRateConfig config)
+{
+/* todo */
+return;
+}
+
+void *get_dirtyrate_thread(void *arg)
+{
+struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
+int ret;
+
+ret = dirty_rate_set_state(CAL_DIRTY_RATE_ACTIVE);
+if (ret == -1) {
+return NULL;
+}
+
+calculate_dirtyrate(config);
+
+ret = dirty_rate_set_state(CAL_DIRTY_RATE_END);
+
+return NULL;
+}
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
new file mode 100644
index 000..914c363
--- /dev/null
+++ b/migration/dirtyrate.h
@@ -0,0 +1,44 @@
+/*
+ *  Dirtyrate common functions
+ *
+ *  Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ *  Authors:
+ *  Chuan Zheng 
+ *
+ *  This work is licensed under the terms of the GNU GPL, version 2 or later.
+ *  See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_MIGRATION_DIRTYRATE_H
+#define QEMU_MIGRATION_DIRTYRATE_H
+
+/*
+ * Sample 256 pages per GB as default.
+ * TODO: Make it configurable.
+ */
+#define DIRTYRATE_DEFAULT_SAMPLE_PAGES256
+
+/* Take 1s as default for calculation duration */
+#define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
+
+struct DirtyRateConfig {
+uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
+int64_t sample_period_seconds; /* time duration between two sampling */
+};
+
+/*
+ *  To record calculate dirty_rate status:
+ *  0: initial status, calculating thread is not be created here.
+ *  1: calculating thread is created.
+ *  2: calculating thread is end, we can get result.
+ */
+typedef enum {
+CAL_DIRTY_RATE_INIT = 0,
+CAL_DIRTY_RATE_ACTIVE,
+CAL_DIRTY_RATE_END,
+} CalculatingDirtyRateState;
+
+void *get_dirtyrate_thread(void *arg);
+#endif
+
-- 
1.8.3.1




[PATCH v2 07/10] migration/dirtyrate: skip sampling ramblock with size below MIN_RAMBLOCK_SIZE

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

In order to sample real RAM, skip ramblock with size below
MIN_RAMBLOCK_SIZE which is 128M as default.

Signed-off-by: Zheng Chuan 
---
 migration/dirtyrate.c | 24 
 migration/dirtyrate.h |  5 +
 2 files changed, 29 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index f136067..3dc9feb 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -179,6 +179,24 @@ alloc_ramblock_dirty_info(int *block_index,
 return block_dinfo;
 }
 
+static int skip_sample_ramblock(RAMBlock *block)
+{
+int64_t ramblock_size;
+
+/* ramblock size in MB */
+ramblock_size = qemu_ram_get_used_length(block) >> 20;
+
+/*
+ * Consider ramblock with size larger than 128M is what we
+ * want to sample.
+ */
+if (ramblock_size < MIN_RAMBLOCK_SIZE) {
+return -1;
+}
+
+return 0;
+}
+
 static int record_ramblock_hash_info(struct DirtyRateConfig config,
  struct RamblockDirtyInfo **block_dinfo, 
int *block_index)
 {
@@ -188,6 +206,9 @@ static int record_ramblock_hash_info(struct DirtyRateConfig 
config,
 int index = 0;
 
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
+if (skip_sample_ramblock(block) < 0) {
+continue;
+}
 dinfo = alloc_ramblock_dirty_info(&index, dinfo);
 if (dinfo == NULL)
 return -1;
@@ -263,6 +284,9 @@ static int compare_page_hash_info(struct RamblockDirtyInfo 
*info, int block_inde
 RAMBlock *block = NULL;
 
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
+if (skip_sample_ramblock(block) < 0) {
+continue;
+}
 block_dinfo = NULL;
 if (!find_page_matched(block, info, block_index + 1, &block_dinfo)) {
 continue;
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 0812b16..fce2e3b 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -31,6 +31,11 @@
 
 #define QCRYPTO_HASH_LEN  16
 
+/*
+ * minimum ramblock size to sampled
+ */
+#define MIN_RAMBLOCK_SIZE128
+
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
 
-- 
1.8.3.1




[PATCH v2 06/10] migration/dirtyrate: Compare page hash results for recorded sampled page

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Compare page hash results for recorded sampled page.

Signed-off-by: Zheng Chuan 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 73 +++
 1 file changed, 73 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 11c0051..f136067 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -206,6 +206,79 @@ static int record_ramblock_hash_info(struct 
DirtyRateConfig config,
 return 0;
 }
 
+static int calc_page_dirty_rate(struct RamblockDirtyInfo *info)
+{
+uint8_t *md = NULL;
+int i;
+int ret = 0;
+
+md = g_try_new0(uint8_t, qcrypto_hash_len);
+if (!md)
+return -1;
+
+for (i = 0; i < info->sample_pages_count; i++) {
+ret = get_ramblock_vfn_hash(info, info->sample_page_vfn[i], &md);
+if (ret < 0) {
+goto out;
+}
+
+if (memcmp(md, info->hash_result + i * qcrypto_hash_len, 
qcrypto_hash_len) != 0) {
+info->sample_dirty_count++;
+}
+}
+
+out:
+g_free(md);
+return ret;
+}
+
+static bool find_page_matched(RAMBlock *block, struct RamblockDirtyInfo *infos,
+   int count, struct RamblockDirtyInfo **matched)
+{
+int i;
+
+for (i = 0; i < count; i++) {
+if (!strcmp(infos[i].idstr, qemu_ram_get_idstr(block))) {
+break;
+}
+}
+
+if (i == count) {
+return false;
+}
+
+if (infos[i].ramblock_addr != qemu_ram_get_host_addr(block) ||
+infos[i].ramblock_pages !=
+(qemu_ram_get_used_length(block) >> 12)) {
+return false;
+}
+
+*matched = &infos[i];
+return true;
+}
+
+static int compare_page_hash_info(struct RamblockDirtyInfo *info, int 
block_index)
+{
+struct RamblockDirtyInfo *block_dinfo = NULL;
+RAMBlock *block = NULL;
+
+RAMBLOCK_FOREACH_MIGRATABLE(block) {
+block_dinfo = NULL;
+if (!find_page_matched(block, info, block_index + 1, &block_dinfo)) {
+continue;
+}
+if (calc_page_dirty_rate(block_dinfo) < 0) {
+return -1;
+}
+update_dirtyrate_stat(block_dinfo);
+}
+if (!dirty_stat.total_sample_count) {
+return -1;
+}
+
+return 0;
+}
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */
-- 
1.8.3.1




[PATCH v2 10/10] migration/dirtyrate: Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function which could be 
called

Signed-off-by: Zheng Chuan 
---
 migration/dirtyrate.c | 56 +++
 qapi/migration.json   | 42 ++
 2 files changed, 98 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index d487030..bf8fe9e 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -66,6 +66,39 @@ static int dirty_rate_set_state(int new_state)
 return 0;
 }
 
+static struct DirtyRateInfo *query_dirty_rate_info(void)
+{
+int64_t dirty_rate = dirty_stat.dirty_rate;
+struct DirtyRateInfo *info = g_malloc0(sizeof(DirtyRateInfo));
+
+switch(CalculatingState) {
+case CAL_DIRTY_RATE_INIT:
+info->dirty_rate = -1;
+info->status = g_strdup("Not start measuring");
+break;
+case CAL_DIRTY_RATE_ACTIVE:
+info->dirty_rate = -1;
+info->status = g_strdup("Still measuring");
+break;
+case CAL_DIRTY_RATE_END:
+info->dirty_rate = dirty_rate;
+info->status = g_strdup("Measured");
+break;
+default:
+info->dirty_rate = -1;
+info->status = g_strdup("Unknown status");
+break;
+}
+
+/*
+ * Only support query once for each calculation,
+ * reset as CAL_DIRTY_RATE_INIT after query
+ */
+(void)dirty_rate_set_state(CAL_DIRTY_RATE_INIT);
+
+return info;
+}
+
 static void reset_dirtyrate_stat(void)
 {
 dirty_stat.total_dirty_samples = 0;
@@ -390,3 +423,26 @@ void *get_dirtyrate_thread(void *arg)
 
 return NULL;
 }
+
+void qmp_calc_dirty_rate(int64_t calc_time, Error **errp)
+{
+static struct DirtyRateConfig config;
+QemuThread thread;
+
+/*
+ * We don't begin calculating thread only when it's in calculating status.
+ */
+if (CalculatingState == CAL_DIRTY_RATE_ACTIVE) {
+return;
+}
+
+config.sample_period_seconds = get_sample_page_period(calc_time);
+config.sample_pages_per_gigabytes = DIRTYRATE_DEFAULT_SAMPLE_PAGES;
+qemu_thread_create(&thread, "get_dirtyrate", get_dirtyrate_thread,
+   (void *)&config, QEMU_THREAD_DETACHED);
+}
+
+struct DirtyRateInfo *qmp_query_dirty_rate(Error **errp)
+{
+return query_dirty_rate_info();
+}
diff --git a/qapi/migration.json b/qapi/migration.json
index d500055..ccc7a4e 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1621,3 +1621,45 @@
 ##
 { 'event': 'UNPLUG_PRIMARY',
   'data': { 'device-id': 'str' } }
+
+##
+# @DirtyRateInfo:
+#
+# Information about current dirty page rate of vm.
+#
+# @dirty-rate: @dirtyrate describing the dirty page rate of vm
+#  in units of MB/s.
+#  If this field return '-1', it means querying is not
+#  start or not complete.
+#
+# @status: @status containing dirtyrate query status includes
+#   status with 'not start measuring' or
+#   'Still measuring' or 'measured'(since 5.2)
+##
+{ 'struct': 'DirtyRateInfo',
+  'data': {'dirty-rate': 'int64',
+   'status': 'str'} }
+
+##
+# @calc-dirty-rate:
+#
+# start calculating dirty page rate for vm
+#
+# @calc-time: time in units of second for sample dirty pages
+#
+# Since: 5.2
+#
+# Example:
+#   {"command": "cal-dirty-rate", "data": {"calc-time": 1} }
+#
+##
+{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64'} }
+
+##
+# @query-dirty-rate:
+#
+# query dirty page rate in units of MB/s for vm
+#
+# Since: 5.2
+##
+{ 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' }
-- 
1.8.3.1




[PATCH v2 03/10] migration/dirtyrate: Add dirtyrate statistics series functions

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Add dirtyrate statistics to record/update dirtyrate info.

Signed-off-by: Zheng Chuan 
---
 migration/dirtyrate.c | 30 ++
 migration/dirtyrate.h | 10 ++
 2 files changed, 40 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index bb0ebe9..8708090 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -24,6 +24,7 @@
 #include "dirtyrate.h"
 
 CalculatingDirtyRateState CalculatingState = CAL_DIRTY_RATE_INIT;
+static struct DirtyRateStat dirty_stat;
 
 static int dirty_rate_set_state(int new_state)
 {
@@ -40,6 +41,35 @@ static int dirty_rate_set_state(int new_state)
 return 0;
 }
 
+static void reset_dirtyrate_stat(void)
+{
+dirty_stat.total_dirty_samples = 0;
+dirty_stat.total_sample_count = 0;
+dirty_stat.total_block_mem_MB = 0;
+dirty_stat.dirty_rate = 0;
+}
+
+static void update_dirtyrate_stat(struct RamblockDirtyInfo *info)
+{
+dirty_stat.total_dirty_samples += info->sample_dirty_count;
+dirty_stat.total_sample_count += info->sample_pages_count;
+/* size of 4K pages in MB */
+dirty_stat.total_block_mem_MB += info->ramblock_pages / 256;
+}
+
+static void update_dirtyrate(uint64_t msec)
+{
+uint64_t dirty_rate;
+unsigned int total_dirty_samples = dirty_stat.total_dirty_samples;
+unsigned int total_sample_count = dirty_stat.total_sample_count;
+size_t total_block_mem_MB = dirty_stat.total_block_mem_MB;
+
+dirty_rate = total_dirty_samples * total_block_mem_MB *
+ 1000 / (total_sample_count * msec);
+
+dirty_stat.dirty_rate = dirty_rate;
+}
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */
diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 9650566..af57c80 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -57,6 +57,16 @@ struct RamblockDirtyInfo {
 uint8_t *hash_result; /* array of hash result for sampled pages */
 };
 
+/*
+ * Store calculate statistics for each measure.
+ */
+struct DirtyRateStat {
+unsigned int total_dirty_samples; /* total dirty pages for this measure */
+unsigned int total_sample_count; /* total sampled pages for this measure */
+size_t total_block_mem_MB; /* size of sampled pages in MB */
+int64_t dirty_rate; /* dirty rate for this measure */
+};
+
 void *get_dirtyrate_thread(void *arg);
 #endif
 
-- 
1.8.3.1




[PATCH v2 05/10] migration/dirtyrate: Record hash results for each sampled page

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Record hash results for each sampled page.

Signed-off-by: Zheng Chuan 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 135 ++
 migration/dirtyrate.h |   7 +++
 2 files changed, 142 insertions(+)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index c4304ef..11c0051 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -25,6 +25,7 @@
 #include "dirtyrate.h"
 
 CalculatingDirtyRateState CalculatingState = CAL_DIRTY_RATE_INIT;
+static unsigned long int qcrypto_hash_len = QCRYPTO_HASH_LEN;
 static struct DirtyRateStat dirty_stat;
 
 static int dirty_rate_set_state(int new_state)
@@ -71,6 +72,140 @@ static void update_dirtyrate(uint64_t msec)
 dirty_stat.dirty_rate = dirty_rate;
 }
 
+/*
+ * get hash result for the sampled memory with length of 4K byte in ramblock,
+ * which starts from ramblock base address.
+ */
+static int get_ramblock_vfn_hash(struct RamblockDirtyInfo *info, unsigned long 
vfn,
+ uint8_t **md)
+{
+struct iovec iov_array;
+int ret = 0;
+int nkey = 1;
+
+iov_array.iov_base = info->ramblock_addr +
+ vfn * DIRTYRATE_SAMPLE_PAGE_SIZE;
+iov_array.iov_len = DIRTYRATE_SAMPLE_PAGE_SIZE;
+
+if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_MD5,
+&iov_array, nkey,
+md, &qcrypto_hash_len, NULL) < 0) {
+ret = -1;
+}
+
+return ret;
+}
+
+static int save_ramblock_hash(struct RamblockDirtyInfo *info)
+{
+unsigned int sample_pages_count;
+uint8_t *md = NULL;
+int i;
+int ret = -1;
+GRand* rand = g_rand_new();
+
+sample_pages_count = info->sample_pages_count;
+
+/* ramblock size less than one page, return success to skip this ramblock 
*/
+if (unlikely(info->ramblock_pages == 0 || sample_pages_count == 0)) {
+ret = 0;
+goto out;
+}
+
+info->hash_result = g_try_malloc0_n(sample_pages_count, sizeof(uint8_t) * 
qcrypto_hash_len);
+if (!info->hash_result) {
+ret = -1;
+goto out;
+}
+
+info->sample_page_vfn = g_try_malloc0_n(sample_pages_count, 
sizeof(unsigned long));
+if (!info->sample_page_vfn) {
+g_free(info->hash_result);
+ret = -1;
+goto out;
+}
+
+for (i = 0; i < sample_pages_count; i++) {
+md = info->hash_result + i * qcrypto_hash_len;
+info->sample_page_vfn[i] = g_rand_int_range(rand, 0, 
info->ramblock_pages - 1);
+ret = get_ramblock_vfn_hash(info, info->sample_page_vfn[i], &md);
+if (ret < 0) {
+goto out;
+}
+}
+ret = 0;
+
+out:
+g_rand_free(rand);
+return ret;
+}
+
+static void get_ramblock_dirty_info(RAMBlock *block, struct RamblockDirtyInfo 
*info,
+struct DirtyRateConfig *config)
+{
+uint64_t sample_pages_per_gigabytes = config->sample_pages_per_gigabytes;
+
+/* Right shift 30 bits to calc block size in GB */
+info->sample_pages_count = (qemu_ram_get_used_length(block) * 
sample_pages_per_gigabytes) >> 30;
+
+/* Right shift 12 bits to calc page count in 4KB */
+info->ramblock_pages = qemu_ram_get_used_length(block) >> 12;
+info->ramblock_addr = qemu_ram_get_host_addr(block);
+strcpy(info->idstr, qemu_ram_get_idstr(block));
+}
+
+static struct RamblockDirtyInfo *
+alloc_ramblock_dirty_info(int *block_index,
+  struct RamblockDirtyInfo *block_dinfo)
+{
+struct RamblockDirtyInfo *info = NULL;
+int index = *block_index;
+
+if (!block_dinfo) {
+block_dinfo = g_try_new(struct RamblockDirtyInfo, 1);
+index = 0;
+} else {
+index++;
+block_dinfo = g_try_realloc(block_dinfo, (index + 1) *
+sizeof(struct RamblockDirtyInfo));
+}
+if (!block_dinfo)
+return NULL;
+
+info = &block_dinfo[index];
+memset(info, 0, sizeof(struct RamblockDirtyInfo));
+
+*block_index = index;
+return block_dinfo;
+}
+
+static int record_ramblock_hash_info(struct DirtyRateConfig config,
+ struct RamblockDirtyInfo **block_dinfo, 
int *block_index)
+{
+struct RamblockDirtyInfo *info = NULL;
+struct RamblockDirtyInfo *dinfo = NULL;
+RAMBlock *block = NULL;
+int index = 0;
+
+RAMBLOCK_FOREACH_MIGRATABLE(block) {
+dinfo = alloc_ramblock_dirty_info(&index, dinfo);
+if (dinfo == NULL)
+return -1;
+info = &dinfo[index];
+get_ramblock_dirty_info(block, info, &config);
+if (save_ramblock_hash(info) < 0) {
+*block_dinfo = dinfo;
+*block_index = index;
+return -1;
+}
+}
+
+*block_dinfo = dinfo;
+*block_index = index;
+
+return 0;
+}
+
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
 /* todo */
diff --git a/migration/dirtyrate.h b

[PATCH v2 02/10] migration/dirtyrate: Add RamlockDirtyInfo to store sampled page info

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Add RamlockDirtyInfo to store sampled page info of each ramblock.

Signed-off-by: Zheng Chuan 
---
 migration/dirtyrate.h | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
index 914c363..9650566 100644
--- a/migration/dirtyrate.h
+++ b/migration/dirtyrate.h
@@ -19,6 +19,11 @@
  */
 #define DIRTYRATE_DEFAULT_SAMPLE_PAGES256
 
+/*
+ * Record ramblock idstr
+ */
+#define RAMBLOCK_INFO_MAX_LEN 256
+
 /* Take 1s as default for calculation duration */
 #define DEFAULT_FETCH_DIRTYRATE_TIME_SEC  1
 
@@ -39,6 +44,19 @@ typedef enum {
 CAL_DIRTY_RATE_END,
 } CalculatingDirtyRateState;
 
+/*
+ * Store dirtypage info for each ramblock.
+ */
+struct RamblockDirtyInfo {
+char idstr[RAMBLOCK_INFO_MAX_LEN]; /* idstr for each ramblock */
+uint8_t *ramblock_addr; /* base address of ramblock we measure */
+size_t ramblock_pages; /* sum of dividation by 4K pages for ramblock */
+size_t *sample_page_vfn; /* relative offset address for sampled page */
+unsigned int sample_pages_count; /* sum of sampled pages */
+unsigned int sample_dirty_count; /* sum of dirty pages we measure */
+uint8_t *hash_result; /* array of hash result for sampled pages */
+};
+
 void *get_dirtyrate_thread(void *arg);
 #endif
 
-- 
1.8.3.1




[PATCH v2 09/10] migration/dirtyrate: Implement calculate_dirtyrate() function

2020-08-15 Thread Chuan Zheng
From: Zheng Chuan 

Implement calculate_dirtyrate() function.

Signed-off-by: Zheng Chuan 
Signed-off-by: YanYing Zhuang 
---
 migration/dirtyrate.c | 46 --
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 54b832a..d487030 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -177,6 +177,21 @@ static void get_ramblock_dirty_info(RAMBlock *block, 
struct RamblockDirtyInfo *i
 strcpy(info->idstr, qemu_ram_get_idstr(block));
 }
 
+static void free_ramblock_dirty_info(struct RamblockDirtyInfo *infos, int 
count)
+{
+int i;
+
+if (!infos) {
+return;
+}
+
+for (i = 0; i < count; i++) {
+g_free(infos[i].sample_page_vfn);
+g_free(infos[i].hash_result);
+}
+g_free(infos);
+}
+
 static struct RamblockDirtyInfo *
 alloc_ramblock_dirty_info(int *block_index,
   struct RamblockDirtyInfo *block_dinfo)
@@ -328,8 +343,35 @@ static int compare_page_hash_info(struct RamblockDirtyInfo 
*info, int block_inde
 
 static void calculate_dirtyrate(struct DirtyRateConfig config)
 {
-/* todo */
-return;
+struct RamblockDirtyInfo *block_dinfo = NULL;
+int block_index = 0;
+int64_t msec = 0;
+int64_t initial_time;
+
+rcu_register_thread();
+reset_dirtyrate_stat();
+initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+rcu_read_lock();
+if (record_ramblock_hash_info(config, &block_dinfo, &block_index) < 0) {
+goto out;
+}
+rcu_read_unlock();
+
+msec = config.sample_period_seconds * 1000;
+msec = set_sample_page_period(msec, initial_time);
+
+rcu_read_lock();
+if (compare_page_hash_info(block_dinfo, block_index) < 0) {
+goto out;
+}
+
+update_dirtyrate(msec);
+
+out:
+rcu_read_unlock();
+free_ramblock_dirty_info(block_dinfo, block_index + 1);
+rcu_unregister_thread();
+
 }
 
 void *get_dirtyrate_thread(void *arg)
-- 
1.8.3.1




Re: [PATCH 00/20] target/arm: SVE2 preparatory patches

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200815013145.539409-1-richard.hender...@linaro.org/



Hi,

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

Type: series
Message-id: 20200815013145.539409-1-richard.hender...@linaro.org
Subject: [PATCH 00/20] target/arm: SVE2 preparatory patches

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20200812183250.9221-1-cfont...@suse.de -> 
patchew/20200812183250.9221-1-cfont...@suse.de
 - [tag update]  patchew/20200814082841.27000-1-f4...@amsat.org -> 
patchew/20200814082841.27000-1-f4...@amsat.org
 * [new tag] 
patchew/20200815013145.539409-1-richard.hender...@linaro.org -> 
patchew/20200815013145.539409-1-richard.hender...@linaro.org
Switched to a new branch 'test'
ee9e70c target/arm: Convert sq{, r}dmulh to gvec for aa64 advsimd
68d3120 target/arm: Convert integer multiply-add (indexed) to gvec for aa64 
advsimd
4915d69 target/arm: Convert integer multiply (indexed) to gvec for aa64 advsimd
4ede158 target/arm: Fix sve_punpk_p vs odd vector lengths
94aae8d target/arm: Fix sve_zip_p vs odd vector lengths
dd7dc33 target/arm: Fix sve_uzp_p vs odd vector lengths
b32338b target/arm: Generalize inl_qrdmlah_* helper functions
095ea16 target/arm: Tidy SVE tszimm shift formats
e34d62c target/arm: Split out gen_gvec_ool_zz
c0d82b9 target/arm: Split out gen_gvec_ool_zzz
a99dbac target/arm: Split out gen_gvec_ool_zzp
cfb28d1 target/arm: Merge helper_sve_clr_* and helper_sve_movz_*
0592c7a target/arm: Split out gen_gvec_ool_zzzp
6e5fc25 target/arm: Use tcg_gen_gvec_bitsel for trans_SEL_
05415f2 target/arm: Clean up 4-operand predicate expansion
7adbccc target/arm: Merge do_vector2_p into do_mov_p
c7cd875 target/arm: Rearrange {sve,fp}_check_access assert
a86390b target/arm: Split out gen_gvec_fn_zzz, do_zzz_fn
289f152 target/arm: Split out gen_gvec_fn_zz
4bbc96a qemu/int128: Add int128_lshift

=== OUTPUT BEGIN ===
1/20 Checking commit 4bbc96a0e6a5 (qemu/int128: Add int128_lshift)
2/20 Checking commit 289f152a8194 (target/arm: Split out gen_gvec_fn_zz)
3/20 Checking commit a86390b7a972 (target/arm: Split out gen_gvec_fn_zzz, 
do_zzz_fn)
4/20 Checking commit c7cd87586c88 (target/arm: Rearrange {sve,fp}_check_access 
assert)
5/20 Checking commit 7adbccc844ea (target/arm: Merge do_vector2_p into do_mov_p)
6/20 Checking commit 05415f287adb (target/arm: Clean up 4-operand predicate 
expansion)
7/20 Checking commit 6e5fc25bd7b0 (target/arm: Use tcg_gen_gvec_bitsel for 
trans_SEL_)
8/20 Checking commit 0592c7a7e8a5 (target/arm: Split out gen_gvec_ool_zzzp)
9/20 Checking commit cfb28d174ae5 (target/arm: Merge helper_sve_clr_* and 
helper_sve_movz_*)
10/20 Checking commit a99dbace62f6 (target/arm: Split out gen_gvec_ool_zzp)
11/20 Checking commit c0d82b9048d4 (target/arm: Split out gen_gvec_ool_zzz)
12/20 Checking commit e34d62ca031f (target/arm: Split out gen_gvec_ool_zz)
13/20 Checking commit 095ea164e906 (target/arm: Tidy SVE tszimm shift formats)
14/20 Checking commit b32338b23247 (target/arm: Generalize inl_qrdmlah_* helper 
functions)
15/20 Checking commit dd7dc33f523b (target/arm: Fix sve_uzp_p vs odd vector 
lengths)
16/20 Checking commit 94aae8d657bb (target/arm: Fix sve_zip_p vs odd vector 
lengths)
17/20 Checking commit 4ede158d452e (target/arm: Fix sve_punpk_p vs odd vector 
lengths)
18/20 Checking commit 4915d696b4a9 (target/arm: Convert integer multiply 
(indexed) to gvec for aa64 advsimd)
ERROR: space prohibited before that close parenthesis ')'
#76: FILE: target/arm/vec_helper.c:730:
+DO_MUL_IDX(gvec_mul_idx_d, uint64_t, )

ERROR: space prohibited before that close parenthesis ')'
#93: FILE: target/arm/vec_helper.c:751:
+DO_FMUL_IDX(gvec_fmul_idx_d, float64, )

total: 2 errors, 0 warnings, 74 lines checked

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

19/20 Checking commit 68d3120b2c82 (target/arm: Convert integer multiply-add 
(indexed) to gvec for aa64 advsimd)
ERROR: space prohibited before that close parenthesis ')'
#105: FILE: target/arm/vec_helper.c:751:
+DO_MLA_IDX(gvec_mla_idx_d, uint64_t, +,   )

ERROR: space prohibited before that close parenthesis ')'
#109: FILE: target/arm/vec_helper.c:755:
+DO_MLA_IDX(gvec_mls_idx_d, uint64_t, -,   )

total: 2 errors, 0 warnings, 91 lines checked

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

20/20 Checking commit ee9e70cbd125 (target/arm: Convert sq{, r}dmulh to gvec 
for aa64 advsimd)
=== OUTPUT END ===

Test comma

[PATCH 03/20] target/arm: Split out gen_gvec_fn_zzz, do_zzz_fn

2020-08-15 Thread Richard Henderson
Model gen_gvec_fn_zzz on gen_gvec_fn3 in translate-a64.c, but
indicating which kind of register and in which order.

Model do_zzz_fn on the other do_foo functions that take an
argument set and verify sve enabled.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 43 +-
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 28e27c55b5..b0fa38db1c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -153,16 +153,13 @@ static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn 
*gvec_fn,
 }
 
 /* Invoke a vector expander on three Zregs.  */
-static bool do_vector3_z(DisasContext *s, GVecGen3Fn *gvec_fn,
- int esz, int rd, int rn, int rm)
+static void gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
+int esz, int rd, int rn, int rm)
 {
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-gvec_fn(esz, vec_full_reg_offset(s, rd),
-vec_full_reg_offset(s, rn),
-vec_full_reg_offset(s, rm), vsz, vsz);
-}
-return true;
+unsigned vsz = vec_full_reg_size(s);
+gvec_fn(esz, vec_full_reg_offset(s, rd),
+vec_full_reg_offset(s, rn),
+vec_full_reg_offset(s, rm), vsz, vsz);
 }
 
 /* Invoke a vector move on two Zregs.  */
@@ -274,24 +271,32 @@ const uint64_t pred_esz_masks[4] = {
  *** SVE Logical - Unpredicated Group
  */
 
+static bool do_zzz_fn(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *gvec_fn)
+{
+if (sve_access_check(s)) {
+gen_gvec_fn_zzz(s, gvec_fn, a->esz, a->rd, a->rn, a->rm);
+}
+return true;
+}
+
 static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_and);
 }
 
 static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_or);
 }
 
 static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_xor, 0, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_xor);
 }
 
 static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_andc, 0, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_andc);
 }
 
 /*
@@ -300,32 +305,32 @@ static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
 
 static bool trans_ADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_add, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_add);
 }
 
 static bool trans_SUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_sub, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_sub);
 }
 
 static bool trans_SQADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_ssadd, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_ssadd);
 }
 
 static bool trans_SQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_sssub, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_sssub);
 }
 
 static bool trans_UQADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_usadd, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_usadd);
 }
 
 static bool trans_UQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_vector3_z(s, tcg_gen_gvec_ussub, a->esz, a->rd, a->rn, a->rm);
+return do_zzz_fn(s, a, tcg_gen_gvec_ussub);
 }
 
 /*
-- 
2.25.1




[PATCH 18/20] target/arm: Convert integer multiply (indexed) to gvec for aa64 advsimd

2020-08-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  4 
 target/arm/translate-a64.c | 16 
 target/arm/vec_helper.c| 29 +
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 759639a63a..d0573a53c8 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -758,6 +758,10 @@ DEF_HELPER_FLAGS_4(gvec_uaba_h, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_uaba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_uaba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(gvec_mul_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_mul_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_mul_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 42aa695dff..d08960a1c8 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13507,6 +13507,22 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
data, gen_helper_gvec_fmlal_idx_a64);
 }
 return;
+
+case 0x08: /* MUL */
+if (!is_long && !is_scalar) {
+static gen_helper_gvec_3 * const fns[3] = {
+gen_helper_gvec_mul_idx_h,
+gen_helper_gvec_mul_idx_s,
+gen_helper_gvec_mul_idx_d,
+};
+tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   is_q ? 16 : 8, vec_full_reg_size(s),
+   index, fns[size - 1]);
+return;
+}
+break;
 }
 
 if (size == 3) {
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
index bbd1141dfc..aa1de36921 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/vec_helper.c
@@ -711,6 +711,27 @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
  */
 
 #define DO_MUL_IDX(NAME, TYPE, H) \
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
+{  \
+intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE);  \
+intptr_t idx = simd_data(desc);\
+TYPE *d = vd, *n = vn, *m = vm;\
+for (i = 0; i < oprsz / sizeof(TYPE); i += segment) {  \
+TYPE mm = m[H(i + idx)];   \
+for (j = 0; j < segment; j++) {\
+d[i + j] = n[i + j] * mm;  \
+}  \
+}  \
+clear_tail(d, oprsz, simd_maxsz(desc));\
+}
+
+DO_MUL_IDX(gvec_mul_idx_h, uint16_t, H2)
+DO_MUL_IDX(gvec_mul_idx_s, uint32_t, H4)
+DO_MUL_IDX(gvec_mul_idx_d, uint64_t, )
+
+#undef DO_MUL_IDX
+
+#define DO_FMUL_IDX(NAME, TYPE, H) \
 void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
 {  \
 intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE);  \
@@ -725,11 +746,11 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void 
*stat, uint32_t desc) \
 clear_tail(d, oprsz, simd_maxsz(desc));\
 }
 
-DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
-DO_MUL_IDX(gvec_fmul_idx_s, float32, H4)
-DO_MUL_IDX(gvec_fmul_idx_d, float64, )
+DO_FMUL_IDX(gvec_fmul_idx_h, float16, H2)
+DO_FMUL_IDX(gvec_fmul_idx_s, float32, H4)
+DO_FMUL_IDX(gvec_fmul_idx_d, float64, )
 
-#undef DO_MUL_IDX
+#undef DO_FMUL_IDX
 
 #define DO_FMLA_IDX(NAME, TYPE, H) \
 void HELPER(NAME)(void *vd, void *vn, void *vm, void *va,  \
-- 
2.25.1




[PATCH 14/20] target/arm: Generalize inl_qrdmlah_* helper functions

2020-08-15 Thread Richard Henderson
Unify add/sub helpers and add a parameter for rounding.
This will allow saturating non-rounding to reuse this code.

Signed-off-by: Richard Henderson 
---
 target/arm/vec_helper.c | 80 +++--
 1 file changed, 29 insertions(+), 51 deletions(-)

diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
index 7d76412ee0..bbd1141dfc 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/vec_helper.c
@@ -37,19 +37,24 @@
 #endif
 
 /* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
-static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
-   int16_t src3, uint32_t *sat)
+static int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
+ bool neg, bool round, uint32_t *sat)
 {
-/* Simplify:
+/*
+ * Simplify:
  * = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
  * = ((a3 << 15) + (e1 * e2) + (1 << 14)) >> 15
  */
 int32_t ret = (int32_t)src1 * src2;
-ret = ((int32_t)src3 << 15) + ret + (1 << 14);
+if (neg) {
+ret = -ret;
+}
+ret += ((int32_t)src3 << 15) + (round << 14);
 ret >>= 15;
+
 if (ret != (int16_t)ret) {
 *sat = 1;
-ret = (ret < 0 ? -0x8000 : 0x7fff);
+ret = (ret < 0 ? INT16_MIN : INT16_MAX);
 }
 return ret;
 }
@@ -58,8 +63,9 @@ uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t 
src1,
   uint32_t src2, uint32_t src3)
 {
 uint32_t *sat = &env->vfp.qc[0];
-uint16_t e1 = inl_qrdmlah_s16(src1, src2, src3, sat);
-uint16_t e2 = inl_qrdmlah_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
+uint16_t e1 = do_sqrdmlah_h(src1, src2, src3, false, true, sat);
+uint16_t e2 = do_sqrdmlah_h(src1 >> 16, src2 >> 16, src3 >> 16,
+false, true, sat);
 return deposit32(e1, 16, 16, e2);
 }
 
@@ -73,35 +79,18 @@ void HELPER(gvec_qrdmlah_s16)(void *vd, void *vn, void *vm,
 uintptr_t i;
 
 for (i = 0; i < opr_sz / 2; ++i) {
-d[i] = inl_qrdmlah_s16(n[i], m[i], d[i], vq);
+d[i] = do_sqrdmlah_h(n[i], m[i], d[i], false, true, vq);
 }
 clear_tail(d, opr_sz, simd_maxsz(desc));
 }
 
-/* Signed saturating rounding doubling multiply-subtract high half, 16-bit */
-static int16_t inl_qrdmlsh_s16(int16_t src1, int16_t src2,
-   int16_t src3, uint32_t *sat)
-{
-/* Similarly, using subtraction:
- * = ((a3 << 16) - ((e1 * e2) << 1) + (1 << 15)) >> 16
- * = ((a3 << 15) - (e1 * e2) + (1 << 14)) >> 15
- */
-int32_t ret = (int32_t)src1 * src2;
-ret = ((int32_t)src3 << 15) - ret + (1 << 14);
-ret >>= 15;
-if (ret != (int16_t)ret) {
-*sat = 1;
-ret = (ret < 0 ? -0x8000 : 0x7fff);
-}
-return ret;
-}
-
 uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1,
   uint32_t src2, uint32_t src3)
 {
 uint32_t *sat = &env->vfp.qc[0];
-uint16_t e1 = inl_qrdmlsh_s16(src1, src2, src3, sat);
-uint16_t e2 = inl_qrdmlsh_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
+uint16_t e1 = do_sqrdmlah_h(src1, src2, src3, true, true, sat);
+uint16_t e2 = do_sqrdmlah_h(src1 >> 16, src2 >> 16, src3 >> 16,
+true, true, sat);
 return deposit32(e1, 16, 16, e2);
 }
 
@@ -115,19 +104,23 @@ void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void 
*vm,
 uintptr_t i;
 
 for (i = 0; i < opr_sz / 2; ++i) {
-d[i] = inl_qrdmlsh_s16(n[i], m[i], d[i], vq);
+d[i] = do_sqrdmlah_h(n[i], m[i], d[i], true, true, vq);
 }
 clear_tail(d, opr_sz, simd_maxsz(desc));
 }
 
 /* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
-static int32_t inl_qrdmlah_s32(int32_t src1, int32_t src2,
-   int32_t src3, uint32_t *sat)
+static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
+ bool neg, bool round, uint32_t *sat)
 {
 /* Simplify similarly to int_qrdmlah_s16 above.  */
 int64_t ret = (int64_t)src1 * src2;
-ret = ((int64_t)src3 << 31) + ret + (1 << 30);
+if (neg) {
+ret = -ret;
+}
+ret = ((int64_t)src3 << 31) + (round << 30);
 ret >>= 31;
+
 if (ret != (int32_t)ret) {
 *sat = 1;
 ret = (ret < 0 ? INT32_MIN : INT32_MAX);
@@ -139,7 +132,7 @@ uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t 
src1,
   int32_t src2, int32_t src3)
 {
 uint32_t *sat = &env->vfp.qc[0];
-return inl_qrdmlah_s32(src1, src2, src3, sat);
+return do_sqrdmlah_s(src1, src2, src3, false, true, sat);
 }
 
 void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm,
@@ -152,31 +145,16 @@ void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void 
*vm,
 uintptr_t i;
 
 for (i = 0; i < opr_sz / 4; ++i) {
-d[i] = inl_qrdmlah_s32(n[i], m[i], d[i], vq);
+d[i] = do_

RE: [PATCH v1 0/1] COLO: migrate dirty ram pages before colo checkpoint

2020-08-15 Thread Zhanghailiang
> -Original Message-
> From: Derek Su [mailto:jwsu1...@gmail.com]
> Sent: Thursday, August 13, 2020 6:28 PM
> To: Lukas Straub 
> Cc: Derek Su ; qemu-devel@nongnu.org; Zhanghailiang
> ; chy...@qnap.com; quint...@redhat.com;
> dgilb...@redhat.com; ctch...@qnap.com
> Subject: Re: [PATCH v1 0/1] COLO: migrate dirty ram pages before colo
> checkpoint
> 
> On Fri, Jul 31, 2020 at 3:52 PM Lukas Straub  wrote:
> >
> > On Sun, 21 Jun 2020 10:10:03 +0800
> > Derek Su  wrote:
> >
> > > This series is to reduce the guest's downtime during colo checkpoint
> > > by migrating dirty ram pages as many as possible before colo checkpoint.
> > >
> > > If the iteration count reaches COLO_RAM_MIGRATE_ITERATION_MAX or ram
> > > pending size is lower than 'x-colo-migrate-ram-threshold', stop the
> > > ram migration and do colo checkpoint.
> > >
> > > Test environment:
> > > The both primary VM and secondary VM has 1GiB ram and 10GbE NIC for
> > > FT traffic.
> > > One fio buffer write job runs on the guest.
> > > The result shows the total primary VM downtime is decreased by ~40%.
> > >
> > > Please help to review it and suggestions are welcomed.
> > > Thanks.
> >
> > Hello Derek,
> > Sorry for the late reply.
> > I think this is not a good idea, because it unnecessarily introduces a delay
> between checkpoint request and the checkpoint itself and thus impairs network
> bound workloads due to increased network latency. Workloads that are
> independent from network don't cause many checkpoints anyway, so it doesn't
> help there either.
> >
> 

Hi Derek,

Actually, There is a quit interesting question we should think: 
What will happen if VM continues to run after detected a mismatched state 
between PVM and SVM,
According to the rules of COLO, we should stop VMs immediately to sync the 
state between PVM and SVM,
But here, you choose them to continue to run for a while, then there may be 
more client's network packages
Coming, and may cause more memory pages dirty, another side effect is the new 
network packages will not
Be sent out with high probability, because their replies should be different 
since the state between PVM and SVM is different.

So, IMHO, it makes non-sense to let VMs to continue to run after detected them 
in different state.
Besides, I don't think it is easy to construct this case in tests.


Thanks,
Hailiang

s> Hello, Lukas & Zhanghailiang
> 
> Thanks for your opinions.
> I went through my patch, and I feel a little confused and would like to dig 
> into it
> more.
> 
> In this patch, colo_migrate_ram_before_checkpoint() is before
> COLO_MESSAGE_CHECKPOINT_REQUEST, so the SVM and PVM should not enter
> the pause state.
> 
> In the meanwhile, the packets to PVM/SVM can still be compared and notify
> inconsistency if mismatched, right?
> Is it possible to introduce extra network latency?
> 
> In my test (randwrite to disk by fio with direct=0), the ping from another 
> client to
> the PVM  using generic colo and colo used this patch are below.
> The network latency does not increase as my expectation.
> 
> generic colo
> ```
> 64 bytes from 192.168.80.18: icmp_seq=87 ttl=64 time=28.109 ms
> 64 bytes from 192.168.80.18: icmp_seq=88 ttl=64 time=16.747 ms
> 64 bytes from 192.168.80.18: icmp_seq=89 ttl=64 time=2388.779 ms
>  64 bytes from 192.168.80.18: icmp_seq=90 ttl=64 time=1385.792 ms
> 64 bytes from 192.168.80.18: icmp_seq=91 ttl=64 time=384.896 ms
>  64 bytes from 192.168.80.18: icmp_seq=92 ttl=64 time=3.895 ms
> 64 bytes from 192.168.80.18: icmp_seq=93 ttl=64 time=1.020 ms
> 64 bytes from 192.168.80.18: icmp_seq=94 ttl=64 time=0.865 ms
> 64 bytes from 192.168.80.18: icmp_seq=95 ttl=64 time=0.854 ms
> 64 bytes from 192.168.80.18: icmp_seq=96 ttl=64 time=28.359 ms
> 64 bytes from 192.168.80.18: icmp_seq=97 ttl=64 time=12.309 ms
> 64 bytes from 192.168.80.18: icmp_seq=98 ttl=64 time=0.870 ms
> 64 bytes from 192.168.80.18: icmp_seq=99 ttl=64 time=2371.733 ms
> 64 bytes from 192.168.80.18: icmp_seq=100 ttl=64 time=1371.440 ms
> 64 bytes from 192.168.80.18: icmp_seq=101 ttl=64 time=366.414 ms
> 64 bytes from 192.168.80.18: icmp_seq=102 ttl=64 time=0.818 ms
> 64 bytes from 192.168.80.18: icmp_seq=103 ttl=64 time=0.997 ms ```
> 
> colo used this patch
> ```
> 64 bytes from 192.168.80.18: icmp_seq=72 ttl=64 time=1.417 ms
> 64 bytes from 192.168.80.18: icmp_seq=73 ttl=64 time=0.931 ms
> 64 bytes from 192.168.80.18: icmp_seq=74 ttl=64 time=0.876 ms
> 64 bytes from 192.168.80.18: icmp_seq=75 ttl=64 time=1184.034 ms
>  64 bytes from 192.168.80.18: icmp_seq=76 ttl=64 time=181.297 ms
>  64 bytes from 192.168.80.18: icmp_seq=77 ttl=64 time=0.865 ms
> 64 bytes from 192.168.80.18: icmp_seq=78 ttl=64 time=0.858 ms
> 64 bytes from 192.168.80.18: icmp_seq=79 ttl=64 time=1.247 ms
> 64 bytes from 192.168.80.18: icmp_seq=80 ttl=64 time=0.946 ms
> 64 bytes from 192.168.80.18: icmp_seq=81 ttl=64 time=0.855 ms
> 64 bytes from 192.168.80.

[PATCH v3 2/3] target/arm: Add cpu properties to control pauth

2020-08-15 Thread Richard Henderson
The crypto overhead of emulating pauth can be significant for
some workloads.  Add two boolean properties that allows the
feature to be turned off, on with the architected algorithm,
or on with an implementation defined algorithm.

We need two intermediate booleans to control the state while
parsing properties lest we clobber ID_AA64ISAR1 into an invalid
intermediate state.

Reviewed-by: Andrew Jones 
Signed-off-by: Richard Henderson 
---
v2: Use boolean properties instead of an enum (drjones).
v3: Add tests (drjones).
---
 target/arm/cpu.h   | 10 +
 target/arm/cpu.c   | 13 +++
 target/arm/cpu64.c | 40 ++
 target/arm/monitor.c   |  1 +
 tests/qtest/arm-cpu-features.c | 13 +++
 5 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b87f03497f..776bf30cbc 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -196,9 +196,11 @@ typedef struct {
 #ifdef TARGET_AARCH64
 # define ARM_MAX_VQ16
 void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
 #else
 # define ARM_MAX_VQ1
 static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
+static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
 #endif
 
 typedef struct ARMVectorReg {
@@ -938,6 +940,14 @@ struct ARMCPU {
 uint64_t reset_cbar;
 uint32_t reset_auxcr;
 bool reset_hivecs;
+
+/*
+ * Intermediate values used during property parsing.
+ * Once finalized, the values should be read from ID_AA64ISAR1.
+ */
+bool prop_pauth;
+bool prop_pauth_impdef;
+
 /* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
 uint32_t dcz_blocksize;
 uint64_t rvbar;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 111579554f..c719562d3d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1307,6 +1307,19 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
 error_propagate(errp, local_err);
 return;
 }
+
+/*
+ * KVM does not support modifications to this feature.
+ * We have not registered the cpu properties when KVM
+ * is in use, so the user will not be able to set them.
+ */
+if (!kvm_enabled()) {
+arm_cpu_pauth_finalize(cpu, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+}
 }
 }
 
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index dd696183df..0227862d39 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -28,6 +28,8 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 #include "qapi/visitor.h"
+#include "hw/qdev-properties.h"
+
 
 #ifndef CONFIG_USER_ONLY
 static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -572,6 +574,36 @@ void aarch64_add_sve_properties(Object *obj)
 }
 }
 
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
+{
+int arch_val = 0, impdef_val = 0;
+uint64_t t;
+
+/* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
+if (cpu->prop_pauth) {
+if (cpu->prop_pauth_impdef) {
+impdef_val = 1;
+} else {
+arch_val = 1;
+}
+} else if (cpu->prop_pauth_impdef) {
+error_setg(errp, "cannot enable pauth-impdef without pauth");
+error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
+}
+
+t = cpu->isar.id_aa64isar1;
+t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
+t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
+cpu->isar.id_aa64isar1 = t;
+}
+
+static Property arm_cpu_pauth_property =
+DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
+static Property arm_cpu_pauth_impdef_property =
+DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
+
 /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
  * otherwise, a CPU with as many features enabled as our emulation supports.
  * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -627,10 +659,6 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
 t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
-t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
-t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
-t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
-t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
 t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
 t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
@@ -718,6 +746,10 @@ static void aarch64_max_initfn(Object *obj)
 cpu->ctr = 0x80038003; 

Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Rohit Shinde
Hey Philippe,

Thanks for the detailed comments! I have a couple of questions.


   1. I'll modify the patch to just include a fallthrough comment instead
   of an attribute. How do I include the v4 version number in the patch? Do I
   erase the last commit on my branch or fork from the master and start the
   work again and label it as v4?
   2. I am trying to find some issues of interest, starting through which I
   can go to bigger contributions. Do you have any suggestions on how I might
   do that? For now, I am trying to tackle the bite sized issues to find my
   way around the code base. I would like to move to substantial contributions.
   3. I have a background in CS theory, but its been 2 years since I
   graduated from my Master's so I am a bit rusty on some stuff. How much CS
   theory (like compilers and OS) do I need to know if I want to contribute?


Thanks,
Rohit.

On Sat, Aug 15, 2020 at 11:24 AM Philippe Mathieu-Daudé 
wrote:

> Hi Rohit,
>
> Congratulation for your first patch! It is in very
> good shape already :)
>
> It is easier for the reviewers if you start the patch subject with
> the name of the subsystem concerned, or the file modified:
>
> "qapi/opts-visitor: Add missing fallthrough annotations"
>
> On 8/15/20 3:00 PM, Rohit Shinde wrote:
> > Added the fallthrough comment so that the compiler doesn't emit an error
> on compiling with the -Wimplicit-fallthrough flag.
>
> If possible align the description to 72 chars.
>
> >
> > Signed off by: Rohit Shinde
>
> The tag is written "Signed-off-by" with '-', then your "name ":
>
> Signed-off-by: Rohit Shinde 
>
> If you configure your git client, using 'git-commit -s' will
> automatically add the S-o-b tag:
>
> $ git config user.name "Rohit Shinde"
> $ git config user.email "rohit.shinde12...@gmail.com"
> $ git commit -s
>
> > ---
> >  qapi/opts-visitor.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> > index 7781c23a42..43cf60d3a0 100644
> > --- a/qapi/opts-visitor.c
> > +++ b/qapi/opts-visitor.c
> > @@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t
> size)
> >  }
> >  ov->list_mode = LM_IN_PROGRESS;
> >  /* range has been completed, fall through in order to pop
> option */
> > +__attribute__((fallthrough));
>
> C uses attributes when declaring a type/variable/function.
> Here this is inside a function body, not a declaration.
> A simple "/* fallthrough */" comment will make the compiler happy.
> You can see a similar patch for example:
>
> https://git.qemu.org/?p=qemu.git;a=blobdiff;f=disas/sh4.c;h=dcdbdf26d8;hp=55ef865a3;hb=ccb237090f;hpb=7aa12aa215
>
> When you find an issue that might have already been fixed elsewhere
> in the repository, 'git-log -p' is your friend. Since the commits are
> patches already accepted/merged, they might be a good source to learn
> (how the issue was fixed, how the bug was described, ...).


> Regards,
>
> Phil.
>
> >
> >  case LM_IN_PROGRESS: {
> >  const QemuOpt *opt;
> >
>
>


Re: [PATCH v4 0/3] Modify AMD topology to use socket/dies/core/thread model

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/159744083536.39197.13827776633866601278.st...@naples-babu.amd.com/



Hi,

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

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

  CC  tests/test-timed-average.o
  CC  tests/test-util-filemonitor.o
/tmp/qemu-test/src/tests/test-x86-cpuid.c: In function 'test_topo_bits':
/tmp/qemu-test/src/tests/test-x86-cpuid.c:34:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 1};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:34:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:39:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 1};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:39:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:48:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:48:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:50:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 3};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:50:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:52:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 4};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:52:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:55:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 14};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:55:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:57:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 15};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:57:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:59:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 16};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:59:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:61:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 1, 17};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:61:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:65:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:65:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:67:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 31, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:67:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:69:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 32, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:69:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:71:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 33, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:71:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:74:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:74:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:76:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 2, 30, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:76:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:78:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInfo) {0, 3, 30, 2};
 ^
/tmp/qemu-test/src/tests/test-x86-cpuid.c:78:5: error: (near initialization for 
'(anonymous)') [-Werror]
/tmp/qemu-test/src/tests/test-x86-cpuid.c:80:5: error: excess elements in 
struct initializer [-Werror]
 topo_info = (X86CPUTopoInf

Re: [PATCH v5 14/14] kvm: remove kvm specific functions from global includes

2020-08-15 Thread Richard Henderson
On 8/12/20 11:32 AM, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
>  accel/kvm/kvm-cpus.h   |  7 +++
>  accel/stubs/kvm-stub.c | 22 --
>  include/sysemu/kvm.h   |  7 ---
>  3 files changed, 7 insertions(+), 29 deletions(-)

Reviewed-by: Richard Henderson 


r~



[PATCH 05/20] target/arm: Merge do_vector2_p into do_mov_p

2020-08-15 Thread Richard Henderson
This is the only user of the function.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index b0fa38db1c..d310709de3 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -178,18 +178,6 @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t 
word)
 tcg_gen_gvec_dup_imm(MO_64, vec_full_reg_offset(s, rd), vsz, vsz, word);
 }
 
-/* Invoke a vector expander on two Pregs.  */
-static bool do_vector2_p(DisasContext *s, GVecGen2Fn *gvec_fn,
- int esz, int rd, int rn)
-{
-if (sve_access_check(s)) {
-unsigned psz = pred_gvec_reg_size(s);
-gvec_fn(esz, pred_full_reg_offset(s, rd),
-pred_full_reg_offset(s, rn), psz, psz);
-}
-return true;
-}
-
 /* Invoke a vector expander on three Pregs.  */
 static bool do_vector3_p(DisasContext *s, GVecGen3Fn *gvec_fn,
  int esz, int rd, int rn, int rm)
@@ -221,7 +209,12 @@ static bool do_vecop4_p(DisasContext *s, const GVecGen4 
*gvec_op,
 /* Invoke a vector move on two Pregs.  */
 static bool do_mov_p(DisasContext *s, int rd, int rn)
 {
-return do_vector2_p(s, tcg_gen_gvec_mov, 0, rd, rn);
+if (sve_access_check(s)) {
+unsigned psz = pred_gvec_reg_size(s);
+tcg_gen_gvec_mov(MO_8, pred_full_reg_offset(s, rd),
+ pred_full_reg_offset(s, rn), psz, psz);
+}
+return true;
 }
 
 /* Set the cpu flags as per a return from an SVE helper.  */
-- 
2.25.1




[PATCH 02/10] numa: introduce MachineClass::forbid_asymmetrical_numa

2020-08-15 Thread Daniel Henrique Barboza
The pSeries machine does not support asymmetrical NUMA configurations.

CC: Eduardo Habkost 
CC: Marcel Apfelbaum 
Signed-off-by: Daniel Henrique Barboza 
---
 hw/core/numa.c  | 7 +++
 hw/ppc/spapr.c  | 1 +
 include/hw/boards.h | 1 +
 3 files changed, 9 insertions(+)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index d1a94a14f8..1e81233c1d 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -547,6 +547,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error 
**errp)
  */
 static void validate_numa_distance(MachineState *ms)
 {
+MachineClass *mc = MACHINE_GET_CLASS(ms);
 int src, dst;
 bool is_asymmetrical = false;
 int nb_numa_nodes = ms->numa_state->num_nodes;
@@ -575,6 +576,12 @@ static void validate_numa_distance(MachineState *ms)
 }
 
 if (is_asymmetrical) {
+if (mc->forbid_asymmetrical_numa) {
+error_report("This machine type does not support "
+ "asymmetrical numa distances.");
+exit(EXIT_FAILURE);
+}
+
 for (src = 0; src < nb_numa_nodes; src++) {
 for (dst = 0; dst < nb_numa_nodes; dst++) {
 if (src != dst && numa_info[src].distance[dst] == 0) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index dd2fa4826b..3b16edaf4c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4512,6 +4512,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
  */
 mc->numa_mem_align_shift = 28;
 mc->auto_enable_numa = true;
+mc->forbid_asymmetrical_numa = true;
 
 smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
 smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index bc5b82ad20..dc6cdd1c53 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -215,6 +215,7 @@ struct MachineClass {
 bool nvdimm_supported;
 bool numa_mem_supported;
 bool auto_enable_numa;
+bool forbid_asymmetrical_numa;
 const char *default_ram_id;
 
 HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
-- 
2.26.2




[PATCH 10/20] target/arm: Split out gen_gvec_ool_zzp

2020-08-15 Thread Richard Henderson
Model after gen_gvec_fn_zzz et al.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index ea6058f7ef..3361e1c01f 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -142,6 +142,17 @@ static int pred_gvec_reg_size(DisasContext *s)
 return size_for_gvec(pred_full_reg_size(s));
 }
 
+/* Invoke an out-of-line helper on 2 Zregs and a predicate. */
+static void gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
+ int rd, int rn, int pg, int data)
+{
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   pred_full_reg_offset(s, pg),
+   vsz, vsz, data, fn);
+}
+
 /* Invoke an out-of-line helper on 3 Zregs and a predicate. */
 static void gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
   int rd, int rn, int rm, int pg, int data)
@@ -415,11 +426,7 @@ static bool do_zpz_ool(DisasContext *s, arg_rpr_esz *a, 
gen_helper_gvec_3 *fn)
 return false;
 }
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   vsz, vsz, 0, fn);
+gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, 0);
 }
 return true;
 }
@@ -603,11 +610,7 @@ static bool do_movz_zpz(DisasContext *s, int rd, int rn, 
int pg,
 };
 
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
-   vec_full_reg_offset(s, rn),
-   pred_full_reg_offset(s, pg),
-   vsz, vsz, invert, fns[esz]);
+gen_gvec_ool_zzp(s, fns[esz], rd, rn, pg, invert);
 }
 return true;
 }
@@ -616,11 +619,7 @@ static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
 gen_helper_gvec_3 *fn)
 {
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   vsz, vsz, a->imm, fn);
+gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm);
 }
 return true;
 }
-- 
2.25.1




[PATCH 05/10] spapr: make ibm, max-associativity-domains scale with user input

2020-08-15 Thread Daniel Henrique Barboza
The ibm,max-associativity-domains is considering that only a single
associativity domain can exist in the same NUMA level. This is true
today because we do not support any type of NUMA distance user
customization, and all nodes are in the same distance to each other.

To enhance NUMA distance support in the pSeries machine we need to
make this limit flexible. This patch rewrites the max-associativity
logic to consider that multiple associativity domains can co-exist
in the same NUMA level. We're using the legacy_numa() helper to
avoid leaking unneeded guest changes.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 073a59c47d..b0c4b80a23 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -919,13 +919,20 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void 
*fdt)
 cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE & 0x),
 cpu_to_be32(ms->smp.max_cpus / ms->smp.threads),
 };
-uint32_t maxdomain = cpu_to_be32(spapr->extra_numa_nodes > 1 ? 1 : 0);
+
+/* The maximum domains for a given NUMA level, supposing that every
+ * additional NUMA node belongs to the same domain (aside from the
+ * 4th level, where we must support all available NUMA domains), is
+ * total number of domains - 1. */
+uint32_t total_nodes_number = ms->numa_state->num_nodes +
+  spapr->extra_numa_nodes;
+uint32_t maxdomain = cpu_to_be32(total_nodes_number - 1);
 uint32_t maxdomains[] = {
 cpu_to_be32(4),
 maxdomain,
 maxdomain,
 maxdomain,
-cpu_to_be32(ms->numa_state->num_nodes + spapr->extra_numa_nodes),
+cpu_to_be32(total_nodes_number),
 };
 
 _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
@@ -962,6 +969,13 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void 
*fdt)
  qemu_hypertas->str, qemu_hypertas->len));
 g_string_free(qemu_hypertas, TRUE);
 
+if (spapr_machine_using_legacy_numa(spapr)) {
+maxdomain = cpu_to_be32(spapr->extra_numa_nodes > 1 ? 1 : 0);
+maxdomains[1] = maxdomain;
+maxdomains[2] = maxdomain;
+maxdomains[3] = maxdomain;
+}
+
 if (smc->pre_5_1_assoc_refpoints) {
 nr_refpoints = 2;
 }
-- 
2.26.2




[PATCH 15/20] target/arm: Fix sve_uzp_p vs odd vector lengths

2020-08-15 Thread Richard Henderson
Missed out on compressing the second half of a predicate
with length vl % 512 > 256.

Adjust all of the x + (y << s) to x | (y << s) as a
general style fix.

Reported-by: Laurent Desnogues 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 30 +-
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 4758d46f34..fcb46f150f 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -1938,7 +1938,7 @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 if (oprsz <= 8) {
 l = compress_bits(n[0] >> odd, esz);
 h = compress_bits(m[0] >> odd, esz);
-d[0] = extract64(l + (h << (4 * oprsz)), 0, 8 * oprsz);
+d[0] = l | (h << (4 * oprsz));
 } else {
 ARMPredicateReg tmp_m;
 intptr_t oprsz_16 = oprsz / 16;
@@ -1952,23 +1952,35 @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 h = n[2 * i + 1];
 l = compress_bits(l >> odd, esz);
 h = compress_bits(h >> odd, esz);
-d[i] = l + (h << 32);
+d[i] = l | (h << 32);
 }
 
-/* For VL which is not a power of 2, the results from M do not
-   align nicely with the uint64_t for D.  Put the aligned results
-   from M into TMP_M and then copy it into place afterward.  */
+/*
+ * For VL which is not a multiple of 512, the results from M do not
+ * align nicely with the uint64_t for D.  Put the aligned results
+ * from M into TMP_M and then copy it into place afterward.
+ */
 if (oprsz & 15) {
-d[i] = compress_bits(n[2 * i] >> odd, esz);
+int final_shift = (oprsz & 15) * 2;
+
+l = n[2 * i + 0];
+h = n[2 * i + 1];
+l = compress_bits(l >> odd, esz);
+h = compress_bits(h >> odd, esz);
+d[i] = l | (h << final_shift);
 
 for (i = 0; i < oprsz_16; i++) {
 l = m[2 * i + 0];
 h = m[2 * i + 1];
 l = compress_bits(l >> odd, esz);
 h = compress_bits(h >> odd, esz);
-tmp_m.p[i] = l + (h << 32);
+tmp_m.p[i] = l | (h << 32);
 }
-tmp_m.p[i] = compress_bits(m[2 * i] >> odd, esz);
+l = m[2 * i + 0];
+h = m[2 * i + 1];
+l = compress_bits(l >> odd, esz);
+h = compress_bits(h >> odd, esz);
+tmp_m.p[i] = l | (h << final_shift);
 
 swap_memmove(vd + oprsz / 2, &tmp_m, oprsz / 2);
 } else {
@@ -1977,7 +1989,7 @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 h = m[2 * i + 1];
 l = compress_bits(l >> odd, esz);
 h = compress_bits(h >> odd, esz);
-d[oprsz_16 + i] = l + (h << 32);
+d[oprsz_16 + i] = l | (h << 32);
 }
 }
 }
-- 
2.25.1




Re: [PATCH v2 000/150] Meson integration for 5.2

2020-08-15 Thread Howard Spoelstra
On Fri, Aug 14, 2020 at 11:15 AM Paolo Bonzini  wrote:

>
> Hi Paolo,

I don't know how much of this is already meant to work, but I run into
several issues when compiling the latest code from the meson-poc-next
branch.

1. MSYS2-based Windows build: The guide to compile e.g., qemu-system-ppc on
Windows with Msys2 works OK to compile Qemu:
https://wiki.qemu.org/Hosts/W32#Native_builds_with_MSYS2
However, when I compile the meson-poc-next branch I run into the following
error:

hsp@HSP-W10-X64-I7 MINGW64 ~/src/qemu-meson-gitlab/build
$ ../configure --cross-prefix=x86_64-w64-mingw32- --target-list=ppc-softmmu
--enable-gtk --enable-sdl
...
Program python3 found: NO
../meson.build:32:0: ERROR: /mingw64/bin/python3 not found
A full log can be found at
C:/msys64/home/hsp/src/qemu-meson-gitlab/build/meson-logs/meson-log.txt
ERROR: meson setup failed

2. When cross compiling from Fedora 32 for Windows with
../configure --cross-prefix=x86_64-w64-mingw32- --enable-gtk --enable-sdl
--target-list=ppc-softmmu

I get the error below even though the v2 commit message says there is a fix
for the absolute path error included:

The Meson build system
Version: 0.55.0
Source dir: /home/hsp/src/qemu-meson-gitlab
Build dir: /home/hsp/src/qemu-meson-gitlab/build
Build type: cross build

../meson.build:1:0: ERROR: prefix value 'c:/Program Files/QEMU' must be an
absolute path

A full log can be found at
/home/hsp/src/qemu-meson-gitlab/build/meson-logs/meson-log.txt

ERROR: meson setup failed

3. As mentioned earlier here concerning a build on fedora 32 host:
https://lists.nongnu.org/archive/html/qemu-devel/2020-08/msg02307.html
Both SDL and GTK Guis do not seem to work, only the vnc server is started.

4. The v2 patch set seems to not apply cleanly to current qemu-master, I
get this error:
patching file docs/devel/build-system.rst (renamed from
docs/devel/build-system.txt)
Hunk #2 succeeded at 179 with fuzz 2 (offset 152 lines).
Hunk #3 succeeded at 187 (offset 152 lines).
Hunk #4 FAILED at 53.
Hunk #5 FAILED at 90.
Hunk #6 FAILED at 115.
Hunk #7 FAILED at 183.
Hunk #8 FAILED at 201.
Hunk #9 FAILED at 211.
Hunk #10 FAILED at 222.
Hunk #11 FAILED at 247.
Hunk #12 FAILED at 308.
Hunk #13 FAILED at 356.
Hunk #14 FAILED at 398.
Hunk #15 FAILED at 451.
12 out of 15 hunks FAILED -- saving rejects to file
docs/devel/build-system.rst.rej

5: And one question: Should the compiled binary etc be placed in the build
directory, or should they go into (in my case) the ppc-softmmu folder as
with a default build?

Best,
Howard


Re: [PATCH 6/7] hw/ide/pci: Replace magic '512' value by BDRV_SECTOR_SIZE

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:33写道:
>
> Use self-explicit definitions instead of magic '512' value.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  hw/ide/pci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 5e85c4ad17..b50091b615 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -138,7 +138,7 @@ static int32_t bmdma_prepare_buf(const IDEDMA *dma, 
> int32_t limit)
>  int l, len;
>
>  pci_dma_sglist_init(&s->sg, pci_dev,
> -s->nsector / (BMDMA_PAGE_SIZE / 512) + 1);
> +s->nsector / (BMDMA_PAGE_SIZE / BDRV_SECTOR_SIZE) + 
> 1);
>  s->io_buffer_size = 0;
>  for(;;) {
>  if (bm->cur_prd_len == 0) {
> --
> 2.21.3
>
>



[PATCH 04/20] target/arm: Rearrange {sve,fp}_check_access assert

2020-08-15 Thread Richard Henderson
We want to ensure that access is checked by the time we ask
for a specific fp/vector register.  We want to ensure that
we do not emit two lots of code to raise an exception.

But sometimes it's difficult to cleanly organize the code
such that we never pass through sve_check_access exactly once.
Allow multiple calls so long as the result is true, that is,
no exception to be raised.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |  1 +
 target/arm/translate-a64.c | 27 ---
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 16f2699ad7..ad7972eb22 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -64,6 +64,7 @@ typedef struct DisasContext {
  * that it is set at the point where we actually touch the FP regs.
  */
 bool fp_access_checked;
+bool sve_access_checked;
 /* ARMv8 single-step state (this is distinct from the QEMU gdbstub
  * single-step support).
  */
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 534c3ff5f3..42aa695dff 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1175,18 +1175,18 @@ static void do_vec_ld(DisasContext *s, int destidx, int 
element,
  * unallocated-encoding checks (otherwise the syndrome information
  * for the resulting exception will be incorrect).
  */
-static inline bool fp_access_check(DisasContext *s)
+static bool fp_access_check(DisasContext *s)
 {
-assert(!s->fp_access_checked);
-s->fp_access_checked = true;
+if (s->fp_excp_el) {
+assert(!s->fp_access_checked);
+s->fp_access_checked = true;
 
-if (!s->fp_excp_el) {
-return true;
+gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
+   syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
+return false;
 }
-
-gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
-   syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
-return false;
+s->fp_access_checked = true;
+return true;
 }
 
 /* Check that SVE access is enabled.  If it is, return true.
@@ -1195,10 +1195,14 @@ static inline bool fp_access_check(DisasContext *s)
 bool sve_access_check(DisasContext *s)
 {
 if (s->sve_excp_el) {
-gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
-   s->sve_excp_el);
+assert(!s->sve_access_checked);
+s->sve_access_checked = true;
+
+gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
+   syn_sve_access_trap(), s->sve_excp_el);
 return false;
 }
+s->sve_access_checked = true;
 return fp_access_check(s);
 }
 
@@ -14548,6 +14552,7 @@ static void disas_a64_insn(CPUARMState *env, 
DisasContext *s)
 s->base.pc_next += 4;
 
 s->fp_access_checked = false;
+s->sve_access_checked = false;
 
 if (dc_isar_feature(aa64_bti, s)) {
 if (s->base.num_insns == 1) {
-- 
2.25.1




Re: [RFC v3 26/71] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns

2020-08-15 Thread Frank Chang
On Sat, Aug 15, 2020 at 2:36 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 8/13/20 7:48 PM, Frank Chang wrote:
> > esz is passed from e.g. GEN_VEXT_LD_STRIDE() macro:
> >
> >> #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
> >> void HELPER(NAME)(void *vd, void * v0, target_ulong base,  \
> >>   target_ulong stride, CPURISCVState *env, \
> >>   uint32_t desc)   \
> >> {  \
> >> uint32_t vm = vext_vm(desc);   \
> >> vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \
> >>  sizeof(ETYPE), GETPC(), MMU_DATA_LOAD);   \
> >> }
> >>
> >> GEN_VEXT_LD_STRIDE(vlse8_v,  int8_t,  lde_b)
> >
> > which is calculated by sizeof(ETYPE), so the results would be: 1, 2, 4,
> 8.
> > and vext_max_elems() is called by e.g. vext_ldst_stride():
>
> Ah, yes.
>
> >> uint32_t max_elems = vext_max_elems(desc, esz);
> >
> > I can add another parameter to the macro and pass the hard-coded
> log2(esz) number
> > if it's the better way instead of using ctzl().
> > Or if there's another approach to get the log2(esz) number more
> elegantly?
>
> Using ctzl(sizeof(type)) in the GEN_VEXT_LD_STRIDE macro will work well.
> This
> will be constant folded by the compiler.
>
>
> r~
>

Nice, didn't come up with the compiler optimization.
Will fix the codes and send out a new version of patchset.
Thanks for the tips.

Frank Chang


[PATCH v3 3/3] target/arm: Use object_property_add_bool for "sve" property

2020-08-15 Thread Richard Henderson
The interface for object_property_add_bool is simpler,
making the code easier to understand.

Reviewed-by: Andrew Jones 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 24 ++--
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 0227862d39..cce0da0b90 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -488,6 +488,12 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor 
*v, const char *name,
 cpu->sve_max_vq = max_vq;
 }
 
+/*
+ * Note that cpu_arm_get/set_sve_vq cannot use the simpler
+ * object_property_add_bool interface because they make use
+ * of the contents of "name" to determine which bit on which
+ * to operate.
+ */
 static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
@@ -529,26 +535,17 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, 
const char *name,
 set_bit(vq - 1, cpu->sve_vq_init);
 }
 
-static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
+static bool cpu_arm_get_sve(Object *obj, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
-bool value = cpu_isar_feature(aa64_sve, cpu);
-
-visit_type_bool(v, name, &value, errp);
+return cpu_isar_feature(aa64_sve, cpu);
 }
 
-static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
+static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
-bool value;
 uint64_t t;
 
-if (!visit_type_bool(v, name, &value, errp)) {
-return;
-}
-
 if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
 error_setg(errp, "'sve' feature not supported by KVM on this host");
 return;
@@ -563,8 +560,7 @@ void aarch64_add_sve_properties(Object *obj)
 {
 uint32_t vq;
 
-object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
-cpu_arm_set_sve, NULL, NULL);
+object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
 
 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
 char name[8];
-- 
2.25.1




Re: [PATCH 1/7] block/null: Make more explicit the driver default size is 1GiB

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:29写道:
>
> As it is not obvious the default size for the null block driver
> is 1 GiB, replace the obfuscated '1 << 30' magic value by a
> definition using IEC binary prefixes.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  block/null.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/block/null.c b/block/null.c
> index 15e1d56746..8354def367 100644
> --- a/block/null.c
> +++ b/block/null.c
> @@ -11,6 +11,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qstring.h"
> @@ -21,6 +22,7 @@
>
>  #define NULL_OPT_LATENCY "latency-ns"
>  #define NULL_OPT_ZEROES  "read-zeroes"
> +#define NULL_OPT_SIZE(1 * GiB)
>
>  typedef struct {
>  int64_t length;
> @@ -86,7 +88,7 @@ static int null_file_open(BlockDriverState *bs, QDict 
> *options, int flags,
>  opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
>  qemu_opts_absorb_qdict(opts, options, &error_abort);
>  s->length =
> -qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 1 << 30);
> +qemu_opt_get_size(opts, BLOCK_OPT_SIZE, NULL_OPT_SIZE);
>  s->latency_ns =
>  qemu_opt_get_number(opts, NULL_OPT_LATENCY, 0);
>  if (s->latency_ns < 0) {
> --
> 2.21.3
>
>



[PATCH v3 0/3] target/arm: Implement an IMPDEF pauth algorithm

2020-08-15 Thread Richard Henderson
The architected pauth algorithm is quite slow without
hardware support, and boot times for kernels that enable
use of the feature have been significantly impacted.

Version 1 blurb at
  https://lists.nongnu.org/archive/html/qemu-devel/2020-08/msg02172.html
which contains larger study of the tradeoffs.

Version 2 changes:
  * Use boolean properties, for qmp_query_cpu_model_expansion (drjones).
  * Move XXH64 implementation to xxhash.h (ajb).
  * Include a small cleanup to parsing the "sve" property
that I noticed along the way.

Version 3 changes:
  * Swap order of patches (drjones).
  * Add properties test case (drjones).


r~

Richard Henderson (3):
  target/arm: Implement an IMPDEF pauth algorithm
  target/arm: Add cpu properties to control pauth
  target/arm: Use object_property_add_bool for "sve" property

 include/qemu/xxhash.h  | 82 ++
 target/arm/cpu.h   | 25 +--
 target/arm/cpu.c   | 13 ++
 target/arm/cpu64.c | 64 ++
 target/arm/monitor.c   |  1 +
 target/arm/pauth_helper.c  | 41 ++---
 tests/qtest/arm-cpu-features.c | 13 ++
 7 files changed, 212 insertions(+), 27 deletions(-)

-- 
2.25.1




[Bug 1877688] Re: 9p virtfs device reports error when opening certain files

2020-08-15 Thread Christian Schoenebeck
Fixed in QEMU 5.1 release.

** Changed in: qemu
   Status: Fix Committed => Fix Released

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

Title:
  9p virtfs device reports error when opening certain files

Status in QEMU:
  Fix Released

Bug description:
  Reading certain files on a 9p mounted FS produces this error message:

  qemu-system-x86_64: VirtFS reply type 117 needs 12 bytes, buffer has
  12, less than minimum

  After this error message is generated, further accesses to the 9p FS
  hangs whatever tries to access it. The Arch Linux guest system is
  otherwise usable. This happens with QEMU 5.0.0 and guest kernel
  version 5.6.11, hosted on an Arch Linux distro. I use the following
  command to launch QEMU:

  exec qemu-system-x86_64 -enable-kvm -display gtk -vga virtio -cpu host
  -m 4G -netdev tap,ifname=vmtap0,id=vn0,script=no,downscript=no -device
  virtio-net-pci,netdev=vn0 -kernel kernel.img -drive
  file=file.img,format=raw,if=virtio -virtfs
  local,path=mnt,mount_tag=host0,security_model=passthrough,id=host0
  -append "console=ttyS0 root=/dev/vda rw"

  There's nothing relevant in the guest kernel logs as far as I'm aware
  of with loglevel set to 7.

  I tracked down the issue to readv() with a small buffer(<=12 bytes)
  and then a large buffer(>= 1024 bytes). A C program is provided to
  trigger this behavior.

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



Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200815151245.10640-1-rohit.shinde12...@gmail.com/



Hi,

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

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

  CC  qapi/qapi-visit-rdma.o
  CC  qapi/qapi-visit-rocker.o
/tmp/qemu-test/src/qapi/opts-visitor.c: In function 'opts_next_list':
/tmp/qemu-test/src/qapi/opts-visitor.c:269:9: error: empty declaration [-Werror]
 __attribute__((fallthrough));
 ^
cc1: all warnings being treated as errors
make: *** [qapi/opts-visitor.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 709, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=b5dcb092e02343cf9cd6f3efc4966930', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-vem4s832/src/docker-src.2020-08-15-12.28.53.24667:/var/tmp/qemu:z,ro',
 'qemu/centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=b5dcb092e02343cf9cd6f3efc4966930
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-vem4s832/src'
make: *** [docker-run-test-quick@centos7] Error 2

real1m44.566s
user0m9.282s


The full log is available at
http://patchew.org/logs/20200815151245.10640-1-rohit.shinde12...@gmail.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH 4/7] hw/ide/ahci: Replace magic '512' value by BDRV_SECTOR_SIZE

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:31写道:
>
> Use self-explicit definitions instead of magic '512' value.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  hw/ide/ahci.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 009120f88b..b696c6291a 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1151,7 +1151,7 @@ static void process_ncq_command(AHCIState *s, int port, 
> uint8_t *cmd_fis,
>  if (!ncq_tfs->sector_count) {
>  ncq_tfs->sector_count = 0x1;
>  }
> -size = ncq_tfs->sector_count * 512;
> +size = ncq_tfs->sector_count * BDRV_SECTOR_SIZE;
>  ahci_populate_sglist(ad, &ncq_tfs->sglist, ncq_tfs->cmdh, size, 0);
>
>  if (ncq_tfs->sglist.size < size) {
> @@ -1703,7 +1703,8 @@ static int ahci_state_post_load(void *opaque, int 
> version_id)
>  return -1;
>  }
>  ahci_populate_sglist(ncq_tfs->drive, &ncq_tfs->sglist,
> - ncq_tfs->cmdh, ncq_tfs->sector_count * 512,
> + ncq_tfs->cmdh,
> + ncq_tfs->sector_count * BDRV_SECTOR_SIZE,
>   0);
>  if (ncq_tfs->sector_count != ncq_tfs->sglist.size >> 9) {
>  return -1;
> --
> 2.21.3
>
>



[PATCH v3 1/3] target/arm: Implement an IMPDEF pauth algorithm

2020-08-15 Thread Richard Henderson
Without hardware acceleration, a cryptographically strong
algorithm is too expensive for pauth_computepac.

Even with hardware accel, we are not currently expecting
to link the linux-user binaries to any crypto libraries,
and doing so would generally make the --static build fail.

So choose XXH64 as a reasonably quick and decent hash.

Signed-off-by: Richard Henderson 
---
v2: Move the XXH64 bits to xxhash.h (ajb).
Create isar_feature_aa64_pauth_arch and fixup a comment
in isar_feature_aa64_pauth that no longer applies.
---
 include/qemu/xxhash.h | 82 +++
 target/arm/cpu.h  | 15 +--
 target/arm/pauth_helper.c | 41 +---
 3 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/include/qemu/xxhash.h b/include/qemu/xxhash.h
index 076f1f6054..cf45859a19 100644
--- a/include/qemu/xxhash.h
+++ b/include/qemu/xxhash.h
@@ -119,4 +119,86 @@ static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t 
cd, uint32_t e,
 return qemu_xxhash7(ab, cd, e, f, 0);
 }
 
+/*
+ * Component parts of the XXH64 algorithm from
+ * https://github.com/Cyan4973/xxHash/blob/v0.8.0/xxhash.h
+ *
+ * The complete algorithm looks like
+ *
+ *  i = 0;
+ *  if (len >= 32) {
+ *  v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
+ *  v2 = seed + XXH_PRIME64_2;
+ *  v3 = seed + 0;
+ *  v4 = seed - XXH_PRIME64_1;
+ *  do {
+ *  v1 = XXH64_round(v1, get64bits(input + i));
+ *  v2 = XXH64_round(v2, get64bits(input + i + 8));
+ *  v3 = XXH64_round(v3, get64bits(input + i + 16));
+ *  v4 = XXH64_round(v4, get64bits(input + i + 24));
+ *  } while ((i += 32) <= len);
+ *  h64 = XXH64_mergerounds(v1, v2, v3, v4);
+ *  } else {
+ *  h64 = seed + XXH_PRIME64_5;
+ *  }
+ *  h64 += len;
+ *
+ *  for (; i + 8 <= len; i += 8) {
+ *  h64 ^= XXH64_round(0, get64bits(input + i));
+ *  h64 = rol64(h64, 27) * XXH_PRIME64_1 + XXH_PRIME64_4;
+ *  }
+ *  for (; i + 4 <= len; i += 4) {
+ *  h64 ^= get32bits(input + i) * PRIME64_1;
+ *  h64 = rol64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
+ *  }
+ *  for (; i < len; i += 1) {
+ *  h64 ^= get8bits(input + i) * XXH_PRIME64_5;
+ *  h64 = rol64(h64, 11) * XXH_PRIME64_1;
+ *  }
+ *
+ *  return XXH64_avalanche(h64)
+ *
+ * Exposing the pieces instead allows for simplified usage when
+ * the length is a known constant and the inputs are in registers.
+ */
+#define XXH_PRIME64_1   0x9E3779B185EBCA87ULL
+#define XXH_PRIME64_2   0xC2B2AE3D27D4EB4FULL
+#define XXH_PRIME64_3   0x165667B19E3779F9ULL
+#define XXH_PRIME64_4   0x85EBCA77C2B2AE63ULL
+#define XXH_PRIME64_5   0x27D4EB2F165667C5ULL
+
+static inline uint64_t XXH64_round(uint64_t acc, uint64_t input)
+{
+return rol64(acc + input * XXH_PRIME64_2, 31) * XXH_PRIME64_1;
+}
+
+static inline uint64_t XXH64_mergeround(uint64_t acc, uint64_t val)
+{
+return (acc ^ XXH64_round(0, val)) * XXH_PRIME64_1 + XXH_PRIME64_4;
+}
+
+static inline uint64_t XXH64_mergerounds(uint64_t v1, uint64_t v2,
+ uint64_t v3, uint64_t v4)
+{
+uint64_t h64;
+
+h64 = rol64(v1, 1) + rol64(v2, 7) + rol64(v3, 12) + rol64(v4, 18);
+h64 = XXH64_mergeround(h64, v1);
+h64 = XXH64_mergeround(h64, v2);
+h64 = XXH64_mergeround(h64, v3);
+h64 = XXH64_mergeround(h64, v4);
+
+return h64;
+}
+
+static inline uint64_t XXH64_avalanche(uint64_t h64)
+{
+h64 ^= h64 >> 33;
+h64 *= XXH_PRIME64_2;
+h64 ^= h64 >> 29;
+h64 *= XXH_PRIME64_3;
+h64 ^= h64 >> 32;
+return h64;
+}
+
 #endif /* QEMU_XXHASH_H */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9e8ed423ea..b87f03497f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3757,10 +3757,8 @@ static inline bool isar_feature_aa64_fcma(const 
ARMISARegisters *id)
 static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
 {
 /*
- * Note that while QEMU will only implement the architected algorithm
- * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
- * defined algorithms, and thus API+GPI, and this predicate controls
- * migration of the 128-bit keys.
+ * Return true if any form of pauth is enabled, as this
+ * predicate controls migration of the 128-bit keys.
  */
 return (id->id_aa64isar1 &
 (FIELD_DP64(0, ID_AA64ISAR1, APA, 0xf) |
@@ -3769,6 +3767,15 @@ static inline bool isar_feature_aa64_pauth(const 
ARMISARegisters *id)
  FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
 }
 
+static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id)
+{
+/*
+ * Return true if pauth is enabled with the architected QARMA algorithm.
+ * QEMU will always set APA+GPA to the same value.
+ */
+return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
+}
+
 static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
diff 

Re: [PATCH v5 13/14] hax: remove hax specific functions from global includes

2020-08-15 Thread Richard Henderson
On 8/12/20 11:32 AM, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
>  accel/stubs/hax-stub.c| 10 --
>  include/sysemu/hax.h  | 17 -
>  target/i386/hax-all.c |  1 -
>  target/i386/hax-cpus.c|  1 -
>  target/i386/hax-cpus.h| 16 
>  target/i386/hax-mem.c |  2 +-
>  target/i386/hax-posix.c   |  3 +--
>  target/i386/hax-windows.c |  2 +-
>  target/i386/hax-windows.h |  2 ++
>  9 files changed, 21 insertions(+), 33 deletions(-)

Reviewed-by: Richard Henderson 


r~



[PATCH 11/20] target/arm: Split out gen_gvec_ool_zzz

2020-08-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 53 +-
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 3361e1c01f..3a90a645fd 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -142,6 +142,17 @@ static int pred_gvec_reg_size(DisasContext *s)
 return size_for_gvec(pred_full_reg_size(s));
 }
 
+/* Invoke an out-of-line helper on 3 Zregs. */
+static void gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn,
+ int rd, int rn, int rm, int data)
+{
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vsz, vsz, data, fn);
+}
+
 /* Invoke an out-of-line helper on 2 Zregs and a predicate. */
 static void gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
  int rd, int rn, int pg, int data)
@@ -769,11 +780,7 @@ static bool do_zzw_ool(DisasContext *s, arg_rrr_esz *a, 
gen_helper_gvec_3 *fn)
 return false;
 }
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, 0, fn);
+gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, 0);
 }
 return true;
 }
@@ -947,11 +954,7 @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
 static bool do_adr(DisasContext *s, arg_rrri *a, gen_helper_gvec_3 *fn)
 {
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, a->imm, fn);
+gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm);
 }
 return true;
 }
@@ -1012,11 +1015,7 @@ static bool trans_FTSSEL(DisasContext *s, arg_rrr_esz *a)
 return false;
 }
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, 0, fns[a->esz]);
+gen_gvec_ool_zzz(s, fns[a->esz], a->rd, a->rn, a->rm, 0);
 }
 return true;
 }
@@ -2067,11 +2066,7 @@ static bool trans_TBL(DisasContext *s, arg_rrr_esz *a)
 };
 
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, 0, fns[a->esz]);
+gen_gvec_ool_zzz(s, fns[a->esz], a->rd, a->rn, a->rm, 0);
 }
 return true;
 }
@@ -2244,11 +2239,7 @@ static bool do_zzz_data_ool(DisasContext *s, arg_rrr_esz 
*a, int data,
 gen_helper_gvec_3 *fn)
 {
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, data, fn);
+gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, data);
 }
 return true;
 }
@@ -3373,11 +3364,7 @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz 
*a)
 };
 
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, 0, fns[a->u][a->sz]);
+gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, 0);
 }
 return true;
 }
@@ -3390,11 +3377,7 @@ static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx 
*a)
 };
 
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vsz, vsz, a->index, fns[a->u][a->sz]);
+gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, a->index);
 }
 return true;
 }
-- 
2.25.1




Re: [PATCH 10/18] hw/sd: Add Cadence SDHCI emulation

2020-08-15 Thread Philippe Mathieu-Daudé
On 8/14/20 6:40 PM, Bin Meng wrote:
> From: Bin Meng 
> 
> Cadence SD/SDIO/eMMC Host Controller (SD4HC) is an SDHCI compatible
> controller. The SDHCI compatible registers start from offset 0x200,
> which are called Slot Register Set (SRS) in its datasheet.
> 
> This creates a Cadence SDHCI model built on top of the existing
> generic SDHCI model. Cadence specific Host Register Set (HRS) is
> implemented to make guest software happy.
> 
> Signed-off-by: Bin Meng 
> ---
> 
>  hw/sd/Kconfig |   4 ++
>  hw/sd/Makefile.objs   |   1 +
>  hw/sd/cadence_sdhci.c | 162 
> ++
>  include/hw/sd/cadence_sdhci.h |  65 +
>  4 files changed, 232 insertions(+)
>  create mode 100644 hw/sd/cadence_sdhci.c
>  create mode 100644 include/hw/sd/cadence_sdhci.h

Please consider using scripts/git.orderfile.

> 
> diff --git a/hw/sd/Kconfig b/hw/sd/Kconfig
> index c5e1e55..633b9af 100644
> --- a/hw/sd/Kconfig
> +++ b/hw/sd/Kconfig
> @@ -19,3 +19,7 @@ config SDHCI_PCI
>  default y if PCI_DEVICES
>  depends on PCI
>  select SDHCI
> +
> +config CADENCE_SDHCI
> +bool
> +select SDHCI
> diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
> index 0d1df17..4d500a6 100644
> --- a/hw/sd/Makefile.objs
> +++ b/hw/sd/Makefile.objs
> @@ -10,3 +10,4 @@ common-obj-$(CONFIG_OMAP) += omap_mmc.o
>  common-obj-$(CONFIG_PXA2XX) += pxa2xx_mmci.o
>  common-obj-$(CONFIG_RASPI) += bcm2835_sdhost.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_sdhci.o
> +common-obj-$(CONFIG_CADENCE_SDHCI) += cadence_sdhci.o
> diff --git a/hw/sd/cadence_sdhci.c b/hw/sd/cadence_sdhci.c
> new file mode 100644
> index 000..67ffd14
> --- /dev/null
> +++ b/hw/sd/cadence_sdhci.c
> @@ -0,0 +1,162 @@
> +/*
> + * Cadence SDHCI emulation
> + *
> + * Copyright (c) 2020 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 or
> + * (at your option) version 3 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "migration/vmstate.h"
> +#include "hw/irq.h"
> +#include "hw/sd/cadence_sdhci.h"
> +#include "sdhci-internal.h"
> +
> +#define TO_REG(addr)((addr) / sizeof(uint32_t))
> +
> +static void cadence_sdhci_reset(DeviceState *dev)
> +{
> +CadenceSDHCIState *sdhci = CADENCE_SDHCI(dev);

We usually use 's' for the model state.

> +
> +memset(sdhci->regs, 0, CADENCE_SDHCI_REG_SIZE);
> +sdhci->regs[TO_REG(SDHCI_CDNS_HRS00)] = SDHCI_CDNS_HRS00_POR_VAL;

As commented in previous patch, here goes:

   device_legacy_reset(DEVICE(&sdhci->slot));

> +}
> +
> +static uint64_t cadence_sdhci_read(void *opaque, hwaddr addr, unsigned int 
> size)
> +{
> +uint32_t val = 0;
> +CadenceSDHCIState *sdhci = opaque;
> +
> +if (addr < CADENCE_SDHCI_REG_SIZE) {
> +val = sdhci->regs[TO_REG(addr)];
> +} else {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Out-of-bounds read at 0x%" HWADDR_PRIx "\n",
> +  __func__, addr);
> +}
> +
> +return (uint64_t)val;
> +}
> +
> +static void cadence_sdhci_write(void *opaque, hwaddr addr, uint64_t val,
> +unsigned int size)
> +{
> +CadenceSDHCIState *sdhci = opaque;
> +uint32_t val32 = (uint32_t)val;
> +
> +switch (addr) {
> +case SDHCI_CDNS_HRS00:
> +/*
> + * The only writable bit is SWR (software reset) and it automatically
> + * clears to zero, so essentially this register remains unchanged.
> + */
> +if (val32 & SDHCI_CDNS_HRS00_SWR) {
> +cadence_sdhci_reset(DEVICE(sdhci));
> +sdhci_poweron_reset(DEVICE(&sdhci->slot));

The 'slot' reset has to go in cadence_sdhci_reset().

> +}
> +
> +break;
> +case SDHCI_CDNS_HRS04:
> +/*
> + * Only emulate the ACK bit behavior when read or write transaction
> + * are requested.
> + */
> +if (val32 & (SDHCI_CDNS_HRS04_WR | SDHCI_CDNS_HRS04_RD)) {
> +val32 |= SDHCI_CDNS_HRS04_ACK;
> +} else {
> +val32 &= ~SDHCI_CDNS_HRS04_ACK;
> +}
> +
> +sdhci->regs[TO_REG(addr)] = val32;
> +break;
> +case SDHCI_CDNS_HRS06:
> +if (val32 & SDHCI_CDNS_HRS06_TUNE_UP) {
> +val32 &= ~SD

Re: [PATCH 09/18] hw/sd: sdhci: Make sdhci_poweron_reset() internal visible

2020-08-15 Thread Philippe Mathieu-Daudé
On 8/14/20 6:40 PM, Bin Meng wrote:
> From: Bin Meng 
> 
> sdhci_poweron_reset() might be needed for any SDHCI compatible
> device that is built on top of the generic SDHCI device.

NAck. Please use device_legacy_reset() instead.

In next patch:

  device_legacy_reset(DEVICE(&sdhci->slot));

Thanks,

Phil.

> 
> Signed-off-by: Bin Meng 
> ---
> 
>  hw/sd/sdhci-internal.h | 1 +
>  hw/sd/sdhci.c  | 2 +-
>  2 files changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
> index e8c753d..b587e8e 100644
> --- a/hw/sd/sdhci-internal.h
> +++ b/hw/sd/sdhci-internal.h
> @@ -342,5 +342,6 @@ void sdhci_uninitfn(SDHCIState *s);
>  void sdhci_common_realize(SDHCIState *s, Error **errp);
>  void sdhci_common_unrealize(SDHCIState *s);
>  void sdhci_common_class_init(ObjectClass *klass, void *data);
> +void sdhci_poweron_reset(DeviceState *dev);
>  
>  #endif
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index deac181..20f2fe0 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -294,7 +294,7 @@ static void sdhci_reset(SDHCIState *s)
>  s->pending_insert_state = false;
>  }
>  
> -static void sdhci_poweron_reset(DeviceState *dev)
> +void sdhci_poweron_reset(DeviceState *dev)
>  {
>  /* QOM (ie power-on) reset. This is identical to reset
>   * commanded via device register apart from handling of the
> 




Re: [PATCH 07/18] hw/sd: sd: Fix incorrect populated function switch status data structure

2020-08-15 Thread Philippe Mathieu-Daudé
+Sai Pavan

On 8/14/20 6:40 PM, Bin Meng wrote:
> From: Bin Meng 
> 
> At present the function switch status data structure bit [399:376]
> are wrongly pupulated. These 3 bytes encode function switch status
> for the 6 function groups, with 4 bits per group, starting from
> function group 6 at bit 399, then followed by function group 5 at
> bit 395, and so on.
> 
> However the codes mistakenly fills in the function group 1 status
> at bit 399. This fixes the code logic.
> 

Fixes: a1bb27b1e9 ("SD card emulation (initial implementation)")

> Signed-off-by: Bin Meng 
> ---
> 
>  hw/sd/sd.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index fad9cf1..51f5900 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -806,11 +806,15 @@ static void sd_function_switch(SDState *sd, uint32_t 
> arg)
>  sd->data[11] = 0x43;
>  sd->data[12] = 0x80; /* Supported group 1 functions */
>  sd->data[13] = 0x03;
> +
> +sd->data[14] = 0;
> +sd->data[15] = 0;
> +sd->data[16] = 0;

Pointless zero initialization.

Reviewed-by: Philippe Mathieu-Daudé 

I'll wait until next week in case Sai Pavan wants to test this
patch (I don't have access to the Xilinx images anymore) then
I'll queue this via my sd-next tree.

Regards,

Phil.

>  for (i = 0; i < 6; i ++) {
>  new_func = (arg >> (i * 4)) & 0x0f;
>  if (mode && new_func != 0x0f)
>  sd->function_group[i] = new_func;
> -sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
> +sd->data[16 - (i >> 1)] |= new_func << ((i % 2) * 4);
>  }
>  memset(&sd->data[17], 0, 47);
>  stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
> 




Re: [PATCH 3/7] hw/ide/core: Replace magic '512' value by BDRV_SECTOR_SIZE

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:31写道:
>
> Use self-explicit definitions instead of magic '512' value.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  hw/ide/core.c | 23 ---
>  1 file changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index f76f7e5234..bcb2aa85fc 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -121,7 +121,7 @@ static void ide_identify(IDEState *s)
>  put_le16(p + 0, 0x0040);
>  put_le16(p + 1, s->cylinders);
>  put_le16(p + 3, s->heads);
> -put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
> +put_le16(p + 4, BDRV_SECTOR_SIZE * s->sectors); /* XXX: retired, remove 
> ? */
>  put_le16(p + 5, 512); /* XXX: retired, remove ? */
>  put_le16(p + 6, s->sectors);
>  padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
> @@ -864,7 +864,7 @@ static void ide_dma_cb(void *opaque, int ret)
>  }
>  }
>
> -if (s->io_buffer_size > s->nsector * 512) {
> +if (s->io_buffer_size > s->nsector * BDRV_SECTOR_SIZE) {
>  /*
>   * The PRDs were longer than needed for this request.
>   * The Active bit must remain set after the request completes.
> @@ -877,7 +877,7 @@ static void ide_dma_cb(void *opaque, int ret)
>
>  sector_num = ide_get_sector(s);
>  if (n > 0) {
> -assert(n * 512 == s->sg.size);
> +assert(n * BDRV_SECTOR_SIZE == s->sg.size);
>  dma_buf_commit(s, s->sg.size);
>  sector_num += n;
>  ide_set_sector(s, sector_num);
> @@ -894,17 +894,17 @@ static void ide_dma_cb(void *opaque, int ret)
>  /* launch next transfer */
>  n = s->nsector;
>  s->io_buffer_index = 0;
> -s->io_buffer_size = n * 512;
> +s->io_buffer_size = n * BDRV_SECTOR_SIZE;
>  prep_size = s->bus->dma->ops->prepare_buf(s->bus->dma, 
> s->io_buffer_size);
>  /* prepare_buf() must succeed and respect the limit */
> -assert(prep_size >= 0 && prep_size <= n * 512);
> +assert(prep_size >= 0 && prep_size <= n * BDRV_SECTOR_SIZE);
>
>  /*
>   * Now prep_size stores the number of bytes in the sglist, and
>   * s->io_buffer_size stores the number of bytes described by the PRDs.
>   */
>
> -if (prep_size < n * 512) {
> +if (prep_size < n * BDRV_SECTOR_SIZE) {
>  /*
>   * The PRDs are too short for this request. Error condition!
>   * Reset the Active bit and don't raise the interrupt.
> @@ -1412,7 +1412,8 @@ static bool cmd_identify(IDEState *s, uint8_t cmd)
>  ide_cfata_identify(s);
>  }
>  s->status = READY_STAT | SEEK_STAT;
> -ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
> +ide_transfer_start(s, s->io_buffer, BDRV_SECTOR_SIZE,
> +   ide_transfer_stop);
>  ide_set_irq(s->bus);
>  return false;
>  } else {
> @@ -1482,7 +1483,7 @@ static bool cmd_write_multiple(IDEState *s, uint8_t cmd)
>  n = MIN(s->nsector, s->req_nb_sectors);
>
>  s->status = SEEK_STAT | READY_STAT;
> -ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
> +ide_transfer_start(s, s->io_buffer, BDRV_SECTOR_SIZE * n, 
> ide_sector_write);
>
>  s->media_changed = 1;
>
> @@ -1524,7 +1525,7 @@ static bool cmd_write_pio(IDEState *s, uint8_t cmd)
>
>  s->req_nb_sectors = 1;
>  s->status = SEEK_STAT | READY_STAT;
> -ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
> +ide_transfer_start(s, s->io_buffer, BDRV_SECTOR_SIZE, ide_sector_write);
>
>  s->media_changed = 1;
>
> @@ -1678,7 +1679,7 @@ static bool cmd_identify_packet(IDEState *s, uint8_t 
> cmd)
>  {
>  ide_atapi_identify(s);
>  s->status = READY_STAT | SEEK_STAT;
> -ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
> +ide_transfer_start(s, s->io_buffer, BDRV_SECTOR_SIZE, ide_transfer_stop);
>  ide_set_irq(s->bus);
>  return false;
>  }
> @@ -2559,7 +2560,7 @@ static void ide_init1(IDEBus *bus, int unit)
>  s->unit = unit;
>  s->drive_serial = drive_serial++;
>  /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
> -s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
> +s->io_buffer_total_len = IDE_DMA_BUF_SECTORS * BDRV_SECTOR_SIZE + 4;
>  s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
>  memset(s->io_buffer, 0, s->io_buffer_total_len);
>
> --
> 2.21.3
>
>



[PATCH 00/10] pseries NUMA distance rework

2020-08-15 Thread Daniel Henrique Barboza
Hi,

This series implements a new approach to the NUMA code in
the spapr machine. We're now able to make an attempt to
try to take user input in consideration, instead of ignoring
any user input regarding NUMA distance.

This series was rebased upon David's ppc-for-5.2 tree. More
information about what are being done here can be found in
the specs/ppc-spapr-numa.rst file (only available in David's
branch ATM). This is also available in [1].

First patch is the patch from Cornelia that added the 5.2 machine
type. I included it here because I built upon it for compatibility
code.

Second patch adds a flag to hw/core/numa.c to forbid assymetrical
topologies for the spapr machine, since we do not support that.

All other patches are focused on cleanups/code juggling and
the actual implementation inside the ppc/spapr files.

With this patch, we're now able to at least attempt to honor
user input. Patch 10 has examples of how the code is working
and what is to expect and, most important, what to not
expect.

NOTE: for anyone willing to test this series, be warned that there
is a bug in the Linux kernel, causing any associativity information
for the node 0 to be discarded. A patch was sent in [2] to try to 
fix that.


[1] https://github.com/danielhb/qemu/tree/spapr_numa_v1
[2] 
https://lore.kernel.org/linuxppc-dev/20200814203413.542050-1-danielhb...@gmail.com/T/#m5c85daff828d8c8156781f9f957ad04903e93151

Cornelia Huck (1):
  hw: add compat machines for 5.2

Daniel Henrique Barboza (9):
  numa: introduce MachineClass::forbid_asymmetrical_numa
  spapr: robustify NVLink2 NUMA node logic
  spapr: add spapr_machine_using_legacy_numa() helper
  spapr: make ibm,max-associativity-domains scale with user input
  spapr: allow 4 NUMA levels in ibm,associativity-reference-points
  spapr: create helper to set ibm,associativity
  spapr: introduce SpaprMachineClass::numa_assoc_domains
  spapr: consider user input when defining spapr guest NUMA
  specs/ppc-spapr-numa: update with new NUMA support

 docs/specs/ppc-spapr-numa.rst | 213 ++
 hw/arm/virt.c |   9 +-
 hw/core/machine.c |   3 +
 hw/core/numa.c|   7 +
 hw/i386/pc.c  |   3 +
 hw/i386/pc_piix.c |  14 +-
 hw/i386/pc_q35.c  |  13 +-
 hw/ppc/spapr.c| 239 +-
 hw/ppc/spapr_hcall.c  |  13 +-
 hw/ppc/spapr_nvdimm.c |  19 ++-
 hw/ppc/spapr_pci.c|  42 +-
 hw/ppc/spapr_pci_nvlink2.c|  10 +-
 hw/s390x/s390-virtio-ccw.c|  14 +-
 include/hw/boards.h   |   4 +
 include/hw/i386/pc.h  |   3 +
 include/hw/pci-host/spapr.h   |   2 +
 include/hw/ppc/spapr.h|  12 +-
 include/hw/ppc/spapr_nvdimm.h |   5 +-
 18 files changed, 568 insertions(+), 57 deletions(-)

-- 
2.26.2




Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200815151148.10571-1-rohit.shinde12...@gmail.com/



Hi,

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

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

  CC  qapi/qapi-types-transaction.o
  CC  qapi/qapi-builtin-visit.o
/tmp/qemu-test/src/qapi/opts-visitor.c: In function 'opts_next_list':
/tmp/qemu-test/src/qapi/opts-visitor.c:269:9: error: empty declaration [-Werror]
 __attribute__((fallthrough));
 ^
cc1: all warnings being treated as errors
make: *** [qapi/opts-visitor.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 709, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=cbaed9e0baf94ba9adfd067fc89d7df2', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-b0zxj7yg/src/docker-src.2020-08-15-12.10.41.4314:/var/tmp/qemu:z,ro',
 'qemu/centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=cbaed9e0baf94ba9adfd067fc89d7df2
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-b0zxj7yg/src'
make: *** [docker-run-test-quick@centos7] Error 2

real1m57.885s
user0m6.528s


The full log is available at
http://patchew.org/logs/20200815151148.10571-1-rohit.shinde12...@gmail.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Bug 1891748] [NEW] qemu-arm-static 5.1 can't run gcc

2020-08-15 Thread Ech
Public bug reported:

Issue discovered while trying to build pikvm (1)

Long story short: when using qemu-arm-static 5.1, gcc exits whith
message:

Allocating guest commpage: Operation not permitted


when using qemu-arm-static v5.0, gcc "works"

Steps to reproduce will follow

(1)  https://github.com/pikvm/pikvm/blob/master/pages/building_os.md

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  qemu-arm-static 5.1 can't run gcc

Status in QEMU:
  New

Bug description:
  Issue discovered while trying to build pikvm (1)

  Long story short: when using qemu-arm-static 5.1, gcc exits whith
  message:

  Allocating guest commpage: Operation not permitted

  
  when using qemu-arm-static v5.0, gcc "works"

  Steps to reproduce will follow

  (1)  https://github.com/pikvm/pikvm/blob/master/pages/building_os.md

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



[PATCH 19/20] target/arm: Convert integer multiply-add (indexed) to gvec for aa64 advsimd

2020-08-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h| 14 ++
 target/arm/translate-a64.c | 34 ++
 target/arm/vec_helper.c| 25 +
 3 files changed, 73 insertions(+)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index d0573a53c8..378bb1898b 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -762,6 +762,20 @@ DEF_HELPER_FLAGS_4(gvec_mul_idx_h, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_mul_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_mul_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_5(gvec_mla_idx_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_mla_idx_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_mla_idx_d, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(gvec_mls_idx_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_mls_idx_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d08960a1c8..c74c6e854c 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13523,6 +13523,40 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 return;
 }
 break;
+
+case 0x10: /* MLA */
+if (!is_long && !is_scalar) {
+static gen_helper_gvec_4 * const fns[3] = {
+gen_helper_gvec_mla_idx_h,
+gen_helper_gvec_mla_idx_s,
+gen_helper_gvec_mla_idx_d,
+};
+tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vec_full_reg_offset(s, rd),
+   is_q ? 16 : 8, vec_full_reg_size(s),
+   index, fns[size - 1]);
+return;
+}
+break;
+
+case 0x14: /* MLS */
+if (!is_long && !is_scalar) {
+static gen_helper_gvec_4 * const fns[3] = {
+gen_helper_gvec_mls_idx_h,
+gen_helper_gvec_mls_idx_s,
+gen_helper_gvec_mls_idx_d,
+};
+tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vec_full_reg_offset(s, rd),
+   is_q ? 16 : 8, vec_full_reg_size(s),
+   index, fns[size - 1]);
+return;
+}
+break;
 }
 
 if (size == 3) {
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
index aa1de36921..fb53684ce3 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/vec_helper.c
@@ -731,6 +731,31 @@ DO_MUL_IDX(gvec_mul_idx_d, uint64_t, )
 
 #undef DO_MUL_IDX
 
+#define DO_MLA_IDX(NAME, TYPE, OP, H) \
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc)   \
+{  \
+intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE);  \
+intptr_t idx = simd_data(desc);\
+TYPE *d = vd, *n = vn, *m = vm, *a = va;   \
+for (i = 0; i < oprsz / sizeof(TYPE); i += segment) {  \
+TYPE mm = m[H(i + idx)];   \
+for (j = 0; j < segment; j++) {\
+d[i + j] = a[i + j] OP n[i + j] * mm;  \
+}  \
+}  \
+clear_tail(d, oprsz, simd_maxsz(desc));\
+}
+
+DO_MLA_IDX(gvec_mla_idx_h, uint16_t, +, H2)
+DO_MLA_IDX(gvec_mla_idx_s, uint32_t, +, H4)
+DO_MLA_IDX(gvec_mla_idx_d, uint64_t, +,   )
+
+DO_MLA_IDX(gvec_mls_idx_h, uint16_t, -, H2)
+DO_MLA_IDX(gvec_mls_idx_s, uint32_t, -, H4)
+DO_MLA_IDX(gvec_mls_idx_d, uint64_t, -,   )
+
+#undef DO_MLA_IDX
+
 #define DO_FMUL_IDX(NAME, TYPE, H) \
 void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
 {  \
-- 
2.25.1




[PATCH 17/20] target/arm: Fix sve_punpk_p vs odd vector lengths

2020-08-15 Thread Richard Henderson
Wrote too much with punpk1 with vl % 512 != 0.

Reported-by: Laurent Desnogues 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index b8651ae173..c983cd4356 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -2104,11 +2104,11 @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t 
pred_desc)
 high = oprsz >> 1;
 }
 
-if ((high & 3) == 0) {
+if ((oprsz & 7) == 0) {
 uint32_t *n = vn;
 high >>= 2;
 
-for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
+for (i = 0; i < oprsz / 8; i++) {
 uint64_t nn = n[H4(high + i)];
 d[i] = expand_bits(nn, 0);
 }
-- 
2.25.1




[PATCH 10/10] specs/ppc-spapr-numa: update with new NUMA support

2020-08-15 Thread Daniel Henrique Barboza
This update provides more in depth information about the
choices and drawbacks of the new NUMA support for the
spapr machine.

Signed-off-by: Daniel Henrique Barboza 
---
 docs/specs/ppc-spapr-numa.rst | 213 ++
 1 file changed, 213 insertions(+)

diff --git a/docs/specs/ppc-spapr-numa.rst b/docs/specs/ppc-spapr-numa.rst
index e762038022..994bfb996f 100644
--- a/docs/specs/ppc-spapr-numa.rst
+++ b/docs/specs/ppc-spapr-numa.rst
@@ -189,3 +189,216 @@ QEMU up to 5.1, as follows:
 
 This also means that user input in QEMU command line does not change the
 NUMA distancing inside the guest for the pseries machine.
+
+New NUMA mechanics for pseries in QEMU 5.2
+==
+
+Starting in QEMU 5.2, the pseries machine now considers user input when
+setting NUMA topology of the guest. The following changes were made:
+
+* ibm,associativity-reference-points was changed to {0x4, 0x3, 0x2, 0x1}, 
allowing
+  for 4 distinct NUMA distance values based on the NUMA levels
+
+* ibm,max-associativity-domains was changed to support multiple associativity
+  domains in all NUMA levels. This is needed to ensure user flexibility
+
+* ibm,associativity for all resources now varies with user input
+
+These changes are only effective for pseries-5.2 and newer machines that are
+created with more than one NUMA node (disconsidering NUMA nodes created by
+the machine itself, e.g. NVLink 2 GPUs). The now legacy support has been
+around for such a long time, with users seeing NUMA distances 10 and 40
+(and 80 if using NVLink2 GPUs), and there is no need to disrupt the
+existing experience of those guests.
+
+To bring the user experience x86 users have when tuning up NUMA, we had
+to operate under the current pseries Linux kernel logic described in
+`How the pseries Linux guest calculates NUMA distances`_. The result
+is that we needed to translate NUMA distance user input to pseries
+Linux kernel input.
+
+Translating user distance to kernel distance
+
+
+User input for NUMA distance can vary from 10 to 254. We need to translate
+that to the values that the Linux kernel operates on (10, 20, 40, 80, 160).
+This is how it is being done:
+
+* user distance 11 to 30 will be interpreted as 20
+* user distance 31 to 60 will be interpreted as 40
+* user distance 61 to 120 will be interpreted as 80
+* user distance 121 and beyond will be interpreted as 160
+* user distance 10 stays 10
+
+The reasoning behind this aproximation is to avoid any round up to the local
+distance (10), keeping it exclusive to the 4th NUMA level (which is still
+exclusive to the node_id). All other ranges were chosen under the developer
+discretion of what would be (somewhat) sensible considering the user input.
+Any other strategy can be used here, but in the end the reality is that we'll
+have to accept that a large array of values will be translated to the same
+NUMA topology in the guest, e.g. this user input:
+
+::
+
+  0   1   2
+  0  10  31 120
+  1  31  10  30
+  2 120  30  10
+
+And this other user input:
+
+::
+
+  0   1   2
+  0  10  60  61
+  1  60  10  11
+  2  61  11  10
+
+Will both be translated to the same values internally:
+
+::
+
+  0   1   2
+  0  10  40  80
+  1  40  10  20
+  2  80  20  10
+
+Users are encouraged to use only the kernel values in the NUMA definition to
+avoid being taken by surprise with that the guest is actually seeing in the
+topology. There are enough potential surprises that are inherent to the
+associativity domain assignment process, discussed below.
+
+
+How associativity domains are assigned
+--
+
+LOPAPR allows more than one associativity array (or 'string') per allocated
+resource. This would be used to represent that the resource has multiple
+connections with the board, and then the operational system, when deciding
+NUMA distancing, should consider the associativity information that provides
+the shortest distance.
+
+The spapr implementation does not support multiple associativity arrays per
+resource, neither does the pseries Linux kernel. We'll have to represent the
+NUMA topology using one associativity per resource, which means that choices
+and compromises are going to be made.
+
+Consider the following NUMA topology entered by user input:
+
+::
+
+  0   1   2   3
+  0  10  20  20  40
+  1  20  10  80  40
+  2  20  80  10  20
+  3  40  40  20  10
+
+Honoring just the relative distances of node 0 to every other node, one 
possible
+value for all associativity arrays would be:
+
+* node 0: 0 B A 0
+* node 1: 0 0 A 1
+* node 2: 0 0 A 2
+* node 3: 0 B 0 3
+
+With the reference points {0x4, 0x3, 0x2, 0x1}, for node 0:
+
+* distance from 0 to 1 is 20 (no match at 0x4, will match at 0x3)
+* distance from 0 to 2 is 20 (no match at 0x4, will match at 0x3)
+* distance from 0 to 3 is 40 (no match at 0x4 and 0x3, will match
+  at 0x2)
+
+The distances related to node

[Bug 1891748] Re: qemu-arm-static 5.1 can't run gcc

2020-08-15 Thread Ech
Additional info,

error message text ( "Allocating guest commpage" ) found in this commit:


https://fossies.org/diffs/qemu/5.0.0_vs_5.1.0-rc0/linux-user/elfload.c-diff.html

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

Title:
  qemu-arm-static 5.1 can't run gcc

Status in QEMU:
  New

Bug description:
  Issue discovered while trying to build pikvm (1)

  Long story short: when using qemu-arm-static 5.1, gcc exits whith
  message:

  Allocating guest commpage: Operation not permitted

  
  when using qemu-arm-static v5.0, gcc "works"

  Steps to reproduce will follow

  (1)  https://github.com/pikvm/pikvm/blob/master/pages/building_os.md

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



[Bug 1891749] [NEW] CGA Mode 6 is only 100 pixels tall, when it's supposed to be 200

2020-08-15 Thread -
Public bug reported:

I have written a program that used CGA Mode 6 (640x200 black and white).
However qemu-system-i386 only displays the first 100 pixels, effectively
limiting the resolution of mode 6 to 640x100. When running the same
program on a real computer it uses the whole 640x200 pixels.

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: i386 linux-user

** Tags added: linux-user

** Tags removed: li

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

Title:
  CGA Mode 6 is only 100 pixels tall, when it's supposed to be 200

Status in QEMU:
  New

Bug description:
  I have written a program that used CGA Mode 6 (640x200 black and
  white). However qemu-system-i386 only displays the first 100 pixels,
  effectively limiting the resolution of mode 6 to 640x100. When running
  the same program on a real computer it uses the whole 640x200 pixels.

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



[PATCH 08/20] target/arm: Split out gen_gvec_ool_zzzp

2020-08-15 Thread Richard Henderson
Model after gen_gvec_fn_zzz et al.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index aa7ed070e3..535d086838 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -142,8 +142,19 @@ static int pred_gvec_reg_size(DisasContext *s)
 return size_for_gvec(pred_full_reg_size(s));
 }
 
-/* Invoke a vector expander on two Zregs.  */
+/* Invoke an out-of-line helper on 3 Zregs and a predicate. */
+static void gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
+  int rd, int rn, int rm, int pg, int data)
+{
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   pred_full_reg_offset(s, pg),
+   vsz, vsz, data, fn);
+}
 
+/* Invoke a vector expander on two Zregs.  */
 static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn *gvec_fn,
int esz, int rd, int rn)
 {
@@ -314,16 +325,11 @@ static bool trans_UQSUB_zzz(DisasContext *s, arg_rrr_esz 
*a)
 
 static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 
*fn)
 {
-unsigned vsz = vec_full_reg_size(s);
 if (fn == NULL) {
 return false;
 }
 if (sve_access_check(s)) {
-tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   pred_full_reg_offset(s, a->pg),
-   vsz, vsz, 0, fn);
+gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0);
 }
 return true;
 }
@@ -337,12 +343,7 @@ static void do_sel_z(DisasContext *s, int rd, int rn, int 
rm, int pg, int esz)
 gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
 gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
 };
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
-   vec_full_reg_offset(s, rn),
-   vec_full_reg_offset(s, rm),
-   pred_full_reg_offset(s, pg),
-   vsz, vsz, 0, fns[esz]);
+gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0);
 }
 
 #define DO_ZPZZ(NAME, name) \
@@ -2704,12 +2705,8 @@ static bool trans_RBIT(DisasContext *s, arg_rpr_esz *a)
 static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a)
 {
 if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   pred_full_reg_offset(s, a->pg),
-   vsz, vsz, a->esz, gen_helper_sve_splice);
+gen_gvec_ool_zzzp(s, gen_helper_sve_splice,
+  a->rd, a->rn, a->rm, a->pg, 0);
 }
 return true;
 }
-- 
2.25.1




[Bug 1891748] Re: qemu-arm-static 5.1 can't run gcc

2020-08-15 Thread Ech
Steps to reproduce

1. Download and extract attached tarball.

$ make # will build the docker container

$ make run # will enter the container

# once in the container, run

# /qemu-arm-static-50 /bin/bash /runme.sh



** Attachment added: "qemu-1891748-1.tgz"
   
https://bugs.launchpad.net/qemu/+bug/1891748/+attachment/5401727/+files/qemu-1891748-1.tgz

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

Title:
  qemu-arm-static 5.1 can't run gcc

Status in QEMU:
  New

Bug description:
  Issue discovered while trying to build pikvm (1)

  Long story short: when using qemu-arm-static 5.1, gcc exits whith
  message:

  Allocating guest commpage: Operation not permitted

  
  when using qemu-arm-static v5.0, gcc "works"

  Steps to reproduce will follow

  (1)  https://github.com/pikvm/pikvm/blob/master/pages/building_os.md

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



[PATCH 06/10] spapr: allow 4 NUMA levels in ibm, associativity-reference-points

2020-08-15 Thread Daniel Henrique Barboza
The value of ibm,associativity-reference-points is in sync with
what Skiboot does. It's a three level NUMA configuration where
the first two levels references the same associativity index
(0x4), meaning that the next distance after the local_distance
(10) is two orders away (a '40' value in the Linux kernel). The
third level (0x2) was added to allow NVLink GPUs to be placed
outside of the same associativity domain of the regular
NUMA nodes. However, we have to deal with the possibility of
user customization of the NUMA distances, something that
Skiboot doesn't need to, and this current scheme is too
tight.

The next step to give users more flexibility is to define 4
distinct NUMA levels, allowing for 5 discrete values of
distances (10, 20, 40, 80 and 160 as seen by the kernel).

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b0c4b80a23..bc51d2db90 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -906,8 +906,9 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void 
*fdt)
 GString *qemu_hypertas = g_string_sized_new(256);
 uint32_t refpoints[] = {
 cpu_to_be32(0x4),
-cpu_to_be32(0x4),
+cpu_to_be32(0x3),
 cpu_to_be32(0x2),
+cpu_to_be32(0x1),
 };
 uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
 uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
@@ -970,6 +971,10 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void 
*fdt)
 g_string_free(qemu_hypertas, TRUE);
 
 if (spapr_machine_using_legacy_numa(spapr)) {
+refpoints[1] = cpu_to_be32(0x4);
+refpoints[2] = cpu_to_be32(0x2);
+nr_refpoints = 3;
+
 maxdomain = cpu_to_be32(spapr->extra_numa_nodes > 1 ? 1 : 0);
 maxdomains[1] = maxdomain;
 maxdomains[2] = maxdomain;
-- 
2.26.2




Re: [PATCH 08/18] hw/sd: sd: Correctly set the high capacity bit

2020-08-15 Thread Philippe Mathieu-Daudé
On 8/14/20 6:40 PM, Bin Meng wrote:
> From: Bin Meng 
> 
> Per the SD spec, Standard Capacity SD Memory Card (SDSC) supports
> capacity up to and including 2 GiB.
> 

Fixes: 2d7adea4fe ("hw/sd: Support SDHC size cards")

> Signed-off-by: Bin Meng 
> ---
> 
>  hw/sd/sd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 51f5900..5e7fc3f 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -313,7 +313,7 @@ static void sd_ocr_powerup(void *opaque)
>  /* card power-up OK */
>  sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
>  
> -if (sd->size > 1 * GiB) {
> +if (sd->size > 2 * GiB) {

But you need to fix sd_set_csd() too, else this is incomplete.

Thanks,

Phil.

>  sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
>  }
>  }
> 




Re: [PATCH v1 0/1] COLO: migrate dirty ram pages before colo checkpoint

2020-08-15 Thread Derek Su
On Sat, Aug 15, 2020 at 9:42 AM Zhanghailiang
 wrote:
>
> > -Original Message-
> > From: Derek Su [mailto:jwsu1...@gmail.com]
> > Sent: Thursday, August 13, 2020 6:28 PM
> > To: Lukas Straub 
> > Cc: Derek Su ; qemu-devel@nongnu.org; Zhanghailiang
> > ; chy...@qnap.com; quint...@redhat.com;
> > dgilb...@redhat.com; ctch...@qnap.com
> > Subject: Re: [PATCH v1 0/1] COLO: migrate dirty ram pages before colo
> > checkpoint
> >
> > On Fri, Jul 31, 2020 at 3:52 PM Lukas Straub  wrote:
> > >
> > > On Sun, 21 Jun 2020 10:10:03 +0800
> > > Derek Su  wrote:
> > >
> > > > This series is to reduce the guest's downtime during colo checkpoint
> > > > by migrating dirty ram pages as many as possible before colo checkpoint.
> > > >
> > > > If the iteration count reaches COLO_RAM_MIGRATE_ITERATION_MAX or ram
> > > > pending size is lower than 'x-colo-migrate-ram-threshold', stop the
> > > > ram migration and do colo checkpoint.
> > > >
> > > > Test environment:
> > > > The both primary VM and secondary VM has 1GiB ram and 10GbE NIC for
> > > > FT traffic.
> > > > One fio buffer write job runs on the guest.
> > > > The result shows the total primary VM downtime is decreased by ~40%.
> > > >
> > > > Please help to review it and suggestions are welcomed.
> > > > Thanks.
> > >
> > > Hello Derek,
> > > Sorry for the late reply.
> > > I think this is not a good idea, because it unnecessarily introduces a 
> > > delay
> > between checkpoint request and the checkpoint itself and thus impairs 
> > network
> > bound workloads due to increased network latency. Workloads that are
> > independent from network don't cause many checkpoints anyway, so it doesn't
> > help there either.
> > >
> >
>
> Hi Derek,
>
> Actually, There is a quit interesting question we should think:
> What will happen if VM continues to run after detected a mismatched state 
> between PVM and SVM,
> According to the rules of COLO, we should stop VMs immediately to sync the 
> state between PVM and SVM,
> But here, you choose them to continue to run for a while, then there may be 
> more client's network packages
> Coming, and may cause more memory pages dirty, another side effect is the new 
> network packages will not
> Be sent out with high probability, because their replies should be different 
> since the state between PVM and SVM is different.
>
> So, IMHO, it makes non-sense to let VMs to continue to run after detected 
> them in different state.
> Besides, I don't think it is easy to construct this case in tests.
>
>
> Thanks,
> Hailiang
>

Hello, Hailiang

Thanks. I got your point.
In my tests, the mismatch between packets does not happen, so the
network latency does not increase.

By the way, I've tried your commit addressing this issue.
It is useful for low dirty memory and low dirty rate workload.

But in high "buffered IO read/write" workload, it results in PVM
resends massive and same dirty ram pages  every cycle triggered
by DEFAULT_RAM_PENDING_CHECK (default 1 second) timer, so hurt the IO
performance and without improvement of downtime?
Do you have any thoughts about this?

Is it possible to separate the checkpoint invoked by the periodic
timer and the packet mismatch and to use a different strategy
to cope with the long downtime issue?

Thanks.

Regards,
Derek

> s> Hello, Lukas & Zhanghailiang
> >
> > Thanks for your opinions.
> > I went through my patch, and I feel a little confused and would like to dig 
> > into it
> > more.
> >
> > In this patch, colo_migrate_ram_before_checkpoint() is before
> > COLO_MESSAGE_CHECKPOINT_REQUEST, so the SVM and PVM should not enter
> > the pause state.
> >
> > In the meanwhile, the packets to PVM/SVM can still be compared and notify
> > inconsistency if mismatched, right?
> > Is it possible to introduce extra network latency?
> >
> > In my test (randwrite to disk by fio with direct=0), the ping from another 
> > client to
> > the PVM  using generic colo and colo used this patch are below.
> > The network latency does not increase as my expectation.
> >
> > generic colo
> > ```
> > 64 bytes from 192.168.80.18: icmp_seq=87 ttl=64 time=28.109 ms
> > 64 bytes from 192.168.80.18: icmp_seq=88 ttl=64 time=16.747 ms
> > 64 bytes from 192.168.80.18: icmp_seq=89 ttl=64 time=2388.779 ms
> >  > 64 bytes from 192.168.80.18: icmp_seq=90 ttl=64 time=1385.792 ms
> > 64 bytes from 192.168.80.18: icmp_seq=91 ttl=64 time=384.896 ms
> >  > 64 bytes from 192.168.80.18: icmp_seq=92 ttl=64 time=3.895 ms
> > 64 bytes from 192.168.80.18: icmp_seq=93 ttl=64 time=1.020 ms
> > 64 bytes from 192.168.80.18: icmp_seq=94 ttl=64 time=0.865 ms
> > 64 bytes from 192.168.80.18: icmp_seq=95 ttl=64 time=0.854 ms
> > 64 bytes from 192.168.80.18: icmp_seq=96 ttl=64 time=28.359 ms
> > 64 bytes from 192.168.80.18: icmp_seq=97 ttl=64 time=12.309 ms
> > 64 bytes from 192.168.80.18: icmp_seq=98 ttl=64 time=0.870 ms
> > 64 bytes from 192.168.80.18: icmp_seq=99 ttl=64 time=2371.733 ms
> > 64 bytes from 1

Re: [RFC v3 26/71] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns

2020-08-15 Thread Frank Chang
On Sat, Aug 15, 2020 at 2:36 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 8/13/20 7:48 PM, Frank Chang wrote:
> > esz is passed from e.g. GEN_VEXT_LD_STRIDE() macro:
> >
> >> #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
> >> void HELPER(NAME)(void *vd, void * v0, target_ulong base,  \
> >>   target_ulong stride, CPURISCVState *env, \
> >>   uint32_t desc)   \
> >> {  \
> >> uint32_t vm = vext_vm(desc);   \
> >> vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \
> >>  sizeof(ETYPE), GETPC(), MMU_DATA_LOAD);   \
> >> }
> >>
> >> GEN_VEXT_LD_STRIDE(vlse8_v,  int8_t,  lde_b)
> >
> > which is calculated by sizeof(ETYPE), so the results would be: 1, 2, 4,
> 8.
> > and vext_max_elems() is called by e.g. vext_ldst_stride():
>
> Ah, yes.
>
> >> uint32_t max_elems = vext_max_elems(desc, esz);
> >
> > I can add another parameter to the macro and pass the hard-coded
> log2(esz) number
> > if it's the better way instead of using ctzl().
> > Or if there's another approach to get the log2(esz) number more
> elegantly?
>
> Using ctzl(sizeof(type)) in the GEN_VEXT_LD_STRIDE macro will work well.
> This
> will be constant folded by the compiler.
>
>
> r~
>

Checked the codes again,
GEN_VEXT_LD_STRIDE() will eventually call vext_ldst_stride() and pass esz
as the parameter.
However, esz is not only used in vext_max_elems() but also used for other
calculation, e.g.:

probe_pages(env, base + stride * i, nf * esz, ra, access_type);
and
target_ulong addr = base + stride * i + k * esz;

If we pass ctzl(sizeof(type)) in GEN_VEXT_LD_STRIDE(),
I would still have to do: (1 << esz) to get the correct element size in the
above calculations.
Would it eliminate the performance gain we have in vext_max_elems() instead?

Frank Chang


Re: [PATCH v5 11/14] hvf: remove hvf specific functions from global includes

2020-08-15 Thread Richard Henderson
On 8/12/20 11:32 AM, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
>  accel/stubs/Makefile.objs  |  1 -
>  accel/stubs/hvf-stub.c | 30 --
>  include/sysemu/hvf.h   |  8 
>  target/i386/hvf/hvf-cpus.h |  8 
>  target/i386/hvf/x86hvf.c   |  2 ++
>  target/i386/hvf/x86hvf.h   |  1 -
>  6 files changed, 10 insertions(+), 40 deletions(-)
>  delete mode 100644 accel/stubs/hvf-stub.c

Reviewed-by: Richard Henderson 


r~



[PATCH 04/10] spapr: add spapr_machine_using_legacy_numa() helper

2020-08-15 Thread Daniel Henrique Barboza
The changes to come to NUMA support are all guest visible. In
theory we could just create a new 5_1 class option flag to
avoid the changes to cascade to 5.1 and under. The reality is that
these changes are only relevant if the machine has more than one
NUMA node. There is no need to change guest behavior that has
been around for years needlesly.

This new helper will be used by the next patches to determine
whether we should retain the (soon to be) legacy NUMA behavior
in the pSeries machine. The new behavior will only be exposed
if::

- machine is pseries-5.2 and newer;
- more than one NUMA node is declared in NUMA state.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 12 
 include/hw/ppc/spapr.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 22e78cfc84..073a59c47d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -308,6 +308,15 @@ static hwaddr spapr_node0_size(MachineState *machine)
 return machine->ram_size;
 }
 
+bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr)
+{
+MachineState *machine = MACHINE(spapr);
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+
+return smc->pre_5_2_numa_associativity ||
+   machine->numa_state->num_nodes <= 1;
+}
+
 static void add_str(GString *s, const gchar *s1)
 {
 g_string_append_len(s, s1, strlen(s1) + 1);
@@ -4602,8 +4611,11 @@ DEFINE_SPAPR_MACHINE(5_2, "5.2", true);
  */
 static void spapr_machine_5_1_class_options(MachineClass *mc)
 {
+SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
 spapr_machine_5_2_class_options(mc);
 compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
+smc->pre_5_2_numa_associativity = true;
 }
 
 DEFINE_SPAPR_MACHINE(5_1, "5.1", false);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 739a6a4942..d9f1afa8b2 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -130,6 +130,7 @@ struct SpaprMachineClass {
 bool smp_threads_vsmt; /* set VSMT to smp_threads by default */
 hwaddr rma_limit;  /* clamp the RMA to this size */
 bool pre_5_1_assoc_refpoints;
+bool pre_5_2_numa_associativity;
 
 void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
   uint64_t *buid, hwaddr *pio, 
@@ -847,6 +848,7 @@ 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);
+bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr);
 
 /* DRC callbacks. */
 void spapr_core_release(DeviceState *dev);
-- 
2.26.2




[PATCH 07/10] spapr: create helper to set ibm,associativity

2020-08-15 Thread Daniel Henrique Barboza
We have several places around hw/ppc files where we use the
same code to set the ibm,associativity array. This patch
creates a helper called spapr_set_associativity() to do
that in a single place. It'll also make it saner to change
the value of ibm,associativity in the next patches.

After this patch, only 2 places are left with open code
ibm,associativity assignment:

- spapr_dt_dynamic_reconfiguration_memory()
- h_home_node_associativity() in spapr_hcall.c

The update of associativity values will be made in these places
manually later on.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 32 +---
 hw/ppc/spapr_nvdimm.c  |  8 +++-
 hw/ppc/spapr_pci.c |  8 +++-
 include/hw/ppc/spapr.h |  1 +
 4 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index bc51d2db90..b80a6f6936 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -201,15 +201,27 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, 
PowerPCCPU *cpu,
 return ret;
 }
 
+void spapr_set_associativity(uint32_t *assoc, int node_id, int cpu_index)
+{
+uint8_t assoc_size = 0x4;
+
+if (cpu_index >= 0) {
+assoc_size = 0x5;
+assoc[5] = cpu_to_be32(cpu_index);
+}
+
+assoc[0] = cpu_to_be32(assoc_size);
+assoc[1] = cpu_to_be32(0x0);
+assoc[2] = cpu_to_be32(0x0);
+assoc[3] = cpu_to_be32(0x0);
+assoc[4] = cpu_to_be32(node_id);
+}
+
 static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
 {
 int index = spapr_get_vcpu_id(cpu);
-uint32_t associativity[] = {cpu_to_be32(0x5),
-cpu_to_be32(0x0),
-cpu_to_be32(0x0),
-cpu_to_be32(0x0),
-cpu_to_be32(cpu->node_id),
-cpu_to_be32(index)};
+uint32_t associativity[6];
+spapr_set_associativity(associativity, cpu->node_id, index);
 
 /* Advertise NUMA via ibm,associativity */
 return fdt_setprop(fdt, offset, "ibm,associativity", associativity,
@@ -325,15 +337,13 @@ static void add_str(GString *s, const gchar *s1)
 static int spapr_dt_memory_node(void *fdt, int nodeid, hwaddr start,
 hwaddr size)
 {
-uint32_t associativity[] = {
-cpu_to_be32(0x4), /* length */
-cpu_to_be32(0x0), cpu_to_be32(0x0),
-cpu_to_be32(0x0), cpu_to_be32(nodeid)
-};
+uint32_t associativity[5];
 char mem_name[32];
 uint64_t mem_reg_property[2];
 int off;
 
+spapr_set_associativity(associativity, nodeid, -1);
+
 mem_reg_property[0] = cpu_to_be64(start);
 mem_reg_property[1] = cpu_to_be64(size);
 
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 81410aa63f..bd109bfc00 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -115,15 +115,13 @@ int spapr_dt_nvdimm(void *fdt, int parent_offset,
  &error_abort);
 uint64_t slot = object_property_get_uint(OBJECT(nvdimm), PC_DIMM_SLOT_PROP,
  &error_abort);
-uint32_t associativity[] = {
-cpu_to_be32(0x4), /* length */
-cpu_to_be32(0x0), cpu_to_be32(0x0),
-cpu_to_be32(0x0), cpu_to_be32(node)
-};
+uint32_t associativity[5];
 uint64_t lsize = nvdimm->label_size;
 uint64_t size = object_property_get_int(OBJECT(nvdimm), PC_DIMM_SIZE_PROP,
 NULL);
 
+spapr_set_associativity(associativity, node, -1);
+
 drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PMEM, slot);
 g_assert(drc);
 
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 09ac58fd7f..c02ace226c 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2321,11 +2321,8 @@ int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState 
*phb,
 cpu_to_be32(1),
 cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
 };
-uint32_t associativity[] = {cpu_to_be32(0x4),
-cpu_to_be32(0x0),
-cpu_to_be32(0x0),
-cpu_to_be32(0x0),
-cpu_to_be32(phb->numa_node)};
+uint32_t associativity[5];
+
 SpaprTceTable *tcet;
 SpaprDrc *drc;
 Error *err = NULL;
@@ -2358,6 +2355,7 @@ int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState 
*phb,
 
 /* Advertise NUMA via ibm,associativity */
 if (phb->numa_node != -1) {
+spapr_set_associativity(associativity, phb->numa_node, -1);
 _FDT(fdt_setprop(fdt, bus_off, "ibm,associativity", associativity,
  sizeof(associativity)));
 }
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d9f1afa8b2..cd158bf95a 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -863,6 +863,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState 
*spapr,
 
 void spapr_rtc_r

Re: [PATCH 7/7] hw/scsi/scsi-disk: Replace magic '512' value by BDRV_SECTOR_SIZE

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:34写道:
>
> Use self-explicit definitions instead of magic '512' value.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  hw/scsi/scsi-disk.c | 44 +++-
>  1 file changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index 8ce68a9dd6..7612035a4e 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -71,7 +71,7 @@ typedef struct SCSIDiskClass {
>
>  typedef struct SCSIDiskReq {
>  SCSIRequest req;
> -/* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
> +/* Both sector and sector_count are in terms of BDRV_SECTOR_SIZE bytes.  
> */
>  uint64_t sector;
>  uint32_t sector_count;
>  uint32_t buflen;
> @@ -141,7 +141,7 @@ static void scsi_init_iovec(SCSIDiskReq *r, size_t size)
>  r->buflen = size;
>  r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
>  }
> -r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
> +r->iov.iov_len = MIN(r->sector_count * BDRV_SECTOR_SIZE, r->buflen);
>  qemu_iovec_init_external(&r->qiov, &r->iov, 1);
>  }
>
> @@ -311,7 +311,7 @@ static void scsi_read_complete_noio(SCSIDiskReq *r, int 
> ret)
>  goto done;
>  }
>
> -n = r->qiov.size / 512;
> +n = r->qiov.size / BDRV_SECTOR_SIZE;
>  r->sector += n;
>  r->sector_count -= n;
>  scsi_req_data(&r->req, r->qiov.size);
> @@ -505,7 +505,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int 
> ret)
>  goto done;
>  }
>
> -n = r->qiov.size / 512;
> +n = r->qiov.size / BDRV_SECTOR_SIZE;
>  r->sector += n;
>  r->sector_count -= n;
>  if (r->sector_count == 0) {
> @@ -1284,7 +1284,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, 
> uint8_t *outbuf)
>  } else { /* MODE_SENSE_10 */
>  outbuf[7] = 8; /* Block descriptor length  */
>  }
> -nb_sectors /= (s->qdev.blocksize / 512);
> +nb_sectors /= (s->qdev.blocksize / BDRV_SECTOR_SIZE);
>  if (nb_sectors > 0xff) {
>  nb_sectors = 0;
>  }
> @@ -1342,7 +1342,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, 
> uint8_t *outbuf)
>  start_track = req->cmd.buf[6];
>  blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
>  trace_scsi_disk_emulate_read_toc(start_track, format, msf >> 1);
> -nb_sectors /= s->qdev.blocksize / 512;
> +nb_sectors /= s->qdev.blocksize / BDRV_SECTOR_SIZE;
>  switch (format) {
>  case 0:
>  toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
> @@ -1738,9 +1738,10 @@ static void scsi_write_same_complete(void *opaque, int 
> ret)
>
>  block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
>
> -data->nb_sectors -= data->iov.iov_len / 512;
> -data->sector += data->iov.iov_len / 512;
> -data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len);
> +data->nb_sectors -= data->iov.iov_len / BDRV_SECTOR_SIZE;
> +data->sector += data->iov.iov_len / BDRV_SECTOR_SIZE;
> +data->iov.iov_len = MIN(data->nb_sectors * BDRV_SECTOR_SIZE,
> +data->iov.iov_len);
>  if (data->iov.iov_len) {
>  block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
>   data->iov.iov_len, BLOCK_ACCT_WRITE);
> @@ -1805,9 +1806,10 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq 
> *r, uint8_t *inbuf)
>
>  data = g_new0(WriteSameCBData, 1);
>  data->r = r;
> -data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
> -data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);
> -data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);
> +data->sector = r->req.cmd.lba * (s->qdev.blocksize / BDRV_SECTOR_SIZE);
> +data->nb_sectors = nb_sectors * (s->qdev.blocksize / BDRV_SECTOR_SIZE);
> +data->iov.iov_len = MIN(data->nb_sectors * BDRV_SECTOR_SIZE,
> +SCSI_WRITE_SAME_MAX);
>  data->iov.iov_base = buf = blk_blockalign(s->qdev.conf.blk,
>data->iov.iov_len);
>  qemu_iovec_init_external(&data->qiov, &data->iov, 1);
> @@ -1980,7 +1982,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest 
> *req, uint8_t *buf)
>  if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
>  goto illegal_request;
>  }
> -nb_sectors /= s->qdev.blocksize / 512;
> +nb_sectors /= s->qdev.blocksize / BDRV_SECTOR_SIZE;
>  /* Returned value is the address of the last sector.  */
>  nb_sectors--;
>  /* Remember the new size for read/write sanity checking. */
> @@ -2049,7 +2051,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest 
> *req, uint8_t *buf)
>  if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
>  goto illegal_request;
>  }
> -  

[PATCH 03/10] spapr: robustify NVLink2 NUMA node logic

2020-08-15 Thread Daniel Henrique Barboza
NVLink2 GPUs are allocated in their own NUMA node, at maximum
distance from every other resource in the board. The existing
logic makes some assumptions that don't scale well:

- only NVLink2 GPUs will ever require such mechanism, meaning
that the GPU logic is tightly coupled with the NUMA setup of
the machine, via how ibm,max-associativity-domains is set.

- the code is relying on the lack of support for sparse NUMA
nodes in QEMU. Eventually this support can be implemented, and
then the assumption that spapr->gpu_numa_id represents the total
of NUMA nodes plus all generated NUMA ids for the GPUs, which
relies on all QEMU NUMA nodes not being sparsed, has a good
potential for disaster.

This patch aims to fix both assumptions by creating a generic
mechanism to get an available NUMA node, regardless of the
NUMA setup being sparse or not. The idea is to rename the existing
spapr->gpu_numa_id to spapr->current_numa_id and add a new
spapr->extra_numa_nodes attribute. They are used in a new function
called spapr_pci_get_available_numa_id(), that takes into account
that the NUMA conf can be sparsed or not, to retrieve an available
NUMA id for the caller. Each consecutive call of
spapr_pci_get_available_numa_id() will generate a new ID, up
to the limit of numa_state->num_nodes + spapr->extra_numa_nodes
exceeding MAX_NODES. This is a generic code being used only by
NVLink2 ATM, being available to be used in the future by any
other device.

With this new function in place, we can decouple
ibm,max-associativity-domains logic from NVLink2 logic by
using the new spapr->extra_numa_nodes to define the maxdomains
of the forth NUMA level. Instead of defining it as gpu_numa_id,
use num_nodes + extra_numa_nodes. This also makes it resilient
to any future change in the support of sparse NUMA nodes.

Despite all the code juggling, no functional change was made
because sparse NUMA nodes isn't a thing and we do not support
distinct NUMA distances via user input. Next patches will
change that.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c  | 15 ++-
 hw/ppc/spapr_pci.c  | 33 +
 hw/ppc/spapr_pci_nvlink2.c  | 10 ++
 include/hw/pci-host/spapr.h |  2 ++
 include/hw/ppc/spapr.h  |  4 +++-
 5 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3b16edaf4c..22e78cfc84 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -910,13 +910,13 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void 
*fdt)
 cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE & 0x),
 cpu_to_be32(ms->smp.max_cpus / ms->smp.threads),
 };
-uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
+uint32_t maxdomain = cpu_to_be32(spapr->extra_numa_nodes > 1 ? 1 : 0);
 uint32_t maxdomains[] = {
 cpu_to_be32(4),
 maxdomain,
 maxdomain,
 maxdomain,
-cpu_to_be32(spapr->gpu_numa_id),
+cpu_to_be32(ms->numa_state->num_nodes + spapr->extra_numa_nodes),
 };
 
 _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
@@ -2824,13 +2824,18 @@ static void spapr_machine_init(MachineState *machine)
 /*
  * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
  * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
- * called from vPHB reset handler so we initialize the counter here.
+ * called from vPHB reset handler. We have code to generate an extra numa
+ * id to place the GPU via 'extra_numa_nodes' and 'current_numa_node', 
which
+ * are initialized here.
+ *
  * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
  * must be equally distant from any other node.
- * The final value of spapr->gpu_numa_id is going to be written to
+ *
+ * The extra NUMA node ids generated for GPU usage will be written to
  * max-associativity-domains in spapr_build_fdt().
  */
-spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
+spapr->current_numa_id = 0;
+spapr->extra_numa_nodes = 0;
 
 if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) &&
 ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 0a418f1e67..09ac58fd7f 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2492,3 +2492,36 @@ void spapr_pci_switch_vga(bool big_endian)
&big_endian);
 }
 }
+
+unsigned spapr_pci_get_available_numa_id(Error **errp)
+{
+MachineState *machine = MACHINE(qdev_get_machine());
+SpaprMachineState *spapr = SPAPR_MACHINE(machine);
+NodeInfo *numa_info = machine->numa_state->nodes;
+unsigned i, start;
+
+if (machine->numa_state->num_nodes + spapr->extra_numa_nodes >= MAX_NODES) 
{
+error_setg(errp,
+   "Unable to get an extra NUMA node beyond MAX_NODES = %d",
+   MAX_NODES);
+ 

Re: [PATCH 11/18] hw/riscv: microchip_pfsoc: Connect a Cadence SDHCI controller and an SD card

2020-08-15 Thread Philippe Mathieu-Daudé
On 8/14/20 6:40 PM, Bin Meng wrote:
> From: Bin Meng 
> 
> Microchip PolarFire SoC integrates one Cadence SDHCI controller.
> On the Icicle Kit board, one eMMC chip and an external SD card
> connect to this controller depending on different configuration.
> 
> As QEMU does not support eMMC yet, we just emulate the SD card
> configuration. To test this, the Hart Software Services (HSS)
> should choose the SD card configuration:
> 
> $ cp boards/icicle-kit-es/def_config.sdcard .config
> $ make BOARD=icicle-kit-es
> 
> The SD card image can be built from the Yocto BSP at:
> https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp
> 
> Note the generated SD card image should be resized before use:
> $ qemu-img resize /path/to/sdcard.img 4G
> 
> Launch QEMU with the following command:
> $ qemu-system-riscv64 -nographic -M microchip-icicle-kit -sd sdcard.img
> 
> Signed-off-by: Bin Meng 
> ---
> 
>  hw/riscv/Kconfig   |  1 +
>  hw/riscv/microchip_pfsoc.c | 26 ++
>  include/hw/riscv/microchip_pfsoc.h |  4 
>  3 files changed, 31 insertions(+)
> 
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index ceb7c16..7412db9 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -55,3 +55,4 @@ config MICROCHIP_PFSOC
>  select SIFIVE
>  select UNIMP
>  select MCHP_PFSOC_MMUART
> +select CADENCE_SDHCI
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index f6b375c..7c09078 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -12,6 +12,7 @@
>   * 1) PLIC (Platform Level Interrupt Controller)
>   * 2) eNVM (Embedded Non-Volatile Memory)
>   * 3) MMUARTs (Multi-Mode UART)
> + * 4) Cadence eMMC/SDHC controller and an SD card connected to it
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -75,6 +76,7 @@ static const struct MemmapEntry {
>  [MICROCHIP_PFSOC_MMUART0] = { 0x2000, 0x1000 },
>  [MICROCHIP_PFSOC_SYSREG] =  { 0x20002000, 0x2000 },
>  [MICROCHIP_PFSOC_MPUCFG] =  { 0x20005000, 0x1000 },
> +[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
>  [MICROCHIP_PFSOC_MMUART1] = { 0x2010, 0x1000 },
>  [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
>  [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
> @@ -111,6 +113,11 @@ static void microchip_pfsoc_soc_instance_init(Object 
> *obj)
>  qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type",
>   TYPE_RISCV_CPU_SIFIVE_U54);
>  qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", RESET_VECTOR);
> +
> +object_initialize_child(obj, "sd-controller", &s->sdhci,
> +TYPE_CADENCE_SDHCI);
> +object_initialize_child(OBJECT(&s->sdhci), "sd-controller.sdhci",
> +&s->sdhci.slot, TYPE_SYSBUS_SDHCI);

OK now I see this patch, so NAck. TYPE_SYSBUS_SDHCI has to be
initialized in TYPE_CADENCE_SDHCI, not in all TYPE_CADENCE_SDHCI
users.

>  }
>  
>  static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
> @@ -223,6 +230,13 @@ static void microchip_pfsoc_soc_realize(DeviceState 
> *dev, Error **errp)
>  memmap[MICROCHIP_PFSOC_MPUCFG].base,
>  memmap[MICROCHIP_PFSOC_MPUCFG].size);
>  
> +/* SDHCI */

Consider setting the SDHCI DMA MR here.

> +sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp);
> +sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
> +memmap[MICROCHIP_PFSOC_EMMC_SD].base);
> +sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci.slot), 0,
> +qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_EMMC_SD_IRQ));
> +
>  /* MMUARTs */
>  s->serial0 = mchp_pfsoc_mmuart_create(system_memory,
>  memmap[MICROCHIP_PFSOC_MMUART0].base,
> @@ -290,6 +304,7 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(machine);
>  MemoryRegion *system_memory = get_system_memory();
>  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> +DriveInfo *dinfo = drive_get_next(IF_SD);
>  
>  /* Sanity check on RAM size */
>  if (machine->ram_size < mc->default_ram_size) {
> @@ -312,6 +327,17 @@ static void 
> microchip_icicle_kit_machine_init(MachineState *machine)
>  
>  /* Load the firmware */
>  riscv_find_and_load_firmware(machine, BIOS_FILENAME, RESET_VECTOR, NULL);
> +
> +/* Attach an SD card */
> +if (dinfo) {
> +SDHCIState *sdhci = &(s->soc.sdhci.slot);

NAck again, you are not supposed to access this field here.
This is why in the previous patch I asked why the "sd-bus" property
was not propagated from child to parent.

Thanks,

Phil.

> +DeviceState *card = qdev_new(TYPE_SD_CARD);
> +BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
> +
> +   

Re: [PATCH 5/7] hw/ide/atapi: Replace magic '512' value by BDRV_SECTOR_SIZE

2020-08-15 Thread Li Qiang
Philippe Mathieu-Daudé  于2020年8月14日周五 下午4:30写道:
>
> Use self-explicit definitions instead of magic '512' value.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Li Qiang 

> ---
>  hw/ide/atapi.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
> index 17a9d635d8..14a2b0bb2f 100644
> --- a/hw/ide/atapi.c
> +++ b/hw/ide/atapi.c
> @@ -824,9 +824,9 @@ static void cmd_get_configuration(IDEState *s, uint8_t 
> *buf)
>   *
>   *  Only a problem if the feature/profiles grow.
>   */
> -if (max_len > 512) {
> +if (max_len > BDRV_SECTOR_SIZE) {
>  /* XXX: assume 1 sector */
> -max_len = 512;
> +max_len = BDRV_SECTOR_SIZE;
>  }
>
>  memset(buf, 0, max_len);
> @@ -1186,8 +1186,8 @@ static void cmd_read_dvd_structure(IDEState *s, 
> uint8_t* buf)
>  }
>  }
>
> -memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
> -   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
> +memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * BDRV_SECTOR_SIZE + 4 ?
> +   IDE_DMA_BUF_SECTORS * BDRV_SECTOR_SIZE + 4 : max_len);
>
>  switch (format) {
>  case 0x00 ... 0x7f:
> --
> 2.21.3
>
>



[PATCH 07/20] target/arm: Use tcg_gen_gvec_bitsel for trans_SEL_pppp

2020-08-15 Thread Richard Henderson
The gvec operation was added after the initial implementation
of the SEL instruction and was missed in the conversion.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 31 ---
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 13a0194d59..aa7ed070e3 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1188,34 +1188,19 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s 
*a)
 return do__flags(s, a, &op);
 }
 
-static void gen_sel_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
-{
-tcg_gen_and_i64(pn, pn, pg);
-tcg_gen_andc_i64(pm, pm, pg);
-tcg_gen_or_i64(pd, pn, pm);
-}
-
-static void gen_sel_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn,
-   TCGv_vec pm, TCGv_vec pg)
-{
-tcg_gen_and_vec(vece, pn, pn, pg);
-tcg_gen_andc_vec(vece, pm, pm, pg);
-tcg_gen_or_vec(vece, pd, pn, pm);
-}
-
 static bool trans_SEL_(DisasContext *s, arg_rprr_s *a)
 {
-static const GVecGen4 op = {
-.fni8 = gen_sel_pg_i64,
-.fniv = gen_sel_pg_vec,
-.fno = gen_helper_sve_sel_,
-.prefer_i64 = TCG_TARGET_REG_BITS == 64,
-};
-
 if (a->s) {
 return false;
 }
-return do__flags(s, a, &op);
+if (sve_access_check(s)) {
+unsigned psz = pred_gvec_reg_size(s);
+tcg_gen_gvec_bitsel(MO_8, pred_full_reg_offset(s, a->rd),
+pred_full_reg_offset(s, a->pg),
+pred_full_reg_offset(s, a->rn),
+pred_full_reg_offset(s, a->rm), psz, psz);
+}
+return true;
 }
 
 static void gen_orr_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
-- 
2.25.1




[PATCH 08/10] spapr: introduce SpaprMachineClass::numa_assoc_domains

2020-08-15 Thread Daniel Henrique Barboza
We can't use the input from machine->numa_state->nodes directly
in the pSeries machine because PAPR does not work with raw distance
values, like ACPI SLIT does. We need to determine common
associativity domains, based on similar performance/distance of the
resources, and set these domains in the associativy array that goes
to the FDT of each resource.

To ease the translation between regular ACPI NUMA distance info
to our PAPR dialect, let's create a matrix called numa_assoc_domains
in the SpaprMachineClass. This matrix will be initiated during
machine init, where  we will read NUMA information from user input,
apply a heuristic to determine the associativity domains for each node,
then populate numa_assoc_domains accordingly.

The changes are mostly centered in the spapr_set_associativity()
helper that will use the values of numa_assoc_domains instead of
using 0x0, with spapr_dt_dynamic_reconfiguration_memory() and
h_home_node_associativity() being the exceptions.

To keep the changes under control, we'll plug in the matrix usage
in the existing code first. The actual heuristic to determine
the associativity domains for each NUMA node will come in a follow-up
patch.

Note that the matrix is initiated with zeros, meaning that there is
no guest changes implemented in this patch. We'll keep these
changes from legacy NUMA guests by not initiating the matrix
in these cases.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c| 46 +++
 hw/ppc/spapr_hcall.c  | 13 --
 hw/ppc/spapr_nvdimm.c | 13 +-
 hw/ppc/spapr_pci.c|  3 ++-
 include/hw/ppc/spapr.h|  7 +-
 include/hw/ppc/spapr_nvdimm.h |  5 ++--
 6 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b80a6f6936..4f50ab21ee 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -201,8 +201,13 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, 
PowerPCCPU *cpu,
 return ret;
 }
 
-void spapr_set_associativity(uint32_t *assoc, int node_id, int cpu_index)
+void spapr_set_associativity(uint32_t *assoc, int node_id, int cpu_index,
+ MachineState *machine)
 {
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+uint8_t assoc_domain1 = smc->numa_assoc_domains[node_id][0];
+uint8_t assoc_domain2 = smc->numa_assoc_domains[node_id][1];
+uint8_t assoc_domain3 = smc->numa_assoc_domains[node_id][2];
 uint8_t assoc_size = 0x4;
 
 if (cpu_index >= 0) {
@@ -211,17 +216,18 @@ void spapr_set_associativity(uint32_t *assoc, int 
node_id, int cpu_index)
 }
 
 assoc[0] = cpu_to_be32(assoc_size);
-assoc[1] = cpu_to_be32(0x0);
-assoc[2] = cpu_to_be32(0x0);
-assoc[3] = cpu_to_be32(0x0);
+assoc[1] = cpu_to_be32(assoc_domain1);
+assoc[2] = cpu_to_be32(assoc_domain2);
+assoc[3] = cpu_to_be32(assoc_domain3);
 assoc[4] = cpu_to_be32(node_id);
 }
 
-static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
+static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu,
+   MachineState *machine)
 {
 int index = spapr_get_vcpu_id(cpu);
 uint32_t associativity[6];
-spapr_set_associativity(associativity, cpu->node_id, index);
+spapr_set_associativity(associativity, cpu->node_id, index, machine);
 
 /* Advertise NUMA via ibm,associativity */
 return fdt_setprop(fdt, offset, "ibm,associativity", associativity,
@@ -335,14 +341,14 @@ static void add_str(GString *s, const gchar *s1)
 }
 
 static int spapr_dt_memory_node(void *fdt, int nodeid, hwaddr start,
-hwaddr size)
+hwaddr size, MachineState *machine)
 {
 uint32_t associativity[5];
 char mem_name[32];
 uint64_t mem_reg_property[2];
 int off;
 
-spapr_set_associativity(associativity, nodeid, -1);
+spapr_set_associativity(associativity, nodeid, -1, machine);
 
 mem_reg_property[0] = cpu_to_be64(start);
 mem_reg_property[1] = cpu_to_be64(size);
@@ -574,6 +580,7 @@ static int 
spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
void *fdt)
 {
 MachineState *machine = MACHINE(spapr);
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
 int nb_numa_nodes = machine->numa_state->num_nodes;
 int ret, i, offset;
 uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
@@ -628,12 +635,17 @@ static int 
spapr_dt_dynamic_reconfiguration_memory(SpaprMachineState *spapr,
 int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */
 cur_index += 2;
 for (i = 0; i < nr_nodes; i++) {
+uint8_t assoc_domain1 = smc->numa_assoc_domains[i][0];
+uint8_t assoc_domain2 = smc->numa_assoc_domains[i][1];
+uint8_t assoc_domain3 = smc->numa_assoc_domains[i][2];
+
 uint32_t associativity[] = {
-   

[PATCH 09/20] target/arm: Merge helper_sve_clr_* and helper_sve_movz_*

2020-08-15 Thread Richard Henderson
The existing clr functions have only one vector argument, and so
can only clear in place.  The existing movz functions have two
vector arguments, and so can clear while moving.  Merge them, with
a flag that controls the sense of active vs inactive elements
being cleared.

Signed-off-by: Richard Henderson 
---
 target/arm/helper-sve.h|  5 ---
 target/arm/sve_helper.c| 70 --
 target/arm/translate-sve.c | 53 +++--
 3 files changed, 34 insertions(+), 94 deletions(-)

diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
index 63c4a087ca..4411c47120 100644
--- a/target/arm/helper-sve.h
+++ b/target/arm/helper-sve.h
@@ -269,11 +269,6 @@ DEF_HELPER_FLAGS_3(sve_uminv_h, TCG_CALL_NO_RWG, i64, ptr, 
ptr, i32)
 DEF_HELPER_FLAGS_3(sve_uminv_s, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
 DEF_HELPER_FLAGS_3(sve_uminv_d, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
 
-DEF_HELPER_FLAGS_3(sve_clr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
-
 DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve_movz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 382fa82bc8..4758d46f34 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -956,85 +956,43 @@ uint32_t HELPER(sve_pnext)(void *vd, void *vg, uint32_t 
pred_desc)
 return flags;
 }
 
-/* Store zero into every active element of Zd.  We will use this for two
- * and three-operand predicated instructions for which logic dictates a
- * zero result.  In particular, logical shift by element size, which is
- * otherwise undefined on the host.
- *
- * For element sizes smaller than uint64_t, we use tables to expand
- * the N bits of the controlling predicate to a byte mask, and clear
- * those bytes.
+/*
+ * Copy Zn into Zd, and store zero into inactive elements.
+ * If inv, store zeros into the active elements.
  */
-void HELPER(sve_clr_b)(void *vd, void *vg, uint32_t desc)
-{
-intptr_t i, opr_sz = simd_oprsz(desc) / 8;
-uint64_t *d = vd;
-uint8_t *pg = vg;
-for (i = 0; i < opr_sz; i += 1) {
-d[i] &= ~expand_pred_b(pg[H1(i)]);
-}
-}
-
-void HELPER(sve_clr_h)(void *vd, void *vg, uint32_t desc)
-{
-intptr_t i, opr_sz = simd_oprsz(desc) / 8;
-uint64_t *d = vd;
-uint8_t *pg = vg;
-for (i = 0; i < opr_sz; i += 1) {
-d[i] &= ~expand_pred_h(pg[H1(i)]);
-}
-}
-
-void HELPER(sve_clr_s)(void *vd, void *vg, uint32_t desc)
-{
-intptr_t i, opr_sz = simd_oprsz(desc) / 8;
-uint64_t *d = vd;
-uint8_t *pg = vg;
-for (i = 0; i < opr_sz; i += 1) {
-d[i] &= ~expand_pred_s(pg[H1(i)]);
-}
-}
-
-void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
-{
-intptr_t i, opr_sz = simd_oprsz(desc) / 8;
-uint64_t *d = vd;
-uint8_t *pg = vg;
-for (i = 0; i < opr_sz; i += 1) {
-if (pg[H1(i)] & 1) {
-d[i] = 0;
-}
-}
-}
-
-/* Copy Zn into Zd, and store zero into inactive elements.  */
 void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
 {
 intptr_t i, opr_sz = simd_oprsz(desc) / 8;
+uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
 uint64_t *d = vd, *n = vn;
 uint8_t *pg = vg;
+
 for (i = 0; i < opr_sz; i += 1) {
-d[i] = n[i] & expand_pred_b(pg[H1(i)]);
+d[i] = n[i] & (expand_pred_b(pg[H1(i)]) ^ inv);
 }
 }
 
 void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
 {
 intptr_t i, opr_sz = simd_oprsz(desc) / 8;
+uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
 uint64_t *d = vd, *n = vn;
 uint8_t *pg = vg;
+
 for (i = 0; i < opr_sz; i += 1) {
-d[i] = n[i] & expand_pred_h(pg[H1(i)]);
+d[i] = n[i] & (expand_pred_h(pg[H1(i)]) ^ inv);
 }
 }
 
 void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
 {
 intptr_t i, opr_sz = simd_oprsz(desc) / 8;
+uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
 uint64_t *d = vd, *n = vn;
 uint8_t *pg = vg;
+
 for (i = 0; i < opr_sz; i += 1) {
-d[i] = n[i] & expand_pred_s(pg[H1(i)]);
+d[i] = n[i] & (expand_pred_s(pg[H1(i)]) ^ inv);
 }
 }
 
@@ -1043,8 +1001,10 @@ void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, 
uint32_t desc)
 intptr_t i, opr_sz = simd_oprsz(desc) / 8;
 uint64_t *d = vd, *n = vn;
 uint8_t *pg = vg;
+uint8_t inv = simd_data(desc);
+
 for (i = 0; i < opr_sz; i += 1) {
-d[i] = n[i] & -(uint64_t)(pg[H1(i)] & 1);
+d[i] = n[i] & -(uint64_t)((pg[H1(i)] ^ inv) & 1);
 }
 }
 
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 535d086838..ea6058f7ef 100644
--- 

[PATCH 13/20] target/arm: Tidy SVE tszimm shift formats

2020-08-15 Thread Richard Henderson
Rather than require the user to fill in the immediate (shl or shr),
create full formats that include the immediate.

Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 4f580a25e7..6425396ac1 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -150,13 +150,17 @@
 @rd_rn_i6    ... rn:5 . imm:s6 rd:5 &rri
 
 # Two register operand, one immediate operand, with predicate,
-# element size encoded as TSZHL.  User must fill in imm.
-@rdn_pg_tszimm   .. ... ... ... pg:3 . rd:5 \
-&rpri_esz rn=%reg_movprfx esz=%tszimm_esz
+# element size encoded as TSZHL.
+@rdn_pg_tszimm_shl   .. ... ... ... pg:3 . rd:5 \
+&rpri_esz rn=%reg_movprfx esz=%tszimm_esz imm=%tszimm_shl
+@rdn_pg_tszimm_shr   .. ... ... ... pg:3 . rd:5 \
+&rpri_esz rn=%reg_movprfx esz=%tszimm_esz imm=%tszimm_shr
 
 # Similarly without predicate.
-@rd_rn_tszimm    .. ... ... .. rn:5 rd:5 \
-&rri_esz esz=%tszimm16_esz
+@rd_rn_tszimm_shl    .. ... ... .. rn:5 rd:5 \
+&rri_esz esz=%tszimm16_esz imm=%tszimm16_shl
+@rd_rn_tszimm_shr    .. ... ... .. rn:5 rd:5 \
+&rri_esz esz=%tszimm16_esz imm=%tszimm16_shr
 
 # Two register operand, one immediate operand, with 4-bit predicate.
 # User must fill in imm.
@@ -289,14 +293,10 @@ UMINV   0100 .. 001 011 001 ... . .   
  @rd_pg_rn
 ### SVE Shift by Immediate - Predicated Group
 
 # SVE bitwise shift by immediate (predicated)
-ASR_zpzi0100 .. 000 000 100 ... .. ... . \
-@rdn_pg_tszimm imm=%tszimm_shr
-LSR_zpzi0100 .. 000 001 100 ... .. ... . \
-@rdn_pg_tszimm imm=%tszimm_shr
-LSL_zpzi0100 .. 000 011 100 ... .. ... . \
-@rdn_pg_tszimm imm=%tszimm_shl
-ASRD0100 .. 000 100 100 ... .. ... . \
-@rdn_pg_tszimm imm=%tszimm_shr
+ASR_zpzi0100 .. 000 000 100 ... .. ... .  @rdn_pg_tszimm_shr
+LSR_zpzi0100 .. 000 001 100 ... .. ... .  @rdn_pg_tszimm_shr
+LSL_zpzi0100 .. 000 011 100 ... .. ... .  @rdn_pg_tszimm_shl
+ASRD0100 .. 000 100 100 ... .. ... .  @rdn_pg_tszimm_shr
 
 # SVE bitwise shift by vector (predicated)
 ASR_zpzz0100 .. 010 000 100 ... . .   @rdn_pg_rm
@@ -400,12 +400,9 @@ RDVL0100 101 1 01010 imm:s6 rd:5
 ### SVE Bitwise Shift - Unpredicated Group
 
 # SVE bitwise shift by immediate (unpredicated)
-ASR_zzi 0100 .. 1 . 1001 00 . . \
-@rd_rn_tszimm imm=%tszimm16_shr
-LSR_zzi 0100 .. 1 . 1001 01 . . \
-@rd_rn_tszimm imm=%tszimm16_shr
-LSL_zzi 0100 .. 1 . 1001 11 . . \
-@rd_rn_tszimm imm=%tszimm16_shl
+ASR_zzi 0100 .. 1 . 1001 00 . .  @rd_rn_tszimm_shr
+LSR_zzi 0100 .. 1 . 1001 01 . .  @rd_rn_tszimm_shr
+LSL_zzi 0100 .. 1 . 1001 11 . .  @rd_rn_tszimm_shl
 
 # SVE bitwise shift by wide elements (unpredicated)
 # Note esz != 3
-- 
2.25.1




[PATCH 20/20] target/arm: Convert sq{, r}dmulh to gvec for aa64 advsimd

2020-08-15 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h| 10 
 target/arm/translate-a64.c | 33 ++
 target/arm/vec_helper.c| 48 ++
 3 files changed, 81 insertions(+), 10 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 378bb1898b..3ca73a1764 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -776,6 +776,16 @@ DEF_HELPER_FLAGS_5(gvec_mls_idx_s, TCG_CALL_NO_RWG,
 DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_5(neon_sqdmulh_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqdmulh_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c74c6e854c..d4da12268c 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -697,6 +697,20 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, 
int rd, int rn,
 tcg_temp_free_ptr(fpst);
 }
 
+/* Expand a 3-operand + qc + operation using an out-of-line helper.  */
+static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
+int rm, gen_helper_gvec_3_ptr *fn)
+{
+TCGv_ptr qc_ptr = tcg_temp_new_ptr();
+
+tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
+tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm), qc_ptr,
+   is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
+tcg_temp_free_ptr(qc_ptr);
+}
+
 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
  * than the 32 bit equivalent.
  */
@@ -11753,6 +11767,15 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
 }
 return;
+case 0x16: /* SQDMULH, SQRDMULH */
+{
+static gen_helper_gvec_3_ptr * const fns[2][2] = {
+{ gen_helper_neon_sqdmulh_h, gen_helper_neon_sqrdmulh_h },
+{ gen_helper_neon_sqdmulh_s, gen_helper_neon_sqrdmulh_s },
+};
+gen_gvec_op3_qc(s, is_q, rd, rn, rm, fns[size - 1][u]);
+}
+return;
 case 0x11:
 if (!u) { /* CMTST */
 gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
@@ -11864,16 +11887,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 genenvfn = fns[size][u];
 break;
 }
-case 0x16: /* SQDMULH, SQRDMULH */
-{
-static NeonGenTwoOpEnvFn * const fns[2][2] = {
-{ gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 
},
-{ gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 
},
-};
-assert(size == 1 || size == 2);
-genenvfn = fns[size - 1][u];
-break;
-}
 default:
 g_assert_not_reached();
 }
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
index fb53684ce3..73d62c4e4f 100644
--- a/target/arm/vec_helper.c
+++ b/target/arm/vec_helper.c
@@ -109,6 +109,30 @@ void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
 clear_tail(d, opr_sz, simd_maxsz(desc));
 }
 
+void HELPER(neon_sqdmulh_h)(void *vd, void *vn, void *vm,
+void *vq, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc);
+int16_t *d = vd, *n = vn, *m = vm;
+
+for (i = 0; i < opr_sz / 2; ++i) {
+d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, false, vq);
+}
+clear_tail(d, opr_sz, simd_maxsz(desc));
+}
+
+void HELPER(neon_sqrdmulh_h)(void *vd, void *vn, void *vm,
+ void *vq, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc);
+int16_t *d = vd, *n = vn, *m = vm;
+
+for (i = 0; i < opr_sz / 2; ++i) {
+d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, true, vq);
+}
+clear_tail(d, opr_sz, simd_maxsz(desc));
+}
+
 /* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
 static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
  bool neg, bool round, uint32_t *sat)
@@ -172,6 +196,30 @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
 clear_tail(d, opr_sz, simd_maxsz(desc));
 }
 
+void HELPER(neon_sqdmulh_s)(void *vd, void *vn, void *vm,
+void *vq, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc);

Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Philippe Mathieu-Daudé
This is v3 with no change w.r.t. v1/v2 (except this time you correctly
Cc'ed the maintainers). Maybe something is wrong in your setup?

On 8/15/20 5:12 PM, Rohit Shinde wrote:
> Added the fallthrough comment so that the compiler doesn't emit an error on 
> compiling with the -Wimplicit-fallthrough flag.
> 
> Signed-off-by: Rohit Shinde 
> ---
>  qapi/opts-visitor.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> index 7781c23a42..43cf60d3a0 100644
> --- a/qapi/opts-visitor.c
> +++ b/qapi/opts-visitor.c
> @@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
>  }
>  ov->list_mode = LM_IN_PROGRESS;
>  /* range has been completed, fall through in order to pop option */
> +__attribute__((fallthrough));
>  
>  case LM_IN_PROGRESS: {
>  const QemuOpt *opt;
> 




[PATCH 01/20] qemu/int128: Add int128_lshift

2020-08-15 Thread Richard Henderson
Add left-shift to match the existing right-shift.

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

diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index 5c9890db8b..76ea405922 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -63,6 +63,11 @@ static inline Int128 int128_rshift(Int128 a, int n)
 return a >> n;
 }
 
+static inline Int128 int128_lshift(Int128 a, int n)
+{
+return a << n;
+}
+
 static inline Int128 int128_add(Int128 a, Int128 b)
 {
 return a + b;
@@ -217,6 +222,17 @@ static inline Int128 int128_rshift(Int128 a, int n)
 }
 }
 
+static inline Int128 int128_lshift(Int128 a, int n)
+{
+uint64_t l = a.lo << (n & 63);
+if (n >= 64) {
+return int128_make128(0, l);
+} else if (n > 0) {
+return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
+}
+return a;
+}
+
 static inline Int128 int128_add(Int128 a, Int128 b)
 {
 uint64_t lo = a.lo + b.lo;
-- 
2.25.1




Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Philippe Mathieu-Daudé
When you repost a patch, please add a version. This is patch v2.
Next (once you read my v1 comments) should be v3.

Watch out, v1 correctly Cc'ed the maintainers, this v2 doesn't.

On 8/15/20 5:11 PM, Rohit Shinde wrote:
> Added the fallthrough comment so that the compiler doesn't emit an error on 
> compiling with the -Wimplicit-fallthrough flag.
> 
> Signed-off-by: Rohit Shinde 
> ---
>  qapi/opts-visitor.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> index 7781c23a42..43cf60d3a0 100644
> --- a/qapi/opts-visitor.c
> +++ b/qapi/opts-visitor.c
> @@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
>  }
>  ov->list_mode = LM_IN_PROGRESS;
>  /* range has been completed, fall through in order to pop option */
> +__attribute__((fallthrough));
>  
>  case LM_IN_PROGRESS: {
>  const QemuOpt *opt;
> 




Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Philippe Mathieu-Daudé
Hi Rohit,

Congratulation for your first patch! It is in very
good shape already :)

It is easier for the reviewers if you start the patch subject with
the name of the subsystem concerned, or the file modified:

"qapi/opts-visitor: Add missing fallthrough annotations"

On 8/15/20 3:00 PM, Rohit Shinde wrote:
> Added the fallthrough comment so that the compiler doesn't emit an error on 
> compiling with the -Wimplicit-fallthrough flag.

If possible align the description to 72 chars.

> 
> Signed off by: Rohit Shinde

The tag is written "Signed-off-by" with '-', then your "name ":

Signed-off-by: Rohit Shinde 

If you configure your git client, using 'git-commit -s' will
automatically add the S-o-b tag:

$ git config user.name "Rohit Shinde"
$ git config user.email "rohit.shinde12...@gmail.com"
$ git commit -s

> ---
>  qapi/opts-visitor.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> index 7781c23a42..43cf60d3a0 100644
> --- a/qapi/opts-visitor.c
> +++ b/qapi/opts-visitor.c
> @@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
>  }
>  ov->list_mode = LM_IN_PROGRESS;
>  /* range has been completed, fall through in order to pop option */
> +__attribute__((fallthrough));

C uses attributes when declaring a type/variable/function.
Here this is inside a function body, not a declaration.
A simple "/* fallthrough */" comment will make the compiler happy.
You can see a similar patch for example:
https://git.qemu.org/?p=qemu.git;a=blobdiff;f=disas/sh4.c;h=dcdbdf26d8;hp=55ef865a3;hb=ccb237090f;hpb=7aa12aa215

When you find an issue that might have already been fixed elsewhere
in the repository, 'git-log -p' is your friend. Since the commits are
patches already accepted/merged, they might be a good source to learn
(how the issue was fixed, how the bug was described, ...).

Regards,

Phil.

>  
>  case LM_IN_PROGRESS: {
>  const QemuOpt *opt;
> 




[PATCH v4 1/3] i386: Simplify CPUID_8000_001E for AMD

2020-08-15 Thread Babu Moger
apic_id contains all the information required to build CPUID_8000_001E.
Also remove the restriction on number bits on core_id and node_id.
Remove all the hardcoded values and replace with generalized
fields.

Refer the Processor Programming Reference (PPR) documentation
available from the bugzilla Link below.

Signed-off-by: Babu Moger 
Reviewed-by: Igor Mammedov 
---
 target/i386/cpu.c |   77 +
 1 file changed, 36 insertions(+), 41 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 588f32e136..c892432cae 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -388,57 +388,52 @@ static void encode_topo_cpuid801e(X86CPUTopoInfo 
*topo_info, X86CPU *cpu,
 {
 X86CPUTopoIDs topo_ids = {0};
 unsigned long nodes = MAX(topo_info->nodes_per_pkg, 1);
-int shift;
 
 x86_topo_ids_from_apicid_epyc(cpu->apic_id, topo_info, &topo_ids);
 
 *eax = cpu->apic_id;
+
 /*
+ * CPUID_Fn801E_EBX [Core Identifiers] (CoreId)
+ * Read-only. Reset: _h.
+ * See Core::X86::Cpuid::ExtApicId.
+ * Core::X86::Cpuid::CoreId_lthree[1:0]_core[3:0]_thread[1:0];
  * CPUID_Fn801E_EBX
- * 31:16 Reserved
- * 15:8  Threads per core (The number of threads per core is
- *   Threads per core + 1)
- *  7:0  Core id (see bit decoding below)
- *   SMT:
- *   4:3 node id
- * 2 Core complex id
- *   1:0 Core id
- *   Non SMT:
- *   5:4 node id
- * 3 Core complex id
- *   1:0 Core id
+ * Bits Description
+ * 31:16 Reserved.
+ * 15:8 ThreadsPerCore: threads per core. Read-only. Reset: XXh.
+ *  The number of threads per core is ThreadsPerCore+1.
+ *  7:0 CoreId: core ID. Read-only. Reset: XXh.
+ *
+ *  NOTE: CoreId is already part of apic_id. Just use it. We can
+ *  use all the 8 bits to represent the core_id here.
  */
-*ebx = ((topo_info->threads_per_core - 1) << 8) | (topo_ids.node_id << 3) |
-(topo_ids.core_id);
+*ebx = ((topo_info->threads_per_core - 1) << 8) | (topo_ids.core_id & 
0xFF);
+
 /*
+ * CPUID_Fn801E_ECX [Node Identifiers] (NodeId)
+ * Read-only. Reset: _0XXXh.
+ * Core::X86::Cpuid::NodeId_lthree[1:0]_core[3:0]_thread[1:0];
  * CPUID_Fn801E_ECX
- * 31:11 Reserved
- * 10:8  Nodes per processor (Nodes per processor is number of nodes + 1)
- *  7:0  Node id (see bit decoding below)
- * 2  Socket id
- *   1:0  Node id
+ * Bits Description
+ * 31:11 Reserved.
+ * 10:8 NodesPerProcessor: Node per processor. Read-only. Reset: XXXb.
+ *  ValidValues:
+ *  Value Description
+ *  000b  1 node per processor.
+ *  001b  2 nodes per processor.
+ *  010b Reserved.
+ *  011b 4 nodes per processor.
+ *  111b-100b Reserved.
+ *  7:0 NodeId: Node ID. Read-only. Reset: XXh.
+ *
+ * NOTE: Hardware reserves 3 bits for number of nodes per processor.
+ * But users can create more nodes than the actual hardware can
+ * support. To genaralize we can use all the upper 8 bits for nodes.
+ * NodeId is combination of node and socket_id which is already decoded
+ * in apic_id. Just use it by shifting.
  */
-if (nodes <= 4) {
-*ecx = ((nodes - 1) << 8) | (topo_ids.pkg_id << 2) | topo_ids.node_id;
-} else {
-/*
- * Node id fix up. Actual hardware supports up to 4 nodes. But with
- * more than 32 cores, we may end up with more than 4 nodes.
- * Node id is a combination of socket id and node id. Only requirement
- * here is that this number should be unique accross the system.
- * Shift the socket id to accommodate more nodes. We dont expect both
- * socket id and node id to be big number at the same time. This is not
- * an ideal config but we need to to support it. Max nodes we can have
- * is 32 (255/8) with 8 cores per node and 255 max cores. We only need
- * 5 bits for nodes. Find the left most set bit to represent the total
- * number of nodes. find_last_bit returns last set bit(0 based). Left
- * shift(+1) the socket id to represent all the nodes.
- */
-nodes -= 1;
-shift = find_last_bit(&nodes, 8);
-*ecx = (nodes << 8) | (topo_ids.pkg_id << (shift + 1)) |
-   topo_ids.node_id;
-}
+*ecx = ((nodes - 1) << 8) | cpu->node_id;
 *edx = 0;
 }
 




[PATCH 2/2] hw: megasas: consider 'iov_count=0' is an error in megasas_map_sgl

2020-08-15 Thread Li Qiang
Currently in 'megasas_map_sgl' when 'iov_count=0' will just return
success however the 'cmd' doens't contain any iov. This will cause
the assert in 'scsi_dma_complete' failed. This is because in
'dma_blk_cb' the 'dbs->sg_cur_index == dbs->sg->nsg' will be true
and just call 'dma_complete'. However now there is no aiocb returned.

This fixes the LP#1878263:

-->https://bugs.launchpad.net/qemu/+bug/1878263

Reported-by: Alexander Bulekov 
Signed-off-by: Li Qiang 
---
 hw/scsi/megasas.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index d6c9680c36..9562c58a2d 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -278,7 +278,7 @@ static int megasas_map_sgl(MegasasState *s, MegasasCmd 
*cmd, union mfi_sgl *sgl)
 
 cmd->flags = le16_to_cpu(cmd->frame->header.flags);
 iov_count = cmd->frame->header.sge_count;
-if (iov_count > MEGASAS_MAX_SGE) {
+if (!iov_count || iov_count > MEGASAS_MAX_SGE) {
 trace_megasas_iovec_sgl_overflow(cmd->index, iov_count,
  MEGASAS_MAX_SGE);
 return -1;
-- 
2.17.1




[PATCH 01/10] hw: add compat machines for 5.2

2020-08-15 Thread Daniel Henrique Barboza
From: Cornelia Huck 

Add 5.2 machine types for arm/i440fx/q35/s390x/spapr.

Signed-off-by: Cornelia Huck 
---
 hw/arm/virt.c  |  9 -
 hw/core/machine.c  |  3 +++
 hw/i386/pc.c   |  3 +++
 hw/i386/pc_piix.c  | 14 +-
 hw/i386/pc_q35.c   | 13 -
 hw/ppc/spapr.c | 15 +--
 hw/s390x/s390-virtio-ccw.c | 14 +-
 include/hw/boards.h|  3 +++
 include/hw/i386/pc.h   |  3 +++
 9 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ecfee362a1..acf9bfbece 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2546,10 +2546,17 @@ static void machvirt_machine_init(void)
 }
 type_init(machvirt_machine_init);
 
+static void virt_machine_5_2_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(5, 2)
+
 static void virt_machine_5_1_options(MachineClass *mc)
 {
+virt_machine_5_2_options(mc);
+compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
 }
-DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
+DEFINE_VIRT_MACHINE(5, 1)
 
 static void virt_machine_5_0_options(MachineClass *mc)
 {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 8d1a90c6cf..cf5f2dfaeb 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -28,6 +28,9 @@
 #include "hw/mem/nvdimm.h"
 #include "migration/vmstate.h"
 
+GlobalProperty hw_compat_5_1[] = {};
+const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1);
+
 GlobalProperty hw_compat_5_0[] = {
 { "pci-host-bridge", "x-config-reg-migration-enabled", "off" },
 { "virtio-balloon-device", "page-poison", "false" },
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 47c5ca3e34..9aa813949c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -97,6 +97,9 @@
 #include "fw_cfg.h"
 #include "trace.h"
 
+GlobalProperty pc_compat_5_1[] = {};
+const size_t pc_compat_5_1_len = G_N_ELEMENTS(pc_compat_5_1);
+
 GlobalProperty pc_compat_5_0[] = {
 };
 const size_t pc_compat_5_0_len = G_N_ELEMENTS(pc_compat_5_0);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b789e83f9a..c5ba70ca17 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -426,7 +426,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
 machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
 }
 
-static void pc_i440fx_5_1_machine_options(MachineClass *m)
+static void pc_i440fx_5_2_machine_options(MachineClass *m)
 {
 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_i440fx_machine_options(m);
@@ -435,6 +435,18 @@ static void pc_i440fx_5_1_machine_options(MachineClass *m)
 pcmc->default_cpu_version = 1;
 }
 
+DEFINE_I440FX_MACHINE(v5_2, "pc-i440fx-5.2", NULL,
+  pc_i440fx_5_2_machine_options);
+
+static void pc_i440fx_5_1_machine_options(MachineClass *m)
+{
+pc_i440fx_5_2_machine_options(m);
+m->alias = NULL;
+m->is_default = false;
+compat_props_add(m->compat_props, hw_compat_5_1, hw_compat_5_1_len);
+compat_props_add(m->compat_props, pc_compat_5_1, pc_compat_5_1_len);
+}
+
 DEFINE_I440FX_MACHINE(v5_1, "pc-i440fx-5.1", NULL,
   pc_i440fx_5_1_machine_options);
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a3e607a544..0cb9c18cd4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -353,7 +353,7 @@ static void pc_q35_machine_options(MachineClass *m)
 m->max_cpus = 288;
 }
 
-static void pc_q35_5_1_machine_options(MachineClass *m)
+static void pc_q35_5_2_machine_options(MachineClass *m)
 {
 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_q35_machine_options(m);
@@ -361,6 +361,17 @@ static void pc_q35_5_1_machine_options(MachineClass *m)
 pcmc->default_cpu_version = 1;
 }
 
+DEFINE_Q35_MACHINE(v5_2, "pc-q35-5.2", NULL,
+   pc_q35_5_2_machine_options);
+
+static void pc_q35_5_1_machine_options(MachineClass *m)
+{
+pc_q35_5_2_machine_options(m);
+m->alias = NULL;
+compat_props_add(m->compat_props, hw_compat_5_1, hw_compat_5_1_len);
+compat_props_add(m->compat_props, pc_compat_5_1, pc_compat_5_1_len);
+}
+
 DEFINE_Q35_MACHINE(v5_1, "pc-q35-5.1", NULL,
pc_q35_5_1_machine_options);
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a5bb0736e2..dd2fa4826b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4581,15 +4581,26 @@ static void 
spapr_machine_latest_class_options(MachineClass *mc)
 }\
 type_init(spapr_machine_register_##suffix)
 
+/*
+ * pseries-5.2
+ */
+static void spapr_machine_5_2_class_options(MachineClass *mc)
+{
+/* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE(5_2, "5.2", true);
+
 /*
  * pseries-5.1
  */
 static void spapr_machine_5_1_class_options(MachineClass *mc)
 {
-/* Defaults for the latest behaviour inherited from the base class */
+spapr_machine_5_2_class_options(mc);
+compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5

Re: [PATCH 7/7] target/arm/cpu: spe: Enable spe to work with host cpu

2020-08-15 Thread Andrew Jones
On Fri, Aug 14, 2020 at 12:28:25PM -0700, Richard Henderson wrote:
> On 8/11/20 9:49 AM, Andrew Jones wrote:
> > Yes, except you need to drop the ARM_FEATURE_SPE define and use the ID
> > register bit instead like "sve_supported" does.
> 
> On a related note, I think we have a latent bug, or at least a mis-feature:
> 
> sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 
> 0;
> ...
> /* Add feature bits that can't appear until after VCPU init. */
> if (sve_supported) {
> t = ahcf->isar.id_aa64pfr0;
> t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
> ahcf->isar.id_aa64pfr0 = t;
> }
> 
> 
> Should it in fact be
> 
> if (!sve_supported) {
> t = ahcf->isar.id_aa64pfr0;
> t = FIELD_DP64(t, ID_AA64PFR0, SVE, 0);
> ahcf->isar.id_aa64pfr0 = t;
> }
> 
> ?
> 
> Forcing the value to 1 here is going to be wrong the moment we have an SVE2
> enabled cpu.

Indeed. I think KVM should add a KVM_CAP_ARM_SVE2 cap. Then, we keep the
code similar to the way it is now, but set ID_AA64PFR0 appropriately
based on which CAPs are present. I think we probably need that CAP anyway
in order to ensure a guest that is using SVE2 cannot be migrated to a host
that only has SVE.

> 
> Similarly, SPE has more than one "enabled" value for PMSVer.
>

I'll take a look at the KVM series for SPE next week to see if
the UAPI will allow us to determine what values are possible.

Thanks for the heads up about this.

drew




[PATCH 0/2] Fix the assert failure in scsi_dma_complete

2020-08-15 Thread Li Qiang
Currently in 'megasas_map_sgl' when 'iov_count=0' will just return
success however the 'cmd' doens't contain any iov. This will cause
the assert in 'scsi_dma_complete' failed. This is because in
'dma_blk_cb' the 'dbs->sg_cur_index == dbs->sg->nsg' will be true
and just call 'dma_complete'. However now there is no aiocb returned.

This is the LP#1878263:

-->https://bugs.launchpad.net/qemu/+bug/1878263

To solve this we will consider the 'iov_count=0' is an error.
In the first patch, I uses -1 to indicate an error and in the second
patch I consider 'iov_count=0' is an error.

Li Qiang (2):
  hw: megasas: return -1 when 'megasas_map_sgl' fails
  hw: megasas: consider 'iov_count=0' is an error in megasas_map_sgl

 hw/scsi/megasas.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

-- 
2.17.1




[PATCH 09/10] spapr: consider user input when defining spapr guest NUMA

2020-08-15 Thread Daniel Henrique Barboza
This patch puts all the pieces together to finally allow user
input when defining the NUMA topology of the spapr guest.

The logic is centered in the new spapr_init_numa_assoc_domains()
function. This is called once at machine_init(), if we're not
using legacy_numa mode, to initiate the numa_assoc_domain matrix
introduced in the previous patch. We can divide the logic in two
that are mashed together in the body of this function.

First stage is to sanitize the user input from numa_state. Due to
the nature of what ACPI allows the user to do (directly define
the distances the guest will see in the DT) versus what PAPR
allows (we can hint at associativity relations, the OS must decide
what to do), we had to bake in kernel logic in here. The kernel
allows 4 levels of NUMA, where the last one is always the node_id
itself, with distance = 10. The other levels doubles the distances
of previous levels, meaning that the pSeries kernel will only
show distances of 20, 40, 80 and 160 (in case no match is found).
This first stage is then to get the distances defined by the user
and approximate them to those discrete values:

- user distance 11 to 30 will be interpreted as 20
- user distance 31 to 60 will be interpreted as 40
- user distance 61 to 120 will be interpreted as 80
- user distance 121 and beyond will be interpreted as 160
- user distance 10 stays 10

The other stage is defining the associativity domains based
on the NUMA level match. Again, more than one strategy exists
for this same problem, with different results. The approach
taken is to re-use any existing associativity values to the
new matches, instead of overwriting them with a new associativity
match. This decision is necessary because neither we, nor the
pSeries kernel, supports multiple associativity domains for
each resource, meaning that we have to decide what to preserve.
With the current logic, the associativities established by
the earlier nodes take precedence, i.e. associativities defined
by the first node are retained along all other nodes.

These decisions have direct impact on how the user will interact
with the NUMA topology, and none of them are perfect. To keep
this commit message no longer than it already is, let's update the
existing documentation in ppc-spapr-numa.rst with more in depth
details and design considerations/drawbacks in the next patch.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 109 +
 1 file changed, 109 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4f50ab21ee..0d60d06cf4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -222,6 +222,109 @@ void spapr_set_associativity(uint32_t *assoc, int 
node_id, int cpu_index,
 assoc[4] = cpu_to_be32(node_id);
 }
 
+static void spapr_numa_assoc_assign_domain(SpaprMachineClass *smc,
+   uint8_t nodeA, uint8_t nodeB,
+   uint8_t numaLevel,
+   uint8_t curr_domain)
+{
+uint8_t assoc_A, assoc_B;
+
+assoc_A = smc->numa_assoc_domains[nodeA][numaLevel];
+assoc_B = smc->numa_assoc_domains[nodeB][numaLevel];
+
+/* No associativity domains on both. Assign and move on */
+if ((assoc_A | assoc_B) == 0) {
+smc->numa_assoc_domains[nodeA][numaLevel] = curr_domain;
+smc->numa_assoc_domains[nodeB][numaLevel] = curr_domain;
+return;
+}
+
+/* Use the existing assoc domain of any of the nodes to not
+ * disrupt previous associations already defined */
+if (assoc_A != 0) {
+smc->numa_assoc_domains[nodeB][numaLevel] = assoc_A;
+} else {
+smc->numa_assoc_domains[nodeA][numaLevel] = assoc_B;
+}
+}
+
+static void spapr_init_numa_assoc_domains(MachineState *machine)
+{
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+int nb_numa_nodes = machine->numa_state->num_nodes;
+NodeInfo *numa_info = machine->numa_state->nodes;
+uint8_t existing_nodes[nb_numa_nodes];
+int i, j, src_node, dst_node, index = 0;
+
+/* We don't have information about any extra NUMA nodes that
+ * the machine might create at this point (e.g. NVLink2 GPUs).
+ * Assigning associativity domains with low numbers might have
+ * unintended consequences in the presence of GPUs, which are
+ * supposed to always be at maximum distance of everything else,
+ * because we might end up using a GPU numa_id identifier by
+ * accident.
+ *
+ * Starting this counter at MAX_NODES avoids any possible
+ * collision since no NUMA id can reach this value. */
+uint8_t assoc_domain = MAX_NODES;
+
+/* We will assume that the NUMA nodes might be sparsed. This
+ * preliminary fetch step is required to avoid having to search
+ * for an existing NUMA node more than once. */
+for (i = 0; i < MAX_NODES; i++) {
+if (numa_info[i].present) {
+existing_nodes[index++] = i;
+

[PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Rohit Shinde
Added the fallthrough comment so that the compiler doesn't emit an error on 
compiling with the -Wimplicit-fallthrough flag.

Signed-off-by: Rohit Shinde 
---
 qapi/opts-visitor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 7781c23a42..43cf60d3a0 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
 }
 ov->list_mode = LM_IN_PROGRESS;
 /* range has been completed, fall through in order to pop option */
+__attribute__((fallthrough));
 
 case LM_IN_PROGRESS: {
 const QemuOpt *opt;
-- 
2.25.1




Re: [PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200815130046.5344-1-rohit.shinde12...@gmail.com/



Hi,

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

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

  CC  qapi/qapi-visit-block.o
  CC  qapi/qapi-visit-char.o
/tmp/qemu-test/src/qapi/opts-visitor.c: In function 'opts_next_list':
/tmp/qemu-test/src/qapi/opts-visitor.c:269:9: error: empty declaration [-Werror]
 __attribute__((fallthrough));
 ^
cc1: all warnings being treated as errors
make: *** [qapi/opts-visitor.o] Error 1
make: *** Waiting for unfinished jobs
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 709, in 
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=0b358c245bfb4f1ebcc47bd660f243d3', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-hbfp957p/src/docker-src.2020-08-15-11.14.44.15026:/var/tmp/qemu:z,ro',
 'qemu/centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=0b358c245bfb4f1ebcc47bd660f243d3
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-hbfp957p/src'
make: *** [docker-run-test-quick@centos7] Error 2

real2m2.249s
user0m7.870s


The full log is available at
http://patchew.org/logs/20200815130046.5344-1-rohit.shinde12...@gmail.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH] Fixes: Fallthrough warning on line 270 of qemu/qapi/opts-visitor.c

2020-08-15 Thread Rohit Shinde
Added the fallthrough comment so that the compiler doesn't emit an error on 
compiling with the -Wimplicit-fallthrough flag.

Signed-off-by: Rohit Shinde 
---
 qapi/opts-visitor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 7781c23a42..43cf60d3a0 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -266,6 +266,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
 }
 ov->list_mode = LM_IN_PROGRESS;
 /* range has been completed, fall through in order to pop option */
+__attribute__((fallthrough));
 
 case LM_IN_PROGRESS: {
 const QemuOpt *opt;
-- 
2.25.1




Re: [PATCH v5 10/14] cpus: add handle_interrupt to the CpusAccel interface

2020-08-15 Thread Richard Henderson
On 8/12/20 11:32 AM, Claudio Fontana wrote:
> +static void generic_handle_interrupt(CPUState *cpu, int mask)
> +{
> +cpu->interrupt_request |= mask;
> +
> +if (!qemu_cpu_is_self(cpu)) {
> +qemu_cpu_kick(cpu);
> +}
> +}
> +
> +void cpu_interrupt(CPUState *cpu, int mask)
> +{
> +if (cpus_accel && cpus_accel->handle_interrupt) {
> +cpus_accel->handle_interrupt(cpu, mask);
> +} else {
> +generic_handle_interrupt(cpu, mask);
> +}
> +}

First, by this point you have converted all of the accelerators, so I would
expect cpus_accel to always be non-null.  I would expect a patch immediately
preceding this one to place an assert to that effect somewhere in the startup
code, and to remove all of the checks.

Second, I would prefer that all methods be non-null, so that you don't need to
check that either.  This patch would add generic_handle_interrupt (perhaps
named cpus_accel_default_handle_interrupt declared in sysemu/cpus.h?) to the
CpusAccel structure of all except TCG.

Similarly for all other methods that are checking non-null-ness of the method
pointer.  Perhaps assert non-null for each method in cpus_register_accel().


r~



Re: [PATCH 2/2] hw: megasas: consider 'iov_count=0' is an error in megasas_map_sgl

2020-08-15 Thread Li Qiang
Oh, sorry to forget to CC Alexander Bulekov.

Thanks,
Li Qiang

Li Qiang  于2020年8月15日周六 下午10:20写道:
>
> Currently in 'megasas_map_sgl' when 'iov_count=0' will just return
> success however the 'cmd' doens't contain any iov. This will cause
> the assert in 'scsi_dma_complete' failed. This is because in
> 'dma_blk_cb' the 'dbs->sg_cur_index == dbs->sg->nsg' will be true
> and just call 'dma_complete'. However now there is no aiocb returned.
>
> This fixes the LP#1878263:
>
> -->https://bugs.launchpad.net/qemu/+bug/1878263
>
> Reported-by: Alexander Bulekov 
> Signed-off-by: Li Qiang 
> ---
>  hw/scsi/megasas.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
> index d6c9680c36..9562c58a2d 100644
> --- a/hw/scsi/megasas.c
> +++ b/hw/scsi/megasas.c
> @@ -278,7 +278,7 @@ static int megasas_map_sgl(MegasasState *s, MegasasCmd 
> *cmd, union mfi_sgl *sgl)
>
>  cmd->flags = le16_to_cpu(cmd->frame->header.flags);
>  iov_count = cmd->frame->header.sge_count;
> -if (iov_count > MEGASAS_MAX_SGE) {
> +if (!iov_count || iov_count > MEGASAS_MAX_SGE) {
>  trace_megasas_iovec_sgl_overflow(cmd->index, iov_count,
>   MEGASAS_MAX_SGE);
>  return -1;
> --
> 2.17.1
>



[PATCH 16/20] target/arm: Fix sve_zip_p vs odd vector lengths

2020-08-15 Thread Richard Henderson
Wrote too much with low-half zip (zip1) with vl % 512 != 0.

Adjust all of the x + (y << s) to x | (y << s) as a style fix.

Reported-by: Laurent Desnogues 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index fcb46f150f..b8651ae173 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -1870,6 +1870,7 @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
 int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
 intptr_t high = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
+int esize = 1 << esz;
 uint64_t *d = vd;
 intptr_t i;
 
@@ -1882,33 +1883,35 @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 mm = extract64(mm, high * half, half);
 nn = expand_bits(nn, esz);
 mm = expand_bits(mm, esz);
-d[0] = nn + (mm << (1 << esz));
+d[0] = nn | (mm << esize);
 } else {
-ARMPredicateReg tmp_n, tmp_m;
+ARMPredicateReg tmp;
 
 /* We produce output faster than we consume input.
Therefore we must be mindful of possible overlap.  */
-if ((vn - vd) < (uintptr_t)oprsz) {
-vn = memcpy(&tmp_n, vn, oprsz);
-}
-if ((vm - vd) < (uintptr_t)oprsz) {
-vm = memcpy(&tmp_m, vm, oprsz);
+if (vd == vn) {
+vn = memcpy(&tmp, vn, oprsz);
+if (vd == vm) {
+vm = vn;
+}
+} else if (vd == vm) {
+vm = memcpy(&tmp, vm, oprsz);
 }
 if (high) {
 high = oprsz >> 1;
 }
 
-if ((high & 3) == 0) {
+if ((oprsz & 7) == 0) {
 uint32_t *n = vn, *m = vm;
 high >>= 2;
 
-for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
+for (i = 0; i < oprsz / 8; i++) {
 uint64_t nn = n[H4(high + i)];
 uint64_t mm = m[H4(high + i)];
 
 nn = expand_bits(nn, esz);
 mm = expand_bits(mm, esz);
-d[i] = nn + (mm << (1 << esz));
+d[i] = nn | (mm << esize);
 }
 } else {
 uint8_t *n = vn, *m = vm;
@@ -1920,7 +1923,7 @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, 
uint32_t pred_desc)
 
 nn = expand_bits(nn, esz);
 mm = expand_bits(mm, esz);
-d16[H2(i)] = nn + (mm << (1 << esz));
+d16[H2(i)] = nn | (mm << esize);
 }
 }
 }
-- 
2.25.1




[PATCH v4 3/3] hw/i386: Remove node_id, nr_nodes and nodes_per_pkg from topology

2020-08-15 Thread Babu Moger
Remove node_id, nr_nodes and nodes_per_pkg from topology. Use
die_id, nr_dies and dies_per_pkg which is already available.
Removes the confusion over two variables.

With node_id removed in topology the uninitialized memory issue
with -device and CPU hotplug will be fixed.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=1828750
Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |1 -
 hw/i386/x86.c  |1 -
 include/hw/i386/topology.h |   40 +---
 target/i386/cpu.c  |   11 +++
 target/i386/cpu.h  |1 -
 5 files changed, 12 insertions(+), 42 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 47c5ca3e34..0ae5cb3af4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1498,7 +1498,6 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 init_topo_info(&topo_info, x86ms);
 
 env->nr_dies = x86ms->smp_dies;
-env->nr_nodes = topo_info.nodes_per_pkg;
 env->pkg_offset = x86ms->apicid_pkg_offset(&topo_info);
 
 /*
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index e90c42d2fc..4efa1f8b87 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -62,7 +62,6 @@ inline void init_topo_info(X86CPUTopoInfo *topo_info,
 {
 MachineState *ms = MACHINE(x86ms);
 
-topo_info->nodes_per_pkg = ms->numa_state->num_nodes / ms->smp.sockets;
 topo_info->dies_per_pkg = x86ms->smp_dies;
 topo_info->cores_per_die = ms->smp.cores;
 topo_info->threads_per_core = ms->smp.threads;
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 07239f95f4..05ddde7ba0 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -47,14 +47,12 @@ typedef uint32_t apic_id_t;
 
 typedef struct X86CPUTopoIDs {
 unsigned pkg_id;
-unsigned node_id;
 unsigned die_id;
 unsigned core_id;
 unsigned smt_id;
 } X86CPUTopoIDs;
 
 typedef struct X86CPUTopoInfo {
-unsigned nodes_per_pkg;
 unsigned dies_per_pkg;
 unsigned cores_per_die;
 unsigned threads_per_core;
@@ -89,11 +87,6 @@ static inline unsigned apicid_die_width(X86CPUTopoInfo 
*topo_info)
 return apicid_bitwidth_for_count(topo_info->dies_per_pkg);
 }
 
-/* Bit width of the node_id field per socket */
-static inline unsigned apicid_node_width_epyc(X86CPUTopoInfo *topo_info)
-{
-return apicid_bitwidth_for_count(MAX(topo_info->nodes_per_pkg, 1));
-}
 /* Bit offset of the Core_ID field
  */
 static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info)
@@ -114,30 +107,23 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo 
*topo_info)
 return apicid_die_offset(topo_info) + apicid_die_width(topo_info);
 }
 
-#define NODE_ID_OFFSET 3 /* Minimum node_id offset if numa configured */
+#define EPYC_DIE_OFFSET 3 /* Minimum die_id offset if numa configured */
 
 /*
- * Bit offset of the node_id field
- *
- * Make sure nodes_per_pkg >  0 if numa configured else zero.
+ * Bit offset of the die_id field
  */
-static inline unsigned apicid_node_offset_epyc(X86CPUTopoInfo *topo_info)
+static inline unsigned apicid_die_offset_epyc(X86CPUTopoInfo *topo_info)
 {
-unsigned offset = apicid_die_offset(topo_info) +
-  apicid_die_width(topo_info);
+unsigned offset = apicid_core_offset(topo_info) +
+  apicid_core_width(topo_info);
 
-if (topo_info->nodes_per_pkg) {
-return MAX(NODE_ID_OFFSET, offset);
-} else {
-return offset;
-}
+return MAX(EPYC_DIE_OFFSET, offset);
 }
 
 /* Bit offset of the Pkg_ID (socket ID) field */
 static inline unsigned apicid_pkg_offset_epyc(X86CPUTopoInfo *topo_info)
 {
-return apicid_node_offset_epyc(topo_info) +
-   apicid_node_width_epyc(topo_info);
+return apicid_die_offset_epyc(topo_info) + apicid_die_width(topo_info);
 }
 
 /*
@@ -150,8 +136,7 @@ x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info,
   const X86CPUTopoIDs *topo_ids)
 {
 return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(topo_info)) |
-   (topo_ids->node_id << apicid_node_offset_epyc(topo_info)) |
-   (topo_ids->die_id  << apicid_die_offset(topo_info)) |
+   (topo_ids->die_id  << apicid_die_offset_epyc(topo_info)) |
(topo_ids->core_id << apicid_core_offset(topo_info)) |
topo_ids->smt_id;
 }
@@ -160,15 +145,11 @@ static inline void 
x86_topo_ids_from_idx_epyc(X86CPUTopoInfo *topo_info,
   unsigned cpu_index,
   X86CPUTopoIDs *topo_ids)
 {
-unsigned nr_nodes = MAX(topo_info->nodes_per_pkg, 1);
 unsigned nr_dies = topo_info->dies_per_pkg;
 unsigned nr_cores = topo_info->cores_per_die;
 unsigned nr_threads = topo_info->threads_per_core;
-unsigned cores_per_node = DIV_ROUND_UP((nr_dies * nr_cores * nr_threads),
-nr_nodes);
 
 topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_thre

[PATCH v4 0/3] Modify AMD topology to use socket/dies/core/thread model

2020-08-15 Thread Babu Moger
This series fixes couple of issues with recent topology related code.

1. Modify AMD topology to use socket/dies/core/thread model

2. Error out if the user does not pass the dies information if EPYC cpu is numa
   configured.

3. Remove the node_id references in topology and use die_id instead.

4. With node_id removed in topology the uninitialized memory issue 
   with -device and CPU hotplug will be fixed.
   Link: https://bugzilla.redhat.com/show_bug.cgi?id=1828750
---

v4:
  Not much of a change. Just added few text changes.
  Error out configuration instead of warning if dies are not configured in EPYC.
  Few other text changes to clarify the removal of node_id, nr_nodes and 
nodes_per_pkg.

v3:
  
https://lore.kernel.org/qemu-devel/159681772267.9679.1334429994189974662.st...@naples-babu.amd.com/#r
  Added a new check to pass the dies for EPYC numa configuration.
  Added Simplify CPUID_8000_001E patch with some changes suggested by Igor.
  Dropped the patch to build the topology from CpuInstanceProperties.
  TODO: Not sure if we still need the Autonuma changes Igor mentioned.
  Needs more clarity on that.

v2:
   
https://lore.kernel.org/qemu-devel/159362436285.36204.986406297373871949.st...@naples-babu.amd.com/
 - Used the numa information from CpuInstanceProperties for building
   the apic_id suggested by Igor.
 - Also did some minor code re-aarangement to take care of changes.
 - Dropped the patch "Simplify CPUID_8000_001E" from v1. Will send
   it later.

v1:
 
https://lore.kernel.org/qemu-devel/159164739269.20543.3074052993891532749.st...@naples-babu.amd.com

Babu Moger (3):
  i386: Simplify CPUID_8000_001E for AMD
  hw/i386: Update the EPYC topology to use socket/dies/core/thread model
  hw/i386: Remove node_id, nr_nodes and nodes_per_pkg from topology


 hw/i386/pc.c   |1 -
 hw/i386/x86.c  |9 -
 include/hw/i386/topology.h |   40 +---
 target/i386/cpu.c  |   86 +++-
 target/i386/cpu.h  |1 -
 5 files changed, 55 insertions(+), 82 deletions(-)

--



[PATCH v4 2/3] hw/i386: Update the EPYC topology to use socket/dies/core/thread model

2020-08-15 Thread Babu Moger
Update the EPYC topology to use socket/dies/core/thread model. The EPYC
model does not use the smp dies to build the topology. Instead, it uses
numa nodes to build the topology. Internally both are similar concept
which divides the cores on L3 boundary. Combining both into one terminology
makes it simple to program.

Add a new check to error out when smp dies are not provided when EPYC
model is numa configured. Next task is to remove node_id, nr_nodes and
nodes_per_pkg from EPYC topology which will be done in next patch.

Signed-off-by: Babu Moger 
---
 hw/i386/x86.c |8 
 1 file changed, 8 insertions(+)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 67bee1bcb8..e90c42d2fc 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -138,6 +138,14 @@ void x86_cpus_init(X86MachineState *x86ms, int 
default_cpu_version)
 
 /* Check for apicid encoding */
 if (cpu_x86_use_epyc_apic_id_encoding(ms->cpu_type)) {
+if ((ms->numa_state->num_nodes > 0) &&
+ms->numa_state->num_nodes != (ms->smp.sockets * x86ms->smp_dies)) {
+error_setg(&error_fatal, "Numa configuration here requires smp "
+   "'dies' parameter. Configure the cpu topology properly "
+   "with max_cpus = sockets * dies * cores * threads. Dies"
+   " is equivalent to number of numa nodes in a socket.");
+return;
+}
 x86_set_epyc_topo_handlers(ms);
 }
 




[PATCH 06/20] target/arm: Clean up 4-operand predicate expansion

2020-08-15 Thread Richard Henderson
Move the check for !S into do__flags, which allows to merge in
do_vecop4_p.  Split out gen_gvec_fn_ppp without sve_access_check,
to mirror gen_gvec_fn_zzz.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 111 ++---
 1 file changed, 43 insertions(+), 68 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index d310709de3..13a0194d59 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -179,31 +179,13 @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t 
word)
 }
 
 /* Invoke a vector expander on three Pregs.  */
-static bool do_vector3_p(DisasContext *s, GVecGen3Fn *gvec_fn,
- int esz, int rd, int rn, int rm)
+static void gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
+int rd, int rn, int rm)
 {
-if (sve_access_check(s)) {
-unsigned psz = pred_gvec_reg_size(s);
-gvec_fn(esz, pred_full_reg_offset(s, rd),
-pred_full_reg_offset(s, rn),
-pred_full_reg_offset(s, rm), psz, psz);
-}
-return true;
-}
-
-/* Invoke a vector operation on four Pregs.  */
-static bool do_vecop4_p(DisasContext *s, const GVecGen4 *gvec_op,
-int rd, int rn, int rm, int rg)
-{
-if (sve_access_check(s)) {
-unsigned psz = pred_gvec_reg_size(s);
-tcg_gen_gvec_4(pred_full_reg_offset(s, rd),
-   pred_full_reg_offset(s, rn),
-   pred_full_reg_offset(s, rm),
-   pred_full_reg_offset(s, rg),
-   psz, psz, gvec_op);
-}
-return true;
+unsigned psz = pred_gvec_reg_size(s);
+gvec_fn(MO_64, pred_full_reg_offset(s, rd),
+pred_full_reg_offset(s, rn),
+pred_full_reg_offset(s, rm), psz, psz);
 }
 
 /* Invoke a vector move on two Pregs.  */
@@ -1067,6 +1049,11 @@ static bool do__flags(DisasContext *s, arg_rprr_s *a,
 int mofs = pred_full_reg_offset(s, a->rm);
 int gofs = pred_full_reg_offset(s, a->pg);
 
+if (!a->s) {
+tcg_gen_gvec_4(dofs, nofs, mofs, gofs, psz, psz, gvec_op);
+return true;
+}
+
 if (psz == 8) {
 /* Do the operation and the flags generation in temps.  */
 TCGv_i64 pd = tcg_temp_new_i64();
@@ -1126,19 +1113,24 @@ static bool trans_AND_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_and_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
-if (a->s) {
-return do__flags(s, a, &op);
-} else if (a->rn == a->rm) {
-if (a->pg == a->rn) {
-return do_mov_p(s, a->rd, a->rn);
-} else {
-return do_vector3_p(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->pg);
+
+if (!a->s) {
+if (!sve_access_check(s)) {
+return true;
+}
+if (a->rn == a->rm) {
+if (a->pg == a->rn) {
+do_mov_p(s, a->rd, a->rn);
+} else {
+gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
+}
+return true;
+} else if (a->pg == a->rn || a->pg == a->rm) {
+gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
+return true;
 }
-} else if (a->pg == a->rn || a->pg == a->rm) {
-return do_vector3_p(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->rm);
-} else {
-return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
 }
+return do__flags(s, a, &op);
 }
 
 static void gen_bic_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
@@ -1162,13 +1154,14 @@ static bool trans_BIC_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_bic_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
-if (a->s) {
-return do__flags(s, a, &op);
-} else if (a->pg == a->rn) {
-return do_vector3_p(s, tcg_gen_gvec_andc, 0, a->rd, a->rn, a->rm);
-} else {
-return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
+
+if (!a->s && a->pg == a->rn) {
+if (sve_access_check(s)) {
+gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
+}
+return true;
 }
+return do__flags(s, a, &op);
 }
 
 static void gen_eor_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
@@ -1192,11 +1185,7 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_eor_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
-if (a->s) {
-return do__flags(s, a, &op);
-} else {
-return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
-}
+return do__flags(s, a, &op);
 }
 
 static void gen_sel_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
@@ -1222,11 +1211,11 @@ static bool trans_SEL_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_sel_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 6

Re: [PATCH v5 12/14] whpx: remove whpx specific functions from global includes

2020-08-15 Thread Richard Henderson
On 8/12/20 11:32 AM, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
>  accel/stubs/Makefile.objs |  1 -
>  accel/stubs/whpx-stub.c   | 47 
> ---
>  include/sysemu/whpx.h | 19 ---
>  target/i386/whpx-cpus.h   | 17 +
>  4 files changed, 17 insertions(+), 67 deletions(-)
>  delete mode 100644 accel/stubs/whpx-stub.c

Reviewed-by: Richard Henderson 


r~



  1   2   >