Re: [Qemu-devel] [PATCH] tests/docker: Test more components on the Fedora default image

2019-05-04 Thread Marcel Apfelbaum

Hi Philippe,

On 5/4/19 8:54 AM, Philippe Mathieu-Daudé wrote:

Install optional dependencies of QEMU to get better coverage.

The following components are now enabled:

   $ ./configure
   ...
   Multipath support yes
   VNC SASL support  yes
   RDMA support  yes
   PVRDMA supportyes


Appreciated!

Acked-by: Marcel Apfelbaum

Thanks,
Marcel


   libiscsi support  yes
   seccomp support   yes
   libpmem support   yes
   libudev   yes

Note: The udev-devel package is provided by systemd-devel.

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/docker/dockerfiles/fedora.docker | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/tests/docker/dockerfiles/fedora.docker 
b/tests/docker/dockerfiles/fedora.docker
index 69d4a7f5d75..afbba29adaa 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -8,6 +8,7 @@ ENV PACKAGES \
  bzip2-devel \
  ccache \
  clang \
+cyrus-sasl-devel \
  device-mapper-multipath-devel \
  findutils \
  flex \
@@ -23,13 +24,17 @@ ENV PACKAGES \
  libaio-devel \
  libasan \
  libattr-devel \
+libblockdev-mpath-devel \
  libcap-devel \
  libcap-ng-devel \
  libcurl-devel \
  libfdt-devel \
+libiscsi-devel \
  libjpeg-devel \
+libpmem-devel \
  libpng-devel \
  librbd-devel \
+libseccomp-devel \
  libssh2-devel \
  libubsan \
  libusbx-devel \
@@ -74,10 +79,12 @@ ENV PACKAGES \
  pixman-devel \
  python3 \
  PyYAML \
+rdma-core-devel \
  SDL2-devel \
  snappy-devel \
  sparse \
  spice-server-devel \
+systemd-devel \
  systemtap-sdt-devel \
  tar \
  usbredir-devel \





Re: [Qemu-devel] [PATCH] migration: don't set MIGRATION dirty range for ignored block

2019-05-04 Thread Wei Yang
On Sat, May 04, 2019 at 01:42:55PM +0800, Wei Yang wrote:
>The ignored blocks are not migrated and those ranges are not used.

My bad, this change is not correct.

>
>Signed-off-by: Wei Yang 
>---
> exec.c  | 4 +++-
> include/exec/ram_addr.h | 2 ++
> migration/ram.c | 2 +-
> 3 files changed, 6 insertions(+), 2 deletions(-)
>
>diff --git a/exec.c b/exec.c
>index 86a38d3b3b..97da155c12 100644
>--- a/exec.c
>+++ b/exec.c
>@@ -2192,6 +2192,8 @@ static void ram_block_add(RAMBlock *new_block, Error 
>**errp, bool shared)
> RAMBlock *last_block = NULL;
> ram_addr_t old_ram_size, new_ram_size;
> Error *err = NULL;
>+uint8_t dirty_memory_clients = ramblock_is_ignored(new_block) ?
>+ DIRTY_CLIENTS_NOMIG : DIRTY_CLIENTS_ALL;
> 
> old_ram_size = last_ram_page();
> 
>@@ -2252,7 +2254,7 @@ static void ram_block_add(RAMBlock *new_block, Error 
>**errp, bool shared)
> 
> cpu_physical_memory_set_dirty_range(new_block->offset,
> new_block->used_length,
>-DIRTY_CLIENTS_ALL);
>+dirty_memory_clients);
> 
> if (new_block->host) {
> qemu_ram_setup_dump(new_block->host, new_block->max_length);
>diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
>index a7c81bdb32..4765435fb8 100644
>--- a/include/exec/ram_addr.h
>+++ b/include/exec/ram_addr.h
>@@ -72,6 +72,7 @@ static inline unsigned long int 
>ramblock_recv_bitmap_offset(void *host_addr,
> }
> 
> bool ramblock_is_pmem(RAMBlock *rb);
>+bool ramblock_is_ignored(RAMBlock *rb);
> 
> long qemu_getrampagesize(void);
> 
>@@ -117,6 +118,7 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, 
>Error **errp);
> 
> #define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
> #define DIRTY_CLIENTS_NOCODE  (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
>+#define DIRTY_CLIENTS_NOMIG   (DIRTY_CLIENTS_ALL & ~(1 << 
>DIRTY_MEMORY_MIGRATION))
> 
> void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end);
> 
>diff --git a/migration/ram.c b/migration/ram.c
>index 1def8122e9..44525e3816 100644
>--- a/migration/ram.c
>+++ b/migration/ram.c
>@@ -159,7 +159,7 @@ 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));
>-- 
>2.19.1

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 14/15] tests: acpi: refactor rebuild-expected-aml.sh to dump ACPI tables for a specified list of targets

2019-05-04 Thread Wei Yang
On Thu, May 02, 2019 at 04:52:02PM +0200, Igor Mammedov wrote:
>Make initial list contain aarch64 and x86_64 targets.
>
>Signed-off-by: Igor Mammedov 
>Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Wei Yang 

>---
>v4:
> * fix typo (Wei Yang )
>v2:
> * fix up error message (Philippe Mathieu-Daudé )
>---
> tests/data/acpi/rebuild-expected-aml.sh | 23 +++
> 1 file changed, 11 insertions(+), 12 deletions(-)
>
>diff --git a/tests/data/acpi/rebuild-expected-aml.sh 
>b/tests/data/acpi/rebuild-expected-aml.sh
>index abdff70..07f7e3f 100755
>--- a/tests/data/acpi/rebuild-expected-aml.sh
>+++ b/tests/data/acpi/rebuild-expected-aml.sh
>@@ -7,21 +7,12 @@
> #
> # Authors:
> #  Marcel Apfelbaum 
>+#  Igor Mammedov 
> #
> # This work is licensed under the terms of the GNU GPLv2.
> # See the COPYING.LIB file in the top-level directory.
> 
>-qemu=
>-
>-if [ -e x86_64-softmmu/qemu-system-x86_64 ]; then
>-qemu="x86_64-softmmu/qemu-system-x86_64"
>-elif [ -e i386-softmmu/qemu-system-i386 ]; then
>-qemu="i386-softmmu/qemu-system-i386"
>-else
>-echo "Run 'make' to build the qemu exectutable!"
>-echo "Run this script from the build directory."
>-exit 1;
>-fi
>+qemu_bins="aarch64-softmmu/qemu-system-aarch64 
>x86_64-softmmu/qemu-system-x86_64"
> 
> if [ ! -e "tests/bios-tables-test" ]; then
> echo "Test: bios-tables-test is required! Run make check before this 
> script."
>@@ -29,6 +20,14 @@ if [ ! -e "tests/bios-tables-test" ]; then
> exit 1;
> fi
> 
>-TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/bios-tables-test
>+for qemu in $qemu_bins; do
>+if [ ! -e $qemu ]; then
>+echo "Run 'make' to build the following QEMU executables: $qemu_bins"
>+echo "Also, run this script from the build directory."
>+exit 1;
>+fi
>+TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/bios-tables-test
>+done
>+
> 
> echo "The files were rebuilt and can be added to git."
>-- 
>2.7.4

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 05/15] tests: acpi: fetch X_DSDT if pointer to DSDT is 0

2019-05-04 Thread Wei Yang
On Thu, May 02, 2019 at 04:51:53PM +0200, Igor Mammedov wrote:
>that way it would be possible to test a DSDT pointed by
>64bit X_DSDT field in FADT.
>
>PS:
>it will allow to enable testing arm/virt board, which sets
>only newer X_DSDT field.
>
>Signed-off-by: Igor Mammedov 
>---
>v4:
> * dropping Reviewed-bys due to acpi_fetch_table() change
>   introduced by earlier patch:
>   "tests: acpi: make acpi_fetch_table() take size of fetched table pointer"
>v2:
>  add 'val = le32_to_cpu(val)' even if it doesn't necessary
>  it works as reminder that value copied from table is in
>  little-endian format (Philippe Mathieu-Daudé )
>---
> tests/bios-tables-test.c | 11 ++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
>diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
>index a164d27..d165a1b 100644
>--- a/tests/bios-tables-test.c
>+++ b/tests/bios-tables-test.c
>@@ -140,6 +140,9 @@ static void test_acpi_fadt_table(test_data *data)
> AcpiSdtTable table = g_array_index(data->tables, typeof(table), 0);
> uint8_t *fadt_aml = table.aml;
> uint32_t fadt_len = table.aml_len;
>+uint32_t val;
>+int dsdt_offset = 40 /* DSDT */;
>+int dsdt_entry_size = 4;
> 
> g_assert(compare_signature(, "FACP"));
> 
>@@ -148,8 +151,14 @@ static void test_acpi_fadt_table(test_data *data)
>  fadt_aml + 36 /* FIRMWARE_CTRL */, 4, "FACS", false);
> g_array_append_val(data->tables, table);
> 
>+memcpy(, fadt_aml + dsdt_offset, 4);
>+val = le32_to_cpu(val);
>+if (!val) {
>+dsdt_offset = 140 /* X_DSDT */;

In case we can point out where we get it, e.g. ACPI 5, Table 5-34 FADT Format.

This may be more helpful for reviewing and maintaining.

Do you think so?

>+dsdt_entry_size = 8;
>+}
> acpi_fetch_table(data->qts, , _len,
>- fadt_aml + 40 /* DSDT */, 4, "DSDT", true);
>+ fadt_aml + dsdt_offset, dsdt_entry_size, "DSDT", true);
> g_array_append_val(data->tables, table);
> 
> memset(fadt_aml + 36, 0, 4); /* sanitize FIRMWARE_CTRL ptr */
>-- 
>2.7.4

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 04/15] tests: acpi: make pointer to RSDP 64bit

2019-05-04 Thread Wei Yang
On Thu, May 02, 2019 at 04:51:52PM +0200, Igor Mammedov wrote:
>In case of UEFI, RSDP doesn't have to be located in lowmem,
>it could be placed at any address. Make sure that test won't
>break if it is placed above the first 4Gb of address space.
>
>PS:
>While at it cleanup some local variables as we don't really
>need them.
>
>Signed-off-by: Igor Mammedov 
>Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Wei Yang 

>---
>v4:
> - move acpi_fetch_rsdp_table(s/uint32_t addr/uint64_t addr/) to
>   this patch where it belongs from
>   "tests: acpi: make RSDT test routine handle XSDT"
>   (Wei Yang )
>v2:
>  - s/In case of UEFI/In case of UEFI,/ (Laszlo Ersek )
>---
> tests/acpi-utils.h   |  2 +-
> tests/acpi-utils.c   |  2 +-
> tests/bios-tables-test.c | 10 --
> 3 files changed, 6 insertions(+), 8 deletions(-)
>
>diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h
>index f55ccf9..1da6c10 100644
>--- a/tests/acpi-utils.h
>+++ b/tests/acpi-utils.h
>@@ -46,7 +46,7 @@ typedef struct {
> 
> uint8_t acpi_calc_checksum(const uint8_t *data, int len);
> uint32_t acpi_find_rsdp_address(QTestState *qts);
>-void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, uint8_t 
>*rsdp_table);
>+void acpi_fetch_rsdp_table(QTestState *qts, uint64_t addr, uint8_t 
>*rsdp_table);
> void acpi_fetch_table(QTestState *qts, uint8_t **aml, uint32_t *aml_len,
>   const uint8_t *addr_ptr, int addr_size, const char *sig,
>   bool verify_checksum);
>diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c
>index a0d49c4..c216b9e 100644
>--- a/tests/acpi-utils.c
>+++ b/tests/acpi-utils.c
>@@ -51,7 +51,7 @@ uint32_t acpi_find_rsdp_address(QTestState *qts)
> return off;
> }
> 
>-void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, uint8_t 
>*rsdp_table)
>+void acpi_fetch_rsdp_table(QTestState *qts, uint64_t addr, uint8_t 
>*rsdp_table)
> {
> uint8_t revision;
> 
>diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
>index d6ab121..a164d27 100644
>--- a/tests/bios-tables-test.c
>+++ b/tests/bios-tables-test.c
>@@ -26,7 +26,7 @@
> typedef struct {
> const char *machine;
> const char *variant;
>-uint32_t rsdp_addr;
>+uint64_t rsdp_addr;
> uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
> GArray *tables;
> uint32_t smbios_ep_addr;
>@@ -86,13 +86,11 @@ static void test_acpi_rsdp_address(test_data *data)
> 
> static void test_acpi_rsdp_table(test_data *data)
> {
>-uint8_t *rsdp_table = data->rsdp_table, revision;
>-uint32_t addr = data->rsdp_addr;
>+uint8_t *rsdp_table = data->rsdp_table;
> 
>-acpi_fetch_rsdp_table(data->qts, addr, rsdp_table);
>-revision = rsdp_table[15 /* Revision offset */];
>+acpi_fetch_rsdp_table(data->qts, data->rsdp_addr, rsdp_table);
> 
>-switch (revision) {
>+switch (rsdp_table[15 /* Revision offset */]) {
> case 0: /* ACPI 1.0 RSDP */
> /* With rev 1, checksum is only for the first 20 bytes */
> g_assert(!acpi_calc_checksum(rsdp_table,  20));
>-- 
>2.7.4

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 03/15] tests: acpi: make RSDT test routine handle XSDT

2019-05-04 Thread Wei Yang
On Thu, May 02, 2019 at 04:51:51PM +0200, Igor Mammedov wrote:
>If RSDP revision is more than 0 fetch table pointed by XSDT
>and fallback to legacy RSDT table otherwise.
>
>While at it drop unused acpi_get_xsdt_address().
>
>Signed-off-by: Igor Mammedov 

Reviewed-by: Wei Yang 

>---
>PS:
> it doesn't affect existing pc/q35 machines as they use RSDP.revision == 0
> but it will be used by followup patch to enable testing arm/virt
> board which uses provides XSDT table.
>
>v4:
> * move out acpi_parse_rsdp_table() hunk to
>   "tests: acpi: make pointer to RSDP  64bit"
>   where it belongs
>---
> tests/acpi-utils.h   |  1 -
> tests/acpi-utils.c   | 12 
> tests/bios-tables-test.c | 20 ++--
> 3 files changed, 14 insertions(+), 19 deletions(-)
>
>diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h
>index 92285b7..f55ccf9 100644
>--- a/tests/acpi-utils.h
>+++ b/tests/acpi-utils.h
>@@ -46,7 +46,6 @@ typedef struct {
> 
> uint8_t acpi_calc_checksum(const uint8_t *data, int len);
> uint32_t acpi_find_rsdp_address(QTestState *qts);
>-uint64_t acpi_get_xsdt_address(uint8_t *rsdp_table);
> void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, uint8_t 
> *rsdp_table);
> void acpi_fetch_table(QTestState *qts, uint8_t **aml, uint32_t *aml_len,
>   const uint8_t *addr_ptr, int addr_size, const char *sig,
>diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c
>index 644c87b..a0d49c4 100644
>--- a/tests/acpi-utils.c
>+++ b/tests/acpi-utils.c
>@@ -51,18 +51,6 @@ uint32_t acpi_find_rsdp_address(QTestState *qts)
> return off;
> }
> 
>-uint64_t acpi_get_xsdt_address(uint8_t *rsdp_table)
>-{
>-uint64_t xsdt_physical_address;
>-uint8_t revision = rsdp_table[15 /* Revision offset */];
>-
>-/* We must have revision 2 if we're looking for an XSDT pointer */
>-g_assert(revision == 2);
>-
>-memcpy(_physical_address, _table[24 /* XsdtAddress offset */], 
>8);
>-return le64_to_cpu(xsdt_physical_address);
>-}
>-
> void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, uint8_t 
> *rsdp_table)
> {
> uint8_t revision;
>diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
>index 86b592c..d6ab121 100644
>--- a/tests/bios-tables-test.c
>+++ b/tests/bios-tables-test.c
>@@ -107,21 +107,29 @@ static void test_acpi_rsdp_table(test_data *data)
> }
> }
> 
>-static void test_acpi_rsdt_table(test_data *data)
>+static void test_acpi_rxsdt_table(test_data *data)
> {
>+const char *sig = "RSDT";
> AcpiSdtTable rsdt = {};
>+int entry_size = 4;
>+int addr_off = 16 /* RsdtAddress */;
> uint8_t *ent;
> 
>-/* read RSDT table */
>+if (data->rsdp_table[15 /* Revision offset */] != 0) {
>+addr_off = 24 /* XsdtAddress */;
>+entry_size = 8;
>+sig = "XSDT";
>+}
>+/* read [RX]SDT table */
> acpi_fetch_table(data->qts, , _len,
>- >rsdp_table[16 /* RsdtAddress */], 4, "RSDT", 
>true);
>+ >rsdp_table[addr_off], entry_size, sig, true);
> 
> /* Load all tables and add to test list directly RSDT referenced tables */
>-ACPI_FOREACH_RSDT_ENTRY(rsdt.aml, rsdt.aml_len, ent, 4 /* Entry size */) {
>+ACPI_FOREACH_RSDT_ENTRY(rsdt.aml, rsdt.aml_len, ent, entry_size) {
> AcpiSdtTable ssdt_table = {};
> 
> acpi_fetch_table(data->qts, _table.aml, _table.aml_len, ent,
>- 4, NULL, true);
>+ entry_size, NULL, true);
> /* Add table to ASL test tables list */
> g_array_append_val(data->tables, ssdt_table);
> }
>@@ -521,7 +529,7 @@ static void test_acpi_one(const char *params, test_data 
>*data)
> data->tables = g_array_new(false, true, sizeof(AcpiSdtTable));
> test_acpi_rsdp_address(data);
> test_acpi_rsdp_table(data);
>-test_acpi_rsdt_table(data);
>+test_acpi_rxsdt_table(data);
> test_acpi_fadt_table(data);
> 
> if (iasl) {
>-- 
>2.7.4

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 02/15] tests: acpi: make acpi_fetch_table() take size of fetched table pointer

2019-05-04 Thread Wei Yang
On Thu, May 02, 2019 at 04:51:50PM +0200, Igor Mammedov wrote:
>Currently acpi_fetch_table() assumes 32 bit size of table pointer
>in ACPI tables. However X_foo variants are 64 bit, prepare
>acpi_fetch_table() to handle both by adding an argument
>for addr_ptr pointed entry size. Follow up commits will use that
>to read XSDT and X_foo entries in ACPI tables.
>
>Signed-off-by: Igor Mammedov 

Reviewed-by: Wei Yang 

>---
> tests/acpi-utils.h   |  2 +-
> tests/acpi-utils.c   | 10 ++
> tests/bios-tables-test.c |  8 
> tests/vmgenid-test.c |  4 ++--
> 4 files changed, 13 insertions(+), 11 deletions(-)
>
>diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h
>index 4cd5553..92285b7 100644
>--- a/tests/acpi-utils.h
>+++ b/tests/acpi-utils.h
>@@ -49,7 +49,7 @@ uint32_t acpi_find_rsdp_address(QTestState *qts);
> uint64_t acpi_get_xsdt_address(uint8_t *rsdp_table);
> void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, uint8_t 
> *rsdp_table);
> void acpi_fetch_table(QTestState *qts, uint8_t **aml, uint32_t *aml_len,
>-  const uint8_t *addr_ptr, const char *sig,
>+  const uint8_t *addr_ptr, int addr_size, const char *sig,
>   bool verify_checksum);
> 
> #endif  /* TEST_ACPI_UTILS_H */
>diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c
>index 633d8f5..644c87b 100644
>--- a/tests/acpi-utils.c
>+++ b/tests/acpi-utils.c
>@@ -91,13 +91,15 @@ void acpi_fetch_rsdp_table(QTestState *qts, uint32_t addr, 
>uint8_t *rsdp_table)
>  *  actual one.
>  */
> void acpi_fetch_table(QTestState *qts, uint8_t **aml, uint32_t *aml_len,
>-  const uint8_t *addr_ptr, const char *sig,
>+  const uint8_t *addr_ptr, int addr_size, const char *sig,
>   bool verify_checksum)
> {
>-uint32_t addr, len;
>+uint32_t len;
>+uint64_t addr = 0;
> 
>-memcpy(, addr_ptr , sizeof(addr));
>-addr = le32_to_cpu(addr);
>+g_assert(addr_size == 4 || addr_size == 8);
>+memcpy(, addr_ptr , addr_size);
>+addr = le64_to_cpu(addr);
> qtest_memread(qts, addr + 4, , 4); /* Length of ACPI table */
> *aml_len = le32_to_cpu(len);
> *aml = g_malloc0(*aml_len);
>diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
>index 6a678bf..86b592c 100644
>--- a/tests/bios-tables-test.c
>+++ b/tests/bios-tables-test.c
>@@ -114,14 +114,14 @@ static void test_acpi_rsdt_table(test_data *data)
> 
> /* read RSDT table */
> acpi_fetch_table(data->qts, , _len,
>- >rsdp_table[16 /* RsdtAddress */], "RSDT", true);
>+ >rsdp_table[16 /* RsdtAddress */], 4, "RSDT", 
>true);
> 
> /* Load all tables and add to test list directly RSDT referenced tables */
> ACPI_FOREACH_RSDT_ENTRY(rsdt.aml, rsdt.aml_len, ent, 4 /* Entry size */) {
> AcpiSdtTable ssdt_table = {};
> 
> acpi_fetch_table(data->qts, _table.aml, _table.aml_len, ent,
>- NULL, true);
>+ 4, NULL, true);
> /* Add table to ASL test tables list */
> g_array_append_val(data->tables, ssdt_table);
> }
>@@ -139,11 +139,11 @@ static void test_acpi_fadt_table(test_data *data)
> 
> /* Since DSDT/FACS isn't in RSDT, add them to ASL test list manually */
> acpi_fetch_table(data->qts, , _len,
>- fadt_aml + 36 /* FIRMWARE_CTRL */, "FACS", false);
>+ fadt_aml + 36 /* FIRMWARE_CTRL */, 4, "FACS", false);
> g_array_append_val(data->tables, table);
> 
> acpi_fetch_table(data->qts, , _len,
>- fadt_aml + 40 /* DSDT */, "DSDT", true);
>+ fadt_aml + 40 /* DSDT */, 4, "DSDT", true);
> g_array_append_val(data->tables, table);
> 
> memset(fadt_aml + 36, 0, 4); /* sanitize FIRMWARE_CTRL ptr */
>diff --git a/tests/vmgenid-test.c b/tests/vmgenid-test.c
>index f400184..85d8e64 100644
>--- a/tests/vmgenid-test.c
>+++ b/tests/vmgenid-test.c
>@@ -42,12 +42,12 @@ static uint32_t acpi_find_vgia(QTestState *qts)
> 
> acpi_fetch_rsdp_table(qts, rsdp_offset, rsdp_table);
> acpi_fetch_table(qts, , _len, _table[16 /* RsdtAddress */],
>- "RSDT", true);
>+ 4, "RSDT", true);
> 
> ACPI_FOREACH_RSDT_ENTRY(rsdt, rsdt_len, ent, 4 /* Entry size */) {
> uint8_t *table_aml;
> 
>-acpi_fetch_table(qts, _aml, _length, ent, NULL, true);
>+acpi_fetch_table(qts, _aml, _length, ent, 4, NULL, true);
> if (!memcmp(table_aml + 16 /* OEM Table ID */, "VMGENID", 7)) {
> uint32_t vgia_val;
> uint8_t *aml = _aml[36 /* AML byte-code start */];
>-- 
>2.7.4

-- 
Wei Yang
Help you, Help me



[Qemu-devel] [PATCH v2 3/3] hw/isa/i82378.c: use 1900 as a base year

2019-05-04 Thread Artyom Tarasenko
AIX 5.1 expects the base year to be 1900. Adjust accordingly.

Signed-off-by: Artyom Tarasenko 
Reviewed-by: Hervé Poussineau 
---
 hw/isa/i82378.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index a5d67bc..546c928 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -107,7 +107,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
 isa = isa_create_simple(isabus, "i82374");
 
 /* timer */
-isa_create_simple(isabus, TYPE_MC146818_RTC);
+isa = isa_create(isabus, TYPE_MC146818_RTC);
+qdev_prop_set_int32(DEVICE(isa), "base_year", 1900);
+qdev_init_nofail(DEVICE(isa));
 }
 
 static void i82378_init(Object *obj)
-- 
2.7.2




[Qemu-devel] [PATCH v2 0/3] Improve 40p, make AIX 5.1 boot

2019-05-04 Thread Artyom Tarasenko


This series makes various fixes for the -M 40p target.
Particularly now it's possible to boot AIX 5.1 (both from a cdrom
and a hard disk).

The OFW image: 
https://github.com/artyom-tarasenko/openfirmware/releases/download/20190406-AIX-boots/q40pofw-serial.rom

The command line:
qemu-system-ppc -M 40p -bios q40pofw-serial.rom -serial telnet::4441,server 
-hda aix-hdd.qcow2 -cdrom \
/path/to/aix-5.1-cd1.iso  -vga none -nographic

More info can be found here:
https://tyom.blogspot.com/2019/04/aixprep-under-qemu-how-to.html

Artyom Tarasenko (3):
  lsi53c895a: hide 53c895a registers in 53c810
  40p and prep: implement PCI bus mastering
  hw/isa/i82378.c: use 1900 as a base year

 hw/isa/i82378.c  |  4 +++-
 hw/pci-host/prep.c   | 15 +++
 hw/scsi/lsi53c895a.c | 17 ++---
 3 files changed, 28 insertions(+), 8 deletions(-)

-- 
2.7.2




[Qemu-devel] [PATCH v2 1/3] lsi53c895a: hide 53c895a registers in 53c810

2019-05-04 Thread Artyom Tarasenko
AIX/PReP does access to the aliased IO registers of 53810.
Implement aliasing to make the AIX driver work.

Signed-off-by: Artyom Tarasenko 
---
 hw/scsi/lsi53c895a.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index da7239d..6b95699 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2271,6 +2271,9 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
 LSIState *s = LSI53C895A(dev);
 DeviceState *d = DEVICE(dev);
 uint8_t *pci_conf;
+uint64_t mmio_size;
+MemoryRegion *mr;
+uint16_t type = PCI_DEVICE_GET_CLASS(dev)->device_id;
 
 pci_conf = dev->config;
 
@@ -2279,13 +2282,21 @@ static void lsi_scsi_realize(PCIDevice *dev, Error 
**errp)
 /* Interrupt pin A */
 pci_conf[PCI_INTERRUPT_PIN] = 0x01;
 
-memory_region_init_io(>mmio_io, OBJECT(s), _mmio_ops, s,
-  "lsi-mmio", 0x400);
 memory_region_init_io(>ram_io, OBJECT(s), _ram_ops, s,
   "lsi-ram", 0x2000);
 memory_region_init_io(>io_io, OBJECT(s), _io_ops, s,
   "lsi-io", 256);
-
+if (type == PCI_DEVICE_ID_LSI_53C895A) {
+mmio_size = 0x400;
+} else {
+mr = g_new(MemoryRegion, 1);
+memory_region_init_alias(mr, OBJECT(d), "lsi-io-alias", >io_io,
+ 0, 0x80);
+memory_region_add_subregion_overlap(>io_io, 0x80, mr, -1);
+mmio_size = 0x80;
+}
+memory_region_init_io(>mmio_io, OBJECT(s), _mmio_ops, s,
+  "lsi-mmio", mmio_size);
 address_space_init(>pci_io_as, pci_address_space_io(dev), "lsi-pci-io");
 qdev_init_gpio_out(d, >ext_irq, 1);
 
-- 
2.7.2




[Qemu-devel] [PATCH 2/3] 40p and prep: implement PCI bus mastering

2019-05-04 Thread Artyom Tarasenko
Signed-off-by: Artyom Tarasenko 
Reviewed-by: Hervé Poussineau 
---
 hw/pci-host/prep.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 8b9e1fd..94b7465 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -62,6 +62,7 @@ typedef struct PRePPCIState {
 AddressSpace pci_io_as;
 MemoryRegion pci_io;
 MemoryRegion pci_io_non_contiguous;
+MemoryRegion pci_io_system;
 MemoryRegion pci_memory;
 MemoryRegion pci_intack;
 MemoryRegion bm;
@@ -146,7 +147,7 @@ static uint64_t raven_io_read(void *opaque, hwaddr addr,
 uint8_t buf[4];
 
 addr = raven_io_address(s, addr);
-address_space_read(>pci_io_as, addr + 0x8000,
+address_space_read(>pci_io_as, addr,
MEMTXATTRS_UNSPECIFIED, buf, size);
 
 if (size == 1) {
@@ -178,7 +179,7 @@ static void raven_io_write(void *opaque, hwaddr addr,
 g_assert_not_reached();
 }
 
-address_space_write(>pci_io_as, addr + 0x8000,
+address_space_write(>pci_io_as, addr,
 MEMTXATTRS_UNSPECIFIED, buf, size);
 }
 
@@ -276,14 +277,21 @@ static void raven_pcihost_initfn(Object *obj)
 MemoryRegion *address_space_mem = get_system_memory();
 DeviceState *pci_dev;
 
-memory_region_init(>pci_io, obj, "pci-io", 0x3f80);
+memory_region_init(>pci_io, obj, "pci-io", UINT32_MAX);
 memory_region_init_io(>pci_io_non_contiguous, obj, _io_ops, s,
   "pci-io-non-contiguous", 0x0080);
 memory_region_init(>pci_memory, obj, "pci-memory", 0x3f00);
 address_space_init(>pci_io_as, >pci_io, "raven-io");
 
 /* CPU address space */
-memory_region_add_subregion(address_space_mem, 0x8000, >pci_io);
+memory_region_add_subregion_overlap(address_space_mem, 0x0,
+>pci_io, -1);
+
+memory_region_init_alias(>pci_io_system,  obj, "pci-io-system",
+ >pci_io, 0x000, 0x3f80);
+
+memory_region_add_subregion(address_space_mem, 0x8000,
+>pci_io_system);
 memory_region_add_subregion_overlap(address_space_mem, 0x8000,
 >pci_io_non_contiguous, 1);
 memory_region_add_subregion(address_space_mem, 0xc000, >pci_memory);
-- 
2.7.2




[Qemu-devel] [PATCH v2] chardev/char-i2c: Implement Linux I2C character device

2019-05-04 Thread Ernest Esene
Add support for Linux I2C character device for I2C device passthrough
For example:
-chardev linux-i2c,address=0x46,path=/dev/i2c-N,id=i2c-chardev

Signed-off-by: Ernest Esene 

---
v2:
  * Fix errors
  * update "MAINTAINERS" file.
---
 MAINTAINERS|   6 ++
 chardev/Makefile.objs  |   1 +
 chardev/char-i2c.c | 140 +
 chardev/char.c |   3 +
 include/chardev/char-i2c.h |  35 
 include/chardev/char.h |   1 +
 qapi/char.json |  18 ++
 7 files changed, 204 insertions(+)
 create mode 100644 chardev/char-i2c.c
 create mode 100644 include/chardev/char-i2c.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7dd71e0a2d..b79d9b8edf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1801,6 +1801,12 @@ M: Samuel Thibault 
 S: Maintained
 F: chardev/baum.c
 
+Character Devices (Linux I2C)
+M: Ernest Esene 
+S: Maintained
+F: chardev/char-i2c.c
+F: include/chardev/char-i2c.h
+
 Command line option argument parsing
 M: Markus Armbruster 
 S: Supported
diff --git a/chardev/Makefile.objs b/chardev/Makefile.objs
index d68e1347f9..6c96b9a353 100644
--- a/chardev/Makefile.objs
+++ b/chardev/Makefile.objs
@@ -16,6 +16,7 @@ chardev-obj-y += char-stdio.o
 chardev-obj-y += char-udp.o
 chardev-obj-$(CONFIG_WIN32) += char-win.o
 chardev-obj-$(CONFIG_WIN32) += char-win-stdio.o
+chardev-obj-$(CONFIG_POSIX) +=char-i2c.o
 
 common-obj-y += msmouse.o wctablet.o testdev.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
diff --git a/chardev/char-i2c.c b/chardev/char-i2c.c
new file mode 100644
index 00..4b068b0124
--- /dev/null
+++ b/chardev/char-i2c.c
@@ -0,0 +1,140 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2019 Ernest Esene 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/option.h"
+#include "qemu-common.h"
+#include "io/channel-file.h"
+#include "qemu/cutils.h"
+
+#include "chardev/char-fd.h"
+#include "chardev/char-i2c.h"
+#include "chardev/char.h"
+
+#include 
+#include 
+
+static int i2c_ioctl(Chardev *chr, int cmd, void *arg)
+{
+FDChardev *fd_chr = FD_CHARDEV(chr);
+QIOChannelFile *floc = QIO_CHANNEL_FILE(fd_chr->ioc_in);
+int fd = floc->fd;
+int addr;
+
+switch (cmd) {
+case CHR_IOCTL_I2C_SET_ADDR:
+addr = (int) (long) arg;
+
+if (addr > CHR_I2C_ADDR_7BIT_MAX) {
+/*
+ * TODO: check if adapter support 10-bit addr
+ * I2C_FUNC_10BIT_ADDR
+ */
+if (ioctl(fd, I2C_TENBIT, addr) < 0) {
+goto err;
+}
+} else {
+if (ioctl(fd, I2C_SLAVE, addr) < 0) {
+goto err;
+}
+}
+break;
+
+default:
+return -ENOTSUP;
+}
+return 0;
+err:
+return -ENOTSUP;
+}
+
+static void qmp_chardev_open_i2c(Chardev *chr, ChardevBackend *backend,
+ bool *be_opened, Error **errp)
+{
+ChardevI2c *i2c = backend->u.i2c.data;
+void *addr;
+int fd;
+
+fd = qmp_chardev_open_file_source(i2c->device, O_RDWR | O_NONBLOCK,
+  errp);
+if (fd < 0) {
+return;
+}
+qemu_set_block(fd);
+qemu_chr_open_fd(chr, fd, fd);
+addr = (void *) (long) i2c->address;
+i2c_ioctl(chr, CHR_IOCTL_I2C_SET_ADDR, addr);
+}
+
+static void qemu_chr_parse_i2c(QemuOpts *opts, ChardevBackend *backend,
+   Error **errp)
+{
+const char *device = qemu_opt_get(opts, "path");
+const char *addr = qemu_opt_get(opts, "address");
+long address;
+ChardevI2c *i2c;
+if (device == NULL) {
+error_setg(errp, "chardev: linux-i2c: no device path given");
+return;
+}
+if (addr == NULL) {
+error_setg(errp, "chardev: linux-i2c: no device address given");
+return;
+}
+if (qemu_strtol(addr, NULL, 0, 

[Qemu-devel] [Bug 1825359] Re: cpu_ld*_code() triggers MMU_DATA_LOAD i.s.o. MMU_INST_FETCH

2019-05-04 Thread Shahab Vahedi
Thank YOU for all the supports along the way :)

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

Title:
  cpu_ld*_code() triggers MMU_DATA_LOAD i.s.o. MMU_INST_FETCH

Status in QEMU:
  Fix Committed

Bug description:
  commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5
  Merge: c876180938 328eb60dc1
  Author: Peter Maydell ; masked for anti-spamming purposes
  Date:   Mon Mar 11 18:26:37 2019 +
  https://github.com/qemu/qemu/commit/377b155bde451d5ac545fbdcdfbf6ca17a4228f5
  --

  cpu_ld*_code() is used for loading code data as the name suggests. Although, 
it begins accessing memory with MMU_INST_FETCH access type, somewhere down
  the road, when the "io_readx(..., access_type=MMU_INST_FETCH, ...)" is
  called, it is ignoring this "access_type" while calling the "tlb_fill()"
  with a _hardcoded_ MMU_DATA_LOAD:

  cputlb.c
  
  static uint64_t io_readx(..., MMUAccessType access_type, ...)
  {

  if (recheck) {
  CPUTLBEntry *entry;
  target_ulong tlb_addr;

  tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
  ...
  }
  

  This is an issue, because there can exist _small_ regions of memory (smaller
  than the TARGET_PAGE_SIZE) that are only executable and not readable.

  TL;DR

  What happens is at first, a "tlb_fill(..., access_type=MMU_INST_FETCH, ...)"
  is triggered by "tb_lookup_cpu_state()". To be precise, this is the call
  stack which is good behavior:
  ---
  #0  tlb_fill (cs=..., vaddr=684, size=0, access_type=MMU_INST_FETCH, 
mmu_idx=0, retaddr=0) at target/arc/mmu.c:602
  #1  get_page_addr_code (env=..., addr=684) at accel/tcg/cputlb.c:1045
  #2  tb_htable_lookup (cpu=..., pc=684, cs_base=0, flags=0, 
cf_mask=4278190080) at accel/tcg/cpu-exec.c:337
  #3  tb_lookup__cpu_state (cpu=..., pc=..., cs_base=..., flags=..., 
cf_mask=4278190080) at include/exec/tb-lookup.h:43
  #4  tb_find (cpu=..., last_tb=... , tb_exit=0, 
cf_mask=0) at accel/tcg/cpu-exec.c:404
  #5  cpu_exec (cpu=...) at accel/tcg/cpu-exec.c:729
  #6  tcg_cpu_exec (cpu=...) at cpus.c:1430
  #7  qemu_tcg_rr_cpu_thread_fn (arg=...) at cpus.c:1531
  #8  qemu_thread_start (args=...) at util/qemu-thread-posix.c:502
  ---

  After this call, TLB is filled with an entry that its size field is small,
  say 32 bytes. This causes a TLB_RECHECK for consequent memory accesses, which 
  is logical. However, in our decoder, we use cpu_lduw_code() to read the
  instructions and decode them. As mentioned, in the beginning, the
  access_type=MMU_INST_FETCH is lost in "io_readx()" while calling tlb_fill()",
  and now THIS CAUSES A GUEST EXCEPTION BECAUSE THAT REGION IS NOT ALLOWED TO
  BE READ. Here, comes that trace call of the _bad_ behavior:
  ---
  #0  tlb_fill (..., access_type=MMU_DATA_LOAD, ...) at target/arc/mmu.c:605
  #1  io_readx (..., access_type=MMU_INST_FETCH, size=2) at 
accel/tcg/cputlb.c:881
  #2  io_readw (..., access_type=MMU_INST_FETCH) at 
accel/tcg/softmmu_template.h:106
  #3  helper_le_ldw_cmmu (..., oi=16, retaddr=0) at 
accel/tcg/softmmu_template.h:146
  #4  cpu_lduw_code_ra (env=..., ptr=684, retaddr=0) at 
include/exec/cpu_ldst_template.h:102
  #5  cpu_lduw_code (env=..., ptr=684) at include/exec/cpu_ldst_template.h:114
  #6  read_and_decode_context (ctx=..., opcode_p=...) at 
target/arc/arc-decoder.c:1479
  #7  arc_decode (ctx=...) at target/arc/arc-decoder.c:1736
  #8  decode_opc (env=..., ctx=...) at target/arc/translate.c:313
  #9  arc_tr_translate_insn (dcbase=..., cpu=...) at target/arc/translate.c:335
  #10 translator_loop (.. ) at accel/tcg/translator.c:107
  #11 gen_intermediate_code (cpu=..., tb=... ) at 
target/arc/translate.c:413
  #12 tb_gen_code (cpu=..., pc=684, cs_base=0, flags=0, cflags=-16711679) at 
accel/tcg/translate-all.c:1723
  #13 tb_find (cpu=..., last_tb=... , tb_exit=0, 
cf_mask=0) at accel/tcg/cpu-exec.c:407
  #14 cpu_exec (cpu=...) at accel/tcg/cpu-exec.c:729
  #15 tcg_cpu_exec (cpu=...) at cpus.c:1430

  ---

  Do you confirm if this is an issue? Maybe there are other ways to read
  an instruction with MMU_INST_FETCH access that I don't know about.

  Last but not least, although this is not a security issue for QEMU per
  se, but it is hindering a security feature for the guest.

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



Re: [Qemu-devel] [PATCH] hw/net/ne2000: Extract the PCI device from the chipset common code

2019-05-04 Thread Philippe Mathieu-Daudé
On 5/4/19 4:09 PM, Thomas Huth wrote:
> On 04/05/2019 14.35, Philippe Mathieu-Daudé wrote:
>> The ne2000.c file contains functions common the the ISA and PCI
>> devices. To allow to build with one or another, extract the PCI
>> specific part into a new file.
>>
>> This fix an issue where the NE2000_ISA Kconfig had to pull the
>> full PCI core objects.
>>
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  hw/net/Kconfig   |   7 ++-
>>  hw/net/Makefile.objs |   3 +-
>>  hw/net/ne2000-pci.c  | 132 +++
>>  hw/net/ne2000.c  | 105 --
>>  4 files changed, 139 insertions(+), 108 deletions(-)
>>  create mode 100644 hw/net/ne2000-pci.c
>>
>> diff --git a/hw/net/Kconfig b/hw/net/Kconfig
>> index 7d7bbc5d7c9..4ef86dc3a53 100644
>> --- a/hw/net/Kconfig
>> +++ b/hw/net/Kconfig
>> @@ -1,10 +1,14 @@
>>  config DP8393X
>>  bool
>>  
>> +config NE2000_COMMON
>> +bool
> 
> I'd maybe rather simply name it "NE2000" instead of "NE2000_COMMON", but
> that's just a matter of taste.

I started using this name, but then realized it is confuse and someone
could enable CONFIG_NE2000=y expecting a network device, but none would
be linked.

Paolo, would it be useful to add some 'internal' Kconfig property (like
"default")? So that config is not user-selectable, but only
dependency-selectable. CONFIG_ARM_V7M might be a similar example (we
don't want the user to unselect it).

> 
> Reviewed-by: Thomas Huth 

Thanks!



Re: [Qemu-devel] [PATCH] hw/net/ne2000: Extract the PCI device from the chipset common code

2019-05-04 Thread Thomas Huth
On 04/05/2019 14.35, Philippe Mathieu-Daudé wrote:
> The ne2000.c file contains functions common the the ISA and PCI
> devices. To allow to build with one or another, extract the PCI
> specific part into a new file.
> 
> This fix an issue where the NE2000_ISA Kconfig had to pull the
> full PCI core objects.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/net/Kconfig   |   7 ++-
>  hw/net/Makefile.objs |   3 +-
>  hw/net/ne2000-pci.c  | 132 +++
>  hw/net/ne2000.c  | 105 --
>  4 files changed, 139 insertions(+), 108 deletions(-)
>  create mode 100644 hw/net/ne2000-pci.c
> 
> diff --git a/hw/net/Kconfig b/hw/net/Kconfig
> index 7d7bbc5d7c9..4ef86dc3a53 100644
> --- a/hw/net/Kconfig
> +++ b/hw/net/Kconfig
> @@ -1,10 +1,14 @@
>  config DP8393X
>  bool
>  
> +config NE2000_COMMON
> +bool

I'd maybe rather simply name it "NE2000" instead of "NE2000_COMMON", but
that's just a matter of taste.

Reviewed-by: Thomas Huth 



[Qemu-devel] [PATCH PULL 4/4] hw/pvrdma: Add support for SRQ

2019-05-04 Thread Marcel Apfelbaum
From: Kamal Heib 

Implement the pvrdma device commands for supporting SRQ

Signed-off-by: Kamal Heib 
Message-Id: <20190403113343.26384-5-kamalhe...@gmail.com>
Reviewed-by: Yuval Shaia 
Signed-off-by: Marcel Apfelbaum 
---
 hw/rdma/vmw/pvrdma_cmd.c| 147 
 hw/rdma/vmw/pvrdma_main.c   |  16 
 hw/rdma/vmw/pvrdma_qp_ops.c |  46 ++-
 hw/rdma/vmw/pvrdma_qp_ops.h |   1 +
 4 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index b931bb6dc9..8d70c0d23d 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -609,6 +609,149 @@ static int destroy_uc(PVRDMADev *dev, union 
pvrdma_cmd_req *req,
 return 0;
 }
 
+static int create_srq_ring(PCIDevice *pci_dev, PvrdmaRing **ring,
+   uint64_t pdir_dma, uint32_t max_wr,
+   uint32_t max_sge, uint32_t nchunks)
+{
+uint64_t *dir = NULL, *tbl = NULL;
+PvrdmaRing *r;
+int rc = -EINVAL;
+char ring_name[MAX_RING_NAME_SZ];
+uint32_t wqe_sz;
+
+if (!nchunks || nchunks > PVRDMA_MAX_FAST_REG_PAGES) {
+rdma_error_report("Got invalid page count for SRQ ring: %d",
+  nchunks);
+return rc;
+}
+
+dir = rdma_pci_dma_map(pci_dev, pdir_dma, TARGET_PAGE_SIZE);
+if (!dir) {
+rdma_error_report("Failed to map to SRQ page directory");
+goto out;
+}
+
+tbl = rdma_pci_dma_map(pci_dev, dir[0], TARGET_PAGE_SIZE);
+if (!tbl) {
+rdma_error_report("Failed to map to SRQ page table");
+goto out;
+}
+
+r = g_malloc(sizeof(*r));
+*ring = r;
+
+r->ring_state = (struct pvrdma_ring *)
+rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
+if (!r->ring_state) {
+rdma_error_report("Failed to map tp SRQ ring state");
+goto out_free_ring_mem;
+}
+
+wqe_sz = pow2ceil(sizeof(struct pvrdma_rq_wqe_hdr) +
+  sizeof(struct pvrdma_sge) * max_sge - 1);
+sprintf(ring_name, "srq_ring_%" PRIx64, pdir_dma);
+rc = pvrdma_ring_init(r, ring_name, pci_dev, >ring_state[1], max_wr,
+  wqe_sz, (dma_addr_t *)[1], nchunks - 1);
+if (rc) {
+goto out_unmap_ring_state;
+}
+
+goto out;
+
+out_unmap_ring_state:
+rdma_pci_dma_unmap(pci_dev, r->ring_state, TARGET_PAGE_SIZE);
+
+out_free_ring_mem:
+g_free(r);
+
+out:
+rdma_pci_dma_unmap(pci_dev, tbl, TARGET_PAGE_SIZE);
+rdma_pci_dma_unmap(pci_dev, dir, TARGET_PAGE_SIZE);
+
+return rc;
+}
+
+static void destroy_srq_ring(PvrdmaRing *ring)
+{
+pvrdma_ring_free(ring);
+rdma_pci_dma_unmap(ring->dev, ring->ring_state, TARGET_PAGE_SIZE);
+g_free(ring);
+}
+
+static int create_srq(PVRDMADev *dev, union pvrdma_cmd_req *req,
+  union pvrdma_cmd_resp *rsp)
+{
+struct pvrdma_cmd_create_srq *cmd = >create_srq;
+struct pvrdma_cmd_create_srq_resp *resp = >create_srq_resp;
+PvrdmaRing *ring = NULL;
+int rc;
+
+memset(resp, 0, sizeof(*resp));
+
+rc = create_srq_ring(PCI_DEVICE(dev), , cmd->pdir_dma,
+ cmd->attrs.max_wr, cmd->attrs.max_sge,
+ cmd->nchunks);
+if (rc) {
+return rc;
+}
+
+rc = rdma_rm_alloc_srq(>rdma_dev_res, cmd->pd_handle,
+   cmd->attrs.max_wr, cmd->attrs.max_sge,
+   cmd->attrs.srq_limit, >srqn, ring);
+if (rc) {
+destroy_srq_ring(ring);
+return rc;
+}
+
+return 0;
+}
+
+static int query_srq(PVRDMADev *dev, union pvrdma_cmd_req *req,
+ union pvrdma_cmd_resp *rsp)
+{
+struct pvrdma_cmd_query_srq *cmd = >query_srq;
+struct pvrdma_cmd_query_srq_resp *resp = >query_srq_resp;
+
+memset(resp, 0, sizeof(*resp));
+
+return rdma_rm_query_srq(>rdma_dev_res, cmd->srq_handle,
+ (struct ibv_srq_attr *)>attrs);
+}
+
+static int modify_srq(PVRDMADev *dev, union pvrdma_cmd_req *req,
+  union pvrdma_cmd_resp *rsp)
+{
+struct pvrdma_cmd_modify_srq *cmd = >modify_srq;
+
+/* Only support SRQ limit */
+if (!(cmd->attr_mask & IBV_SRQ_LIMIT) ||
+(cmd->attr_mask & IBV_SRQ_MAX_WR))
+return -EINVAL;
+
+return rdma_rm_modify_srq(>rdma_dev_res, cmd->srq_handle,
+  (struct ibv_srq_attr *)>attrs,
+  cmd->attr_mask);
+}
+
+static int destroy_srq(PVRDMADev *dev, union pvrdma_cmd_req *req,
+   union pvrdma_cmd_resp *rsp)
+{
+struct pvrdma_cmd_destroy_srq *cmd = >destroy_srq;
+RdmaRmSRQ *srq;
+PvrdmaRing *ring;
+
+srq = rdma_rm_get_srq(>rdma_dev_res, cmd->srq_handle);
+if (!srq) {
+return -EINVAL;
+}
+
+ring = (PvrdmaRing *)srq->opaque;
+destroy_srq_ring(ring);
+rdma_rm_dealloc_srq(>rdma_dev_res, cmd->srq_handle);
+
+return 0;
+}
+
 struct 

[Qemu-devel] [PATCH PULL 2/4] hw/rdma: Add support for managing SRQ resource

2019-05-04 Thread Marcel Apfelbaum
From: Kamal Heib 

Adding the required functions and definitions for support managing the
shared receive queues (SRQs).

Signed-off-by: Kamal Heib 
Message-Id: <20190403113343.26384-3-kamalhe...@gmail.com>
Reviewed-by: Yuval Shaia 
Signed-off-by: Marcel Apfelbaum 
---
 hw/rdma/rdma_rm.c  | 93 ++
 hw/rdma/rdma_rm.h  | 10 +
 hw/rdma/rdma_rm_defs.h |  8 
 3 files changed, 111 insertions(+)

diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
index b683506b86..c4fb140dcd 100644
--- a/hw/rdma/rdma_rm.c
+++ b/hw/rdma/rdma_rm.c
@@ -544,6 +544,96 @@ void rdma_rm_dealloc_qp(RdmaDeviceResources *dev_res, 
uint32_t qp_handle)
 rdma_res_tbl_dealloc(_res->qp_tbl, qp->qpn);
 }
 
+RdmaRmSRQ *rdma_rm_get_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle)
+{
+return rdma_res_tbl_get(_res->srq_tbl, srq_handle);
+}
+
+int rdma_rm_alloc_srq(RdmaDeviceResources *dev_res, uint32_t pd_handle,
+  uint32_t max_wr, uint32_t max_sge, uint32_t srq_limit,
+  uint32_t *srq_handle, void *opaque)
+{
+RdmaRmSRQ *srq;
+RdmaRmPD *pd;
+int rc;
+
+pd = rdma_rm_get_pd(dev_res, pd_handle);
+if (!pd) {
+return -EINVAL;
+}
+
+srq = rdma_res_tbl_alloc(_res->srq_tbl, srq_handle);
+if (!srq) {
+return -ENOMEM;
+}
+
+rc = rdma_backend_create_srq(>backend_srq, >backend_pd,
+ max_wr, max_sge, srq_limit);
+if (rc) {
+rc = -EIO;
+goto out_dealloc_srq;
+}
+
+srq->opaque = opaque;
+
+return 0;
+
+out_dealloc_srq:
+rdma_res_tbl_dealloc(_res->srq_tbl, *srq_handle);
+
+return rc;
+}
+
+int rdma_rm_query_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle,
+  struct ibv_srq_attr *srq_attr)
+{
+RdmaRmSRQ *srq;
+
+srq = rdma_rm_get_srq(dev_res, srq_handle);
+if (!srq) {
+return -EINVAL;
+}
+
+return rdma_backend_query_srq(>backend_srq, srq_attr);
+}
+
+int rdma_rm_modify_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle,
+   struct ibv_srq_attr *srq_attr, int srq_attr_mask)
+{
+RdmaRmSRQ *srq;
+
+srq = rdma_rm_get_srq(dev_res, srq_handle);
+if (!srq) {
+return -EINVAL;
+}
+
+if ((srq_attr_mask & IBV_SRQ_LIMIT) &&
+(srq_attr->srq_limit == 0)) {
+return -EINVAL;
+}
+
+if ((srq_attr_mask & IBV_SRQ_MAX_WR) &&
+(srq_attr->max_wr == 0)) {
+return -EINVAL;
+}
+
+return rdma_backend_modify_srq(>backend_srq, srq_attr,
+   srq_attr_mask);
+}
+
+void rdma_rm_dealloc_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle)
+{
+RdmaRmSRQ *srq;
+
+srq = rdma_rm_get_srq(dev_res, srq_handle);
+if (!srq) {
+return;
+}
+
+rdma_backend_destroy_srq(>backend_srq, dev_res);
+rdma_res_tbl_dealloc(_res->srq_tbl, srq_handle);
+}
+
 void *rdma_rm_get_cqe_ctx(RdmaDeviceResources *dev_res, uint32_t cqe_ctx_id)
 {
 void **cqe_ctx;
@@ -673,6 +763,8 @@ int rdma_rm_init(RdmaDeviceResources *dev_res, struct 
ibv_device_attr *dev_attr)
 res_tbl_init("CQE_CTX", _res->cqe_ctx_tbl, dev_attr->max_qp *
dev_attr->max_qp_wr, sizeof(void *));
 res_tbl_init("UC", _res->uc_tbl, MAX_UCS, sizeof(RdmaRmUC));
+res_tbl_init("SRQ", _res->srq_tbl, dev_attr->max_srq,
+ sizeof(RdmaRmSRQ));
 
 init_ports(dev_res);
 
@@ -691,6 +783,7 @@ void rdma_rm_fini(RdmaDeviceResources *dev_res, 
RdmaBackendDev *backend_dev,
 
 fini_ports(dev_res, backend_dev, ifname);
 
+res_tbl_free(_res->srq_tbl);
 res_tbl_free(_res->uc_tbl);
 res_tbl_free(_res->cqe_ctx_tbl);
 res_tbl_free(_res->qp_tbl);
diff --git a/hw/rdma/rdma_rm.h b/hw/rdma/rdma_rm.h
index 4f03f9b8c5..e88ab95e26 100644
--- a/hw/rdma/rdma_rm.h
+++ b/hw/rdma/rdma_rm.h
@@ -65,6 +65,16 @@ int rdma_rm_query_qp(RdmaDeviceResources *dev_res, 
RdmaBackendDev *backend_dev,
  int attr_mask, struct ibv_qp_init_attr *init_attr);
 void rdma_rm_dealloc_qp(RdmaDeviceResources *dev_res, uint32_t qp_handle);
 
+RdmaRmSRQ *rdma_rm_get_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle);
+int rdma_rm_alloc_srq(RdmaDeviceResources *dev_res, uint32_t pd_handle,
+  uint32_t max_wr, uint32_t max_sge, uint32_t srq_limit,
+  uint32_t *srq_handle, void *opaque);
+int rdma_rm_query_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle,
+  struct ibv_srq_attr *srq_attr);
+int rdma_rm_modify_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle,
+   struct ibv_srq_attr *srq_attr, int srq_attr_mask);
+void rdma_rm_dealloc_srq(RdmaDeviceResources *dev_res, uint32_t srq_handle);
+
 int rdma_rm_alloc_cqe_ctx(RdmaDeviceResources *dev_res, uint32_t *cqe_ctx_id,
   void *ctx);
 void *rdma_rm_get_cqe_ctx(RdmaDeviceResources *dev_res, uint32_t cqe_ctx_id);
diff 

[Qemu-devel] [PATCH PULL 3/4] hw/rdma: Modify create/destroy QP to support SRQ

2019-05-04 Thread Marcel Apfelbaum
From: Kamal Heib 

Modify create/destroy QP to support shared receive queue and rearrange
the destroy_qp() code to avoid touching the QP after calling
rdma_rm_dealloc_qp().

Signed-off-by: Kamal Heib 
Message-Id: <20190403113343.26384-4-kamalhe...@gmail.com>
Reviewed-by: Yuval Shaia 
Signed-off-by: Marcel Apfelbaum 
---
 hw/rdma/rdma_backend.c   |  9 --
 hw/rdma/rdma_backend.h   |  6 ++--
 hw/rdma/rdma_rm.c| 22 +--
 hw/rdma/rdma_rm.h|  3 +-
 hw/rdma/rdma_rm_defs.h   |  1 +
 hw/rdma/vmw/pvrdma_cmd.c | 59 
 6 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index 04dfd63a57..cf34874e9d 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -794,9 +794,9 @@ void rdma_backend_destroy_cq(RdmaBackendCQ *cq)
 
 int rdma_backend_create_qp(RdmaBackendQP *qp, uint8_t qp_type,
RdmaBackendPD *pd, RdmaBackendCQ *scq,
-   RdmaBackendCQ *rcq, uint32_t max_send_wr,
-   uint32_t max_recv_wr, uint32_t max_send_sge,
-   uint32_t max_recv_sge)
+   RdmaBackendCQ *rcq, RdmaBackendSRQ *srq,
+   uint32_t max_send_wr, uint32_t max_recv_wr,
+   uint32_t max_send_sge, uint32_t max_recv_sge)
 {
 struct ibv_qp_init_attr attr = {};
 
@@ -824,6 +824,9 @@ int rdma_backend_create_qp(RdmaBackendQP *qp, uint8_t 
qp_type,
 attr.cap.max_recv_wr = max_recv_wr;
 attr.cap.max_send_sge = max_send_sge;
 attr.cap.max_recv_sge = max_recv_sge;
+if (srq) {
+attr.srq = srq->ibsrq;
+}
 
 qp->ibqp = ibv_create_qp(pd->ibpd, );
 if (!qp->ibqp) {
diff --git a/hw/rdma/rdma_backend.h b/hw/rdma/rdma_backend.h
index cad7956d98..7c1a19a2b5 100644
--- a/hw/rdma/rdma_backend.h
+++ b/hw/rdma/rdma_backend.h
@@ -89,9 +89,9 @@ void rdma_backend_poll_cq(RdmaDeviceResources *rdma_dev_res, 
RdmaBackendCQ *cq);
 
 int rdma_backend_create_qp(RdmaBackendQP *qp, uint8_t qp_type,
RdmaBackendPD *pd, RdmaBackendCQ *scq,
-   RdmaBackendCQ *rcq, uint32_t max_send_wr,
-   uint32_t max_recv_wr, uint32_t max_send_sge,
-   uint32_t max_recv_sge);
+   RdmaBackendCQ *rcq, RdmaBackendSRQ *srq,
+   uint32_t max_send_wr, uint32_t max_recv_wr,
+   uint32_t max_send_sge, uint32_t max_recv_sge);
 int rdma_backend_qp_state_init(RdmaBackendDev *backend_dev, RdmaBackendQP *qp,
uint8_t qp_type, uint32_t qkey);
 int rdma_backend_qp_state_rtr(RdmaBackendDev *backend_dev, RdmaBackendQP *qp,
diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
index c4fb140dcd..1927f85472 100644
--- a/hw/rdma/rdma_rm.c
+++ b/hw/rdma/rdma_rm.c
@@ -386,12 +386,14 @@ int rdma_rm_alloc_qp(RdmaDeviceResources *dev_res, 
uint32_t pd_handle,
  uint8_t qp_type, uint32_t max_send_wr,
  uint32_t max_send_sge, uint32_t send_cq_handle,
  uint32_t max_recv_wr, uint32_t max_recv_sge,
- uint32_t recv_cq_handle, void *opaque, uint32_t *qpn)
+ uint32_t recv_cq_handle, void *opaque, uint32_t *qpn,
+ uint8_t is_srq, uint32_t srq_handle)
 {
 int rc;
 RdmaRmQP *qp;
 RdmaRmCQ *scq, *rcq;
 RdmaRmPD *pd;
+RdmaRmSRQ *srq = NULL;
 uint32_t rm_qpn;
 
 pd = rdma_rm_get_pd(dev_res, pd_handle);
@@ -408,6 +410,16 @@ int rdma_rm_alloc_qp(RdmaDeviceResources *dev_res, 
uint32_t pd_handle,
 return -EINVAL;
 }
 
+if (is_srq) {
+srq = rdma_rm_get_srq(dev_res, srq_handle);
+if (!srq) {
+rdma_error_report("Invalid srqn %d", srq_handle);
+return -EINVAL;
+}
+
+srq->recv_cq_handle = recv_cq_handle;
+}
+
 if (qp_type == IBV_QPT_GSI) {
 scq->notify = CNT_SET;
 rcq->notify = CNT_SET;
@@ -424,10 +436,14 @@ int rdma_rm_alloc_qp(RdmaDeviceResources *dev_res, 
uint32_t pd_handle,
 qp->send_cq_handle = send_cq_handle;
 qp->recv_cq_handle = recv_cq_handle;
 qp->opaque = opaque;
+qp->is_srq = is_srq;
 
 rc = rdma_backend_create_qp(>backend_qp, qp_type, >backend_pd,
->backend_cq, >backend_cq, 
max_send_wr,
-max_recv_wr, max_send_sge, max_recv_sge);
+>backend_cq, >backend_cq,
+is_srq ? >backend_srq : NULL,
+max_send_wr, max_recv_wr, max_send_sge,
+max_recv_sge);
+
 if (rc) {
 rc = -EIO;
 goto out_dealloc_qp;
diff --git a/hw/rdma/rdma_rm.h b/hw/rdma/rdma_rm.h
index e88ab95e26..e8639909cd 100644
--- a/hw/rdma/rdma_rm.h
+++ b/hw/rdma/rdma_rm.h
@@ -53,7 

[Qemu-devel] [PATCH PULL 1/4] hw/rdma: Add SRQ support to backend layer

2019-05-04 Thread Marcel Apfelbaum
From: Kamal Heib 

Add the required functions and definitions to support shared receive
queues (SRQs) in the backend layer.

Signed-off-by: Kamal Heib 
Message-Id: <20190403113343.26384-2-kamalhe...@gmail.com>
Reviewed-by: Yuval Shaia 
Signed-off-by: Marcel Apfelbaum 
---
 hw/rdma/rdma_backend.c  | 116 +++-
 hw/rdma/rdma_backend.h  |  12 
 hw/rdma/rdma_backend_defs.h |   5 ++
 hw/rdma/rdma_rm.c   |   2 +
 hw/rdma/rdma_rm_defs.h  |   1 +
 5 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index d1660b6474..04dfd63a57 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -40,6 +40,7 @@ typedef struct BackendCtx {
 void *up_ctx;
 struct ibv_sge sge; /* Used to save MAD recv buffer */
 RdmaBackendQP *backend_qp; /* To maintain recv buffers */
+RdmaBackendSRQ *backend_srq;
 } BackendCtx;
 
 struct backend_umad {
@@ -99,6 +100,7 @@ static int rdma_poll_cq(RdmaDeviceResources *rdma_dev_res, 
struct ibv_cq *ibcq)
 int i, ne, total_ne = 0;
 BackendCtx *bctx;
 struct ibv_wc wc[2];
+RdmaProtectedGSList *cqe_ctx_list;
 
 qemu_mutex_lock(_dev_res->lock);
 do {
@@ -116,8 +118,13 @@ static int rdma_poll_cq(RdmaDeviceResources *rdma_dev_res, 
struct ibv_cq *ibcq)
 
 comp_handler(bctx->up_ctx, [i]);
 
-rdma_protected_gslist_remove_int32(>backend_qp->cqe_ctx_list,
-   wc[i].wr_id);
+if (bctx->backend_qp) {
+cqe_ctx_list = >backend_qp->cqe_ctx_list;
+} else {
+cqe_ctx_list = >backend_srq->cqe_ctx_list;
+}
+
+rdma_protected_gslist_remove_int32(cqe_ctx_list, wc[i].wr_id);
 rdma_rm_dealloc_cqe_ctx(rdma_dev_res, wc[i].wr_id);
 g_free(bctx);
 }
@@ -662,6 +669,60 @@ err_free_bctx:
 g_free(bctx);
 }
 
+void rdma_backend_post_srq_recv(RdmaBackendDev *backend_dev,
+RdmaBackendSRQ *srq, struct ibv_sge *sge,
+uint32_t num_sge, void *ctx)
+{
+BackendCtx *bctx;
+struct ibv_sge new_sge[MAX_SGE];
+uint32_t bctx_id;
+int rc;
+struct ibv_recv_wr wr = {}, *bad_wr;
+
+bctx = g_malloc0(sizeof(*bctx));
+bctx->up_ctx = ctx;
+bctx->backend_srq = srq;
+
+rc = rdma_rm_alloc_cqe_ctx(backend_dev->rdma_dev_res, _id, bctx);
+if (unlikely(rc)) {
+complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_NOMEM, ctx);
+goto err_free_bctx;
+}
+
+rdma_protected_gslist_append_int32(>cqe_ctx_list, bctx_id);
+
+rc = build_host_sge_array(backend_dev->rdma_dev_res, new_sge, sge, num_sge,
+  _dev->rdma_dev_res->stats.rx_bufs_len);
+if (rc) {
+complete_work(IBV_WC_GENERAL_ERR, rc, ctx);
+goto err_dealloc_cqe_ctx;
+}
+
+wr.num_sge = num_sge;
+wr.sg_list = new_sge;
+wr.wr_id = bctx_id;
+rc = ibv_post_srq_recv(srq->ibsrq, , _wr);
+if (rc) {
+rdma_error_report("ibv_post_srq_recv fail, srqn=0x%x, rc=%d, errno=%d",
+  srq->ibsrq->handle, rc, errno);
+complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_FAIL_BACKEND, ctx);
+goto err_dealloc_cqe_ctx;
+}
+
+atomic_inc(_dev->rdma_dev_res->stats.missing_cqe);
+backend_dev->rdma_dev_res->stats.rx_bufs++;
+backend_dev->rdma_dev_res->stats.rx_srq++;
+
+return;
+
+err_dealloc_cqe_ctx:
+backend_dev->rdma_dev_res->stats.rx_bufs_err++;
+rdma_rm_dealloc_cqe_ctx(backend_dev->rdma_dev_res, bctx_id);
+
+err_free_bctx:
+g_free(bctx);
+}
+
 int rdma_backend_create_pd(RdmaBackendDev *backend_dev, RdmaBackendPD *pd)
 {
 pd->ibpd = ibv_alloc_pd(backend_dev->context);
@@ -938,6 +999,55 @@ void rdma_backend_destroy_qp(RdmaBackendQP *qp, 
RdmaDeviceResources *dev_res)
 rdma_protected_gslist_destroy(>cqe_ctx_list);
 }
 
+int rdma_backend_create_srq(RdmaBackendSRQ *srq, RdmaBackendPD *pd,
+uint32_t max_wr, uint32_t max_sge,
+uint32_t srq_limit)
+{
+struct ibv_srq_init_attr srq_init_attr = {};
+
+srq_init_attr.attr.max_wr = max_wr;
+srq_init_attr.attr.max_sge = max_sge;
+srq_init_attr.attr.srq_limit = srq_limit;
+
+srq->ibsrq = ibv_create_srq(pd->ibpd, _init_attr);
+if (!srq->ibsrq) {
+rdma_error_report("ibv_create_srq failed, errno=%d", errno);
+return -EIO;
+}
+
+rdma_protected_gslist_init(>cqe_ctx_list);
+
+return 0;
+}
+
+int rdma_backend_query_srq(RdmaBackendSRQ *srq, struct ibv_srq_attr *srq_attr)
+{
+if (!srq->ibsrq) {
+return -EINVAL;
+}
+
+return ibv_query_srq(srq->ibsrq, srq_attr);
+}
+
+int rdma_backend_modify_srq(RdmaBackendSRQ *srq, struct ibv_srq_attr *srq_attr,
+int srq_attr_mask)
+{
+if (!srq->ibsrq) {
+return -EINVAL;
+}
+
+return 

[Qemu-devel] [PATCH PULL 0/4] RDMA queue

2019-05-04 Thread Marcel Apfelbaum
The following changes since commit a6ae23831b05a11880b40f7d58e332c45a6b04f7:

  Merge remote-tracking branch 'remotes/ehabkost/tags/python-next-pull-request' 
into staging (2019-05-03 15:26:09 +0100)

are available in the Git repository at:

  https://github.com/marcel-apf/qemu tags/rdma-pull-request

for you to fetch changes up to 355b7cf356b7f506ca1b716647cc0cf19d312fd2:

  hw/pvrdma: Add support for SRQ (2019-05-04 15:55:56 +0300)


RDMA queue

* pvrdma: Add support for SRQ


Kamal Heib (4):
  hw/rdma: Add SRQ support to backend layer
  hw/rdma: Add support for managing SRQ resource
  hw/rdma: Modify create/destroy QP to support SRQ
  hw/pvrdma: Add support for SRQ

 hw/rdma/rdma_backend.c  | 125 +--
 hw/rdma/rdma_backend.h  |  18 +++-
 hw/rdma/rdma_backend_defs.h |   5 ++
 hw/rdma/rdma_rm.c   | 117 -
 hw/rdma/rdma_rm.h   |  13 ++-
 hw/rdma/rdma_rm_defs.h  |  10 +++
 hw/rdma/vmw/pvrdma_cmd.c| 206 +++-
 hw/rdma/vmw/pvrdma_main.c   |  16 
 hw/rdma/vmw/pvrdma_qp_ops.c |  46 +-
 hw/rdma/vmw/pvrdma_qp_ops.h |   1 +
 10 files changed, 521 insertions(+), 36 deletions(-)

-- 
2.17.1




[Qemu-devel] [PATCH v2 2/2] roms: List and describe the Makefile 'clean' rule

2019-05-04 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 roms/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/roms/Makefile b/roms/Makefile
index f020102c866..1a6c2fa76f9 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -62,6 +62,8 @@ default:
@echo "  u-boot.e500-- update u-boot.e500"
@echo "  u-boot.sam460  -- update u-boot.sam460"
@echo "  efi-- update UEFI (edk2) platform firmware"
+   @echo "  clean  -- delete the files generated by the previous" \
+ "build targets"
 
 bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
-- 
2.20.1




[Qemu-devel] [PATCH v2 1/2] roms: Correct the EDK2_BASETOOLS_OPTFLAGS variable description

2019-05-04 Thread Philippe Mathieu-Daudé
In commit 1cab464136b4 we incorrectly described the
EDK2_BASETOOLS_OPTFLAGS can pass CPPFLAGS and CFLAGS
options to the EDK2 build tools, but it only expands
the CFLAGS (not to the CPPFLAGS).
Update the description to be more accurate.

Reported-by: Laszlo Ersek 
Signed-off-by: Philippe Mathieu-Daudé 
---
 roms/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/roms/Makefile b/roms/Makefile
index 0ce84a45ad5..f020102c866 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -121,8 +121,8 @@ build-efi-roms: build-pxe-roms
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
 
-# Build scripts can pass compiler/linker flags to the EDK2 build tools
-# via the EDK2_BASETOOLS_OPTFLAGS (CPPFLAGS and CFLAGS) and
+# Build scripts can pass compiler/linker flags to the EDK2
+# build  tools via the EDK2_BASETOOLS_OPTFLAGS (CFLAGS) and
 # EDK2_BASETOOLS_LDFLAGS (LDFLAGS) environment variables.
 #
 # Example:
-- 
2.20.1




[Qemu-devel] [PATCH v2 0/2] roms: Add 'clean' make rule and EDK2 documentation fix

2019-05-04 Thread Philippe Mathieu-Daudé
Hi,

Two trivial patches waiting Laszlo's series to land.

Since v1:
- rebased

v1:
https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg01589.html
https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg01598.html

Philippe Mathieu-Daudé (2):
  roms: Correct the EDK2_BASETOOLS_OPTFLAGS variable description
  roms: List and describe the Makefile 'clean' rule

 roms/Makefile | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCH v1 5/8] target/avr: Add instruction translation

2019-05-04 Thread Sarah Harris
This includes:
- table of instruction bit patterns
- intermediate translation functions that extract parameters from opcodes
- TCG translations for each instruction

Signed-off-by: Sarah Harris 
---
 target/avr/translate-inst.h |  695 
 target/avr/translate.c  | 3013 +++
 2 files changed, 3708 insertions(+)
 create mode 100644 target/avr/translate-inst.h
 create mode 100644 target/avr/translate.c

diff --git a/target/avr/translate-inst.h b/target/avr/translate-inst.h
new file mode 100644
index 00..e27f403ba7
--- /dev/null
+++ b/target/avr/translate-inst.h
@@ -0,0 +1,695 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+/*
+ * Functions for extracting instruction parameters from raw opcodes.
+ */
+
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+static inline uint32_t MOVW_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+
+static inline uint32_t MOVW_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+static inline uint32_t MULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+
+static inline uint32_t MULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+static inline uint32_t MULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t MULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+static inline uint32_t FMUL_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMUL_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+static inline uint32_t FMULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+static inline uint32_t FMULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+static inline uint32_t CPC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t CPC_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t SBC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t SBC_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t ADD_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t ADD_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t AND_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t AND_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t EOR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t EOR_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t OR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t OR_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t MOV_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t MOV_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t CPSE_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t CPSE_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t CP_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t CP_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+static inline uint32_t SUB_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t SUB_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+ 

[Qemu-devel] [PATCH v1 3/8] target/avr: Add outward facing interfaces and core CPU logic

2019-05-04 Thread Sarah Harris
This includes:
- CPU data structures
- object model classes and functions
- migration functions
- GDB hooks

Signed-off-by: Sarah Harris 
---
 target/avr/cpu-qom.h |  83 +++
 target/avr/cpu.c | 570 +++
 target/avr/cpu.h | 238 ++
 target/avr/gdbstub.c |  85 +++
 target/avr/machine.c | 122 +
 5 files changed, 1098 insertions(+)
 create mode 100644 target/avr/cpu-qom.h
 create mode 100644 target/avr/cpu.c
 create mode 100644 target/avr/cpu.h
 create mode 100644 target/avr/gdbstub.c
 create mode 100644 target/avr/machine.c

diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h
new file mode 100644
index 00..8085567b87
--- /dev/null
+++ b/target/avr/cpu-qom.h
@@ -0,0 +1,83 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef QEMU_AVR_CPU_QOM_H
+#define QEMU_AVR_CPU_QOM_H
+
+#include "qom/cpu.h"
+
+#define TYPE_AVR_CPU "avr"
+
+#define AVR_CPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(AVRCPUClass, (klass), TYPE_AVR_CPU)
+#define AVR_CPU(obj) \
+OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU)
+#define AVR_CPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AVRCPUClass, (obj), TYPE_AVR_CPU)
+
+/**
+ *  AVRCPUClass:
+ *  @parent_realize: The parent class' realize handler.
+ *  @parent_reset: The parent class' reset handler.
+ *  @vr: Version Register value.
+ *
+ *  A AVR CPU model.
+ */
+typedef struct AVRCPUClass {
+CPUClass parent_class;
+
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+} AVRCPUClass;
+
+/**
+ *  AVRCPU:
+ *  @env: #CPUAVRState
+ *
+ *  A AVR CPU.
+ */
+typedef struct AVRCPU {
+/*< private >*/
+CPUState parent_obj;
+/*< public >*/
+
+CPUAVRState env;
+} AVRCPU;
+
+static inline AVRCPU *avr_env_get_cpu(CPUAVRState *env)
+{
+return container_of(env, AVRCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(avr_env_get_cpu(e))
+#define ENV_OFFSET offsetof(AVRCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vms_avr_cpu;
+#endif
+
+void avr_cpu_do_interrupt(CPUState *cpu);
+bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags);
+hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
+#endif
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
new file mode 100644
index 00..19ce1d7386
--- /dev/null
+++ b/target/avr/cpu.c
@@ -0,0 +1,570 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "qemu-common.h"
+#include "migration/vmstate.h"
+
+static void avr_cpu_set_pc(CPUState *cs, vaddr value)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+
+cpu->env.pc_w = value / 2; /* internally PC points to words */
+}
+
+static bool avr_cpu_has_work(CPUState *cs)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+return (cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_RESET))
+&& cpu_interrupts_enabled(env);
+}
+
+static void avr_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+env->pc_w = tb->pc / 2; /* internally PC points to words */
+}
+
+static void avr_cpu_reset(CPUState *s)
+{
+AVRCPU *cpu = AVR_CPU(s);
+AVRCPUClass *mcc = AVR_CPU_GET_CLASS(cpu);
+  

[Qemu-devel] [PATCH v1 7/8] target/avr: Add example board configuration

2019-05-04 Thread Sarah Harris
A simple board setup that configures an AVR CPU to run a given firmware image.
This is all that's useful to implement without peripheral emulation as AVR CPUs 
include a lot of on-board peripherals.

Signed-off-by: Sarah Harris 
---
 hw/Kconfig   |   1 +
 hw/avr/Kconfig   |   4 +
 hw/avr/Makefile.objs |   1 +
 hw/avr/sample.c  | 177 +++
 4 files changed, 183 insertions(+)
 create mode 100644 hw/avr/Kconfig
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample.c

diff --git a/hw/Kconfig b/hw/Kconfig
index 88b9f15007..dc5eb7a038 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -41,6 +41,7 @@ source watchdog/Kconfig
 # arch Kconfig
 source arm/Kconfig
 source alpha/Kconfig
+source avr/Kconfig
 source cris/Kconfig
 source hppa/Kconfig
 source i386/Kconfig
diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
new file mode 100644
index 00..c6ca8fe775
--- /dev/null
+++ b/hw/avr/Kconfig
@@ -0,0 +1,4 @@
+config AVR_SAMPLE
+bool
+select AVR_TIMER16
+select AVR_USART
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 00..626b7064b3
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y += sample.o
diff --git a/hw/avr/sample.c b/hw/avr/sample.c
new file mode 100644
index 00..21b384b3b3
--- /dev/null
+++ b/hw/avr/sample.c
@@ -0,0 +1,177 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ *  NOTE:
+ *  This is not a real AVR board, this is an example!
+ *  The CPU is an approximation of an ATmega2560, but is missing various
+ *  built-in peripherals.
+ *
+ *  This example board loads provided binary file into flash memory and
+ *  executes it from 0x address in the code memory space.
+ *
+ *  Currently used for AVR CPU validation
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
+#include "ui/console.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "include/hw/sysbus.h"
+#include "include/hw/char/avr_usart.h"
+#include "include/hw/timer/avr_timer16.h"
+#include "elf.h"
+
+#define SIZE_FLASH 0x0004
+#define SIZE_SRAM 0x2200
+/*
+ * Size of additional "external" memory, as if the AVR were configured to use
+ * an external RAM chip.
+ * Note that the configuration registers that normally enable this feature are
+ * unimplemented.
+ */
+#define SIZE_EXMEM 0x
+
+/* Offsets of periphals in emulated memory space (i.e. not host addresses)  */
+#define PRR0 0x64
+#define PRR1 0x65
+#define USART_BASE 0xc0
+#define USART_PRR PRR0
+#define USART_PRR_MASK 0b0010
+#define TIMER1_BASE 0x80
+#define TIMER1_IMSK_BASE 0x6f
+#define TIMER1_IFR_BASE 0x36
+#define TIMER1_PRR PRR0
+#define TIMER1_PRR_MASK 0b0100
+
+/* Interrupt numbers used by peripherals */
+#define TIMER1_CAPT_IRQ 15
+#define TIMER1_COMPA_IRQ 16
+#define TIMER1_COMPB_IRQ 17
+#define TIMER1_COMPC_IRQ 18
+#define TIMER1_OVF_IRQ 19
+
+static void sample_init(MachineState *machine)
+{
+MemoryRegion *address_space_mem;
+MemoryRegion *ram;
+MemoryRegion *flash;
+AVRCPU *cpu_avr;
+const char *firmware = NULL;
+const char *filename;
+int bytes_loaded;
+AVRUsartState *usart0;
+AVRTimer16State *timer1;
+SysBusDevice *busdev;
+
+address_space_mem = get_system_memory();
+ram = g_new(MemoryRegion, 1);
+flash = g_new(MemoryRegion, 1);
+
+/* ATmega2560. */
+cpu_avr = AVR_CPU(cpu_create("avr6-avr"));
+
+memory_region_allocate_system_memory(
+ram, NULL, "avr.ram", SIZE_SRAM + SIZE_EXMEM);
+memory_region_add_subregion(address_space_mem, OFFSET_DATA, ram);
+
+memory_region_init_rom(flash, NULL, "avr.flash", SIZE_FLASH, _fatal);
+memory_region_add_subregion(address_space_mem, OFFSET_CODE, flash);
+
+/* USART 0 built-in peripheral */
+usart0 = AVR_USART(object_new(TYPE_AVR_USART));
+busdev = SYS_BUS_DEVICE(usart0);
+sysbus_mmio_map(busdev, 0, OFFSET_DATA + USART_BASE);
+/*
+ * These IRQ numbers don't match the datasheet because we're counting from
+ * zero and not 

[Qemu-devel] [PATCH v1 4/8] target/avr: Add instruction helpers

2019-05-04 Thread Sarah Harris
Stubs for unimplemented instructions and helpers for instructions that need to 
interact with QEMU.
SPM and WDR are unimplemented because they require emulation of complex 
peripherals.
The implementation of SLEEP is very limited due to the lack of peripherals to 
generate wake interrupts.
Memory access instructions are implemented here because some address ranges 
actually refer to CPU registers.

Signed-off-by: Sarah Harris 
---
 target/avr/helper.c | 343 
 target/avr/helper.h |  28 
 2 files changed, 371 insertions(+)
 create mode 100644 target/avr/helper.c
 create mode 100644 target/avr/helper.h

diff --git a/target/avr/helper.c b/target/avr/helper.c
new file mode 100644
index 00..29b8bfce02
--- /dev/null
+++ b/target/avr/helper.c
@@ -0,0 +1,343 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+
+#include "cpu.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/ioport.h"
+#include "qemu/host-utils.h"
+#include "qemu/error-report.h"
+
+bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+bool ret = false;
+CPUClass *cc = CPU_GET_CLASS(cs);
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index = ctz32(env->intsrc);
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt */
+cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
+return ret;
+}
+
+void avr_cpu_do_interrupt(CPUState *cs)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+uint32_t ret = env->pc_w;
+int vector = 0;
+int size = avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base = 0;
+
+if (cs->exception_index == EXCP_RESET) {
+vector = 0;
+} else if (env->intsrc != 0) {
+vector = ctz32(env->intsrc) + 1;
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+cpu_stb_data(env, env->sp--, (ret & 0xff) >> 16);
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+} else {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+}
+
+env->pc_w = base + vector * size;
+env->sregI = 0; /* clear Global Interrupt Flag */
+
+cs->exception_index = -1;
+}
+
+int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
+int len, bool is_write)
+{
+return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
+}
+
+hwaddr avr_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+return addr; /* I assume 1:1 address correspondance */
+}
+
+int avr_cpu_handle_mmu_fault(
+CPUState *cs, vaddr address, int size, int rw, int mmu_idx)
+{
+/* currently it's assumed that this will never happen */
+cs->exception_index = EXCP_DEBUG;
+cpu_dump_state(cs, stderr, 0);
+return 1;
+}
+
+void tlb_fill(CPUState *cs, target_ulong vaddr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+int prot = 0;
+MemTxAttrs attrs = {};
+uint32_t paddr;
+
+vaddr &= TARGET_PAGE_MASK;
+
+if (mmu_idx == MMU_CODE_IDX) {
+/* access to code in flash */
+paddr = OFFSET_CODE + vaddr;
+prot = PAGE_READ | PAGE_EXEC;
+if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) {
+error_report("execution left flash memory");
+exit(1);
+}
+} else if (vaddr < NO_CPU_REGISTERS + 

[Qemu-devel] [PATCH v1 6/8] target/avr: Add limited support for USART and 16 bit timer peripherals

2019-05-04 Thread Sarah Harris
These were designed to facilitate testing but should provide enough function to 
be useful in other contexts.
Only a subset of the functions of each peripheral is implemented, mainly due to 
the lack of a standard way to handle electrical connections (like GPIO pins).

Signed-off-by: Sarah Harris 
---
 hw/char/Kconfig|   3 +
 hw/char/Makefile.objs  |   1 +
 hw/char/avr_usart.c| 316 ++
 hw/timer/Kconfig   |   3 +
 hw/timer/Makefile.objs |   1 +
 hw/timer/avr_timer16.c | 587 +
 include/hw/char/avr_usart.h|  99 ++
 include/hw/timer/avr_timer16.h |  99 ++
 8 files changed, 1109 insertions(+)
 create mode 100644 hw/char/avr_usart.c
 create mode 100644 hw/timer/avr_timer16.c
 create mode 100644 include/hw/char/avr_usart.h
 create mode 100644 include/hw/timer/avr_timer16.h

diff --git a/hw/char/Kconfig b/hw/char/Kconfig
index 6360c9fffa..7af2c6dd21 100644
--- a/hw/char/Kconfig
+++ b/hw/char/Kconfig
@@ -40,3 +40,6 @@ config SCLPCONSOLE
 
 config TERMINAL3270
 bool
+
+config AVR_USART
+bool
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index cf086e7114..962556d00d 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -20,6 +20,7 @@ obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o
+obj-$(CONFIG_AVR_USART) += avr_usart.o
 
 common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
new file mode 100644
index 00..26c711336b
--- /dev/null
+++ b/hw/char/avr_usart.c
@@ -0,0 +1,316 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/char/avr_usart.h"
+#include "qemu/log.h"
+
+static int avr_usart_can_receive(void *opaque)
+{
+AVRUsartState *usart = opaque;
+
+if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) {
+return 0;
+}
+return 1;
+}
+
+static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size)
+{
+AVRUsartState *usart = opaque;
+assert(size == 1);
+assert(!usart->data_valid);
+usart->data = buffer[0];
+usart->data_valid = true;
+usart->csra |= USART_CSRA_RXC;
+if (usart->csrb & USART_CSRB_RXCIE) {
+qemu_set_irq(usart->rxc_irq, 1);
+}
+}
+
+static void update_char_mask(AVRUsartState *usart)
+{
+uint8_t mode = ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) |
+((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) |
+((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0);
+switch (mode) {
+case 0:
+usart->char_mask = 0b1;
+break;
+case 1:
+usart->char_mask = 0b11;
+break;
+case 2:
+usart->char_mask = 0b111;
+break;
+case 3:
+usart->char_mask = 0b;
+break;
+case 4:
+/* Fallthrough. */
+case 5:
+/* Fallthrough. */
+case 6:
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: Reserved character size 0x%x\n",
+__func__,
+mode);
+break;
+case 7:
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: Nine bit character size not supported (forcing eight)\n",
+__func__);
+usart->char_mask = 0b;
+break;
+default:
+assert(0);
+}
+}
+
+static void avr_usart_reset(DeviceState *dev)
+{
+AVRUsartState *usart = AVR_USART(dev);
+usart->data_valid = false;
+usart->csra = 0b0010;
+usart->csrb = 0b;
+usart->csrc = 0b0110;
+usart->brrl = 0;
+usart->brrh = 0;
+update_char_mask(usart);
+qemu_set_irq(usart->rxc_irq, 0);
+

[Qemu-devel] [PATCH v1 1/8] target/avr: Add instruction decoder

2019-05-04 Thread Sarah Harris
This utility module builds a decision tree to decode instructions, starting 
from a human readable list of instruction bit patterns.
Automatic tree generation will hopefully be more efficient and more 
maintainable than a hand-designed opcode parser.

Tree generation happens at startup because this seemed simpler to implement 
than adding a new build step.

Signed-off-by: Sarah Harris 
---
 target/avr/decode.c | 441 
 target/avr/decode.h |  68 +++
 2 files changed, 509 insertions(+)
 create mode 100644 target/avr/decode.c
 create mode 100644 target/avr/decode.h

diff --git a/target/avr/decode.c b/target/avr/decode.c
new file mode 100644
index 00..a984806d96
--- /dev/null
+++ b/target/avr/decode.c
@@ -0,0 +1,441 @@
+/*
+ * AVR instruction decoder.
+ *
+ * Copyright (c) 2019 University of Kent
+ * Author: Sarah Harris
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * # Why is this here?
+ * This decoder takes a list of human readable descriptions of instructions
+ * and uses it to build a binary decision tree used to choose translation
+ * functions for opcodes.
+ * It's built like this because figuring out the structure of AVR instructions
+ * was too hard and writing a Big Nested Switch by hand seemed too painful.
+ * This seems to be the simplest answer that doesn't use loads (>0.5MB) of RAM.
+ *
+ * # How does it work?
+ * This is based J. R. Quinlan's ID3 algorithm, tweaked to add weights to each
+ * instruction.
+ * Having a binary tree branch on opcode bits seems obvious, but the awkward
+ * part is deciding which order to test the bits.
+ * Getting the order right means that redundant bits can be ignored and fewer
+ * branches are needed; i.e. less memory and faster lookups.
+ * Here, the tests are ordered by an estimate of information gain based on
+ * Shannon Entropy.
+ * In short, we guess how much each bit tells us and pick the one that gives
+ * us most progress toward knowing which instruction we're seeing.
+ * The weights are currently only used to prioritise legal opcodes over
+ * illegal opcodes, which significantly reduces the tree size.
+ *
+ * # Why are you doing this at run time?
+ * It was easier than building and running a special purpose tool during
+ * QEMU's build process.
+ * The tree is only built once, during startup, and hopefully doesn't take long
+ * enough to be noticeable.
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "decode.h"
+
+/* #define DEBUG_DECODER */
+
+/* Wide enough for the largest AVR instruction. */
+#define OPCODE_T uint16_t
+#define OPCODE_SIZE 16
+
+/*
+ * Probability estimate for each instruction.
+ * Larger values mean higher priority.
+ */
+#define WEIGHT_T uint64_t
+#define WEIGHT_LEGAL (1 << 16)
+#define WEIGHT_ILLEGAL 1
+
+typedef union Tree Tree;
+
+typedef struct {
+bool is_leaf;
+/* Bit to test */
+uint bit;
+const Tree *zero;
+const Tree *one;
+} Branch;
+
+typedef struct {
+bool is_leaf;
+TranslateFn decoder;
+/* Instruction length in bits */
+uint32_t length;
+const char *name;
+} Leaf;
+
+union Tree {
+bool is_leaf;
+Branch branch;
+Leaf leaf;
+};
+
+/* Additional (generated) instruction data */
+typedef struct {
+const Instruction *instruction;
+/* Instruction length in bits */
+uint32_t length;
+WEIGHT_T weight;
+/*
+ * Bit pattern matched in opcodes.
+ * For each 1 in mask, the same bit in the opcode must match that from 
bits.
+ */
+OPCODE_T bits;
+OPCODE_T mask;
+} Pattern;
+
+/* Cached decoding tree */
+Tree *cache;
+
+/* Return calculated bit pattern and length for an instruction */
+static Pattern get_info(const Instruction *instruction)
+{
+OPCODE_T bit = 1 << (OPCODE_SIZE - 1);
+OPCODE_T bits = 0;
+OPCODE_T mask = 0;
+uint32_t length = 0;
+const char *c = 

[Qemu-devel] [PATCH v1 0/8] DRAFT AVR Patches

2019-05-04 Thread Sarah Harris
This series of patches adds support for 8 bit Atmel (Microchip) AVR 
microcontrollers.
All documented instructions except DES, SPM, and WDR are implemented.
These patches include very incomplete peripheral emulation, and only a single 
example board definition.

All instructions except LAC, LAS, LAT, XCH, BREAK, and SLEEP have been tested 
by comparing their behaviours against hardware.
The test programs used were designed specifically to exercise as many 
instruction variants as possible.
More details, source code, and results are available here: 
https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests

Additionally, it has been confirmed that this emulation can run FreeRTOS (an 
open source realtime operating system).
AVRs don't have memory management hardware and typically only have a few 
kilobytes of RAM so booting something more standard, e.g. Linux, wasn't 
feasible.
Two peripherals were needed (USART and 16 bit timer) for this test and are 
included in these patches.
The implementations are somewhat limited, mostly because QEMU doesn't seem to 
have much in the way of facilities to handle low-level electrical interfaces 
like GPIO pins.
A simple LED indicator peripheral was also used, but is not included because it 
isn't likely to be generally useful.
The FreeRTOS build and LED patch are available here: 
https://github.com/seharris/qemu-avr-tests/tree/master/free-rtos

These patches are based on work by Michael Rolnik, last discussed here in 2017: 
https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg02290.html
This series is derived from the version found in this repository: 
https://github.com/michaelrolnik/qemu-avr
Changes from that version:
- rebase onto current master
- fixes for some accumulated bitrot (including a crash at startup)
- minor improvements to sample board firmware loading
- fixes for bugs in instruction translations (POP, ASR, LSR, ROR, FMUL, FMULS, 
FMULSU, MUL, MULS, MULSU, OR, SBC, SBCI)
- new instruction decoder to avoid some awkward dependencies
- general cleanup (style fixes, fixing unclear comments, making code easier to 
follow)

On a personal note, I'm unfamiliar with this style of submission so I hope I 
haven't broken anything!

Sarah Harris (8):
  target/avr: Add instruction decoder
  target/avr: Add mechanism to check for active debugger connection
  target/avr: Add outward facing interfaces and core CPU logic
  target/avr: Add instruction helpers
  target/avr: Add instruction translation
  target/avr: Add limited support for USART and 16 bit timer peripherals
  target/avr: Add example board configuration
  target/avr: Register AVR support with the rest of QEMU, the build
system, and the MAINTAINERS file

 MAINTAINERS |6 +
 arch_init.c |2 +
 configure   |6 +
 default-configs/avr-softmmu.mak |5 +
 gdbstub.c   |5 +
 hw/Kconfig  |1 +
 hw/avr/Kconfig  |4 +
 hw/avr/Makefile.objs|1 +
 hw/avr/sample.c |  177 ++
 hw/char/Kconfig |3 +
 hw/char/Makefile.objs   |1 +
 hw/char/avr_usart.c |  316 
 hw/timer/Kconfig|3 +
 hw/timer/Makefile.objs  |1 +
 hw/timer/avr_timer16.c  |  587 ++
 include/disas/dis-asm.h |6 +
 include/exec/gdbstub.h  |4 +
 include/hw/char/avr_usart.h |   99 +
 include/hw/timer/avr_timer16.h  |   99 +
 include/sysemu/arch_init.h  |1 +
 qapi/common.json|2 +-
 target/avr/Makefile.objs|   23 +
 target/avr/cpu-qom.h|   83 +
 target/avr/cpu.c|  570 ++
 target/avr/cpu.h|  238 +++
 target/avr/decode.c |  441 +
 target/avr/decode.h |   68 +
 target/avr/gdbstub.c|   85 +
 target/avr/helper.c |  343 
 target/avr/helper.h |   28 +
 target/avr/machine.c|  122 ++
 target/avr/translate-inst.h |  695 +++
 target/avr/translate.c  | 3013 +++
 tests/machine-none-test.c   |1 +
 34 files changed, 7038 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 hw/avr/Kconfig
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample.c
 create mode 100644 hw/char/avr_usart.c
 create mode 100644 hw/timer/avr_timer16.c
 create mode 100644 include/hw/char/avr_usart.h
 create mode 100644 include/hw/timer/avr_timer16.h
 create mode 100644 target/avr/Makefile.objs
 create mode 100644 target/avr/cpu-qom.h
 create mode 100644 target/avr/cpu.c
 create mode 100644 target/avr/cpu.h
 create mode 100644 target/avr/decode.c
 create mode 100644 target/avr/decode.h
 create mode 100644 target/avr/gdbstub.c
 create mode 100644 target/avr/helper.c
 create mode 100644 target/avr/helper.h
 create mode 100644 

[Qemu-devel] [PATCH v1 8/8] target/avr: Register AVR support with the rest of QEMU, the build system, and the MAINTAINERS file

2019-05-04 Thread Sarah Harris
Signed-off-by: Sarah Harris 
---
 MAINTAINERS |  6 ++
 arch_init.c |  2 ++
 configure   |  6 ++
 default-configs/avr-softmmu.mak |  5 +
 include/disas/dis-asm.h |  6 ++
 include/sysemu/arch_init.h  |  1 +
 qapi/common.json|  2 +-
 target/avr/Makefile.objs| 23 +++
 tests/machine-none-test.c   |  1 +
 9 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 target/avr/Makefile.objs

diff --git a/MAINTAINERS b/MAINTAINERS
index 7dd71e0a2d..859ceb2d08 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -162,6 +162,12 @@ S: Maintained
 F: hw/arm/smmu*
 F: include/hw/arm/smmu*
 
+AVR
+M: Michael Rolnik 
+S: Odd Fixes
+F: target-avr/
+F: hw/avr/
+
 CRIS
 M: Edgar E. Iglesias 
 S: Maintained
diff --git a/arch_init.c b/arch_init.c
index f4f3f610c8..184cdca6dd 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -86,6 +86,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_XTENSA)
 #define QEMU_ARCH QEMU_ARCH_XTENSA
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/configure b/configure
index 60719ddcc5..b8843059b5 100755
--- a/configure
+++ b/configure
@@ -7451,6 +7451,9 @@ case "$target_name" in
 target_compiler=$cross_cc_aarch64
 eval "target_compiler_cflags=\$cross_cc_cflags_${target_name}"
   ;;
+  avr)
+target_compiler=$cross_cc_avr
+  ;;
   cris)
 target_compiler=$cross_cc_cris
   ;;
@@ -7726,6 +7729,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   disas_config "ARM_A64"
 fi
   ;;
+  avr)
+disas_config "AVR"
+  ;;
   cris)
 disas_config "CRIS"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 00..d1e1c28118
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1,5 @@
+# Default configuration for avr-softmmu
+
+# Boards:
+#
+CONFIG_AVR_SAMPLE=y
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 9240ec32c2..a7d230ba66 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -211,6 +211,12 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1  1
+#define bfd_mach_avr2  2
+#define bfd_mach_avr3  3
+#define bfd_mach_avr4  4
+#define bfd_mach_avr5  5
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 10cbafe970..aff57bfe61 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -25,6 +25,7 @@ enum {
 QEMU_ARCH_NIOS2 = (1 << 17),
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_AVR = (1 << 20),
 };
 
 extern const uint32_t arch_type;
diff --git a/qapi/common.json b/qapi/common.json
index 99d313ef3b..eeacd0e3c2 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -187,7 +187,7 @@
 # Since: 3.0
 ##
 { 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
  'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
diff --git a/target/avr/Makefile.objs b/target/avr/Makefile.objs
new file mode 100644
index 00..41355dea1e
--- /dev/null
+++ b/target/avr/Makefile.objs
@@ -0,0 +1,23 @@
+#
+#  QEMU AVR CPU
+#
+#  Copyright (c) 2016 Michael Rolnik
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+obj-y += translate.o cpu.o helper.o decode.o
+obj-y += gdbstub.o
+obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/tests/machine-none-test.c b/tests/machine-none-test.c
index 4c6d470798..361927bb76 100644
--- a/tests/machine-none-test.c
+++ b/tests/machine-none-test.c
@@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] = {
 /* tested targets list */
 { 

[Qemu-devel] [PATCH v1 2/8] target/avr: Add mechanism to check for active debugger connection

2019-05-04 Thread Sarah Harris
AVR CPUs have a BREAK instruction which behaves differently depending on 
whether debugging is enabled.
Since the hardware fuses that normally control this are difficult to emulate, 
and the BREAK instruction is useful for testing, the BREAK instruction is 
instead enabled/disabled depending on whether a GDB session is attached.

Signed-off-by: Sarah Harris 
---
 gdbstub.c  | 5 +
 include/exec/gdbstub.h | 4 
 2 files changed, 9 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index d54abd17cc..a254a364e6 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1793,6 +1793,11 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 return RS_IDLE;
 }
 
+bool gdb_is_active(void)
+{
+return gdbserver_state != NULL;
+}
+
 void gdb_set_stop_cpu(CPUState *cpu)
 {
 GDBProcess *p = gdb_get_cpu_process(gdbserver_state, cpu);
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 08363969c1..d059bf5339 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -45,6 +45,10 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char 
*fmt, ...);
  */
 void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
 int use_gdb_syscalls(void);
+/**
+ * gdb_is_active: return true if debugging in progress
+ */
+bool gdb_is_active(void);
 void gdb_set_stop_cpu(CPUState *cpu);
 void gdb_exit(CPUArchState *, int);
 #ifdef CONFIG_USER_ONLY
-- 
2.21.0




Re: [Qemu-devel] [PATCH v2] vmdk: Set vmdk parent backing_format to vmdk

2019-05-04 Thread Sam
Thanks Thomas, Thanks Max

So how do you want to proceed?

Apply Max’s RFC from here 
(http://lists.nongnu.org/archive/html/qemu-block/2019-04/msg00442.html 
) and 
add the commit id which is stable now?
Or should I resubmit my fix (which is very similar to what Max did) without the 
original change?

Sam

> On 3 May 2019, at 17:32, Max Reitz  wrote:
> 
> On 03.05.19 13:34, Thomas Huth wrote:
>> Hi Sam,
>> 
>> On 02/05/2019 15.08, Sam Eiderman wrote:
>>> Commit b69864e ("vmdk: Support version=3 in VMDK descriptor files")
>>> fixed the probe function to correctly guess vmdk descriptors with
>>> version=3.
>>> 
>>> This solves the issue where vmdk snapshot with parent vmdk descriptor
>>> containing "version=3" would be treated as raw instead vmdk.
>>> 
>>> In the future case where a new vmdk version is introduced, we will again
>>> experience this issue, even if the user will provide "-f vmdk" it will
>>> only apply to the tip image and not to the underlying "misprobed" parent
>>> image.
>>> 
>>> The code in vmdk.c already assumes that the backing file of vmdk must be
>>> vmdk (see vmdk_is_cid_valid which returns 0 if backing file is not
>>> vmdk).
>>> 
>>> So let's make it official by supplying the backing_format as vmdk.
>>> 
>>> Reviewed-by: Mark Kanda 
>>> Reviewed-By: Liran Alon 
>>> Reviewed-by: Arbel Moshe 
>>> Signed-off-by: Shmuel Eiderman 
>>> ---
>>> block/vmdk.c   | 2 ++
>>> tests/qemu-iotests/110 | 6 +++---
>>> tests/qemu-iotests/126 | 4 ++--
>>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>> 
>>> diff --git a/block/vmdk.c b/block/vmdk.c
>>> index 8dec6ef767..de8cb859f8 100644
>>> --- a/block/vmdk.c
>>> +++ b/block/vmdk.c
>>> @@ -397,6 +397,8 @@ static int vmdk_parent_open(BlockDriverState *bs)
>>> pstrcpy(bs->auto_backing_file, end_name - p_name + 1, p_name);
>>> pstrcpy(bs->backing_file, sizeof(bs->backing_file),
>>> bs->auto_backing_file);
>>> +pstrcpy(bs->backing_format, sizeof(bs->backing_format),
>>> +"vmdk");
>>> }
>> 
>> Your patch with this change has already been merged into the QEMU master
>> branch...
>> 
>>> diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
>>> index fad672c1ae..982569dbc5 100755
>>> --- a/tests/qemu-iotests/110
>>> +++ b/tests/qemu-iotests/110
>>> @@ -54,7 +54,7 @@ _make_test_img -b "$TEST_IMG_REL.base" 64M
>>> # qemu should be able to reconstruct the filename, so relative backing names
>>> # should work
>>> TEST_IMG="json:{'driver':'$IMGFMT','file':{'driver':'file','filename':'$TEST_IMG'}}"
>>>  \
>>> -_img_info | _filter_img_info
>>> +_img_info | _filter_img_info | grep -v "backing file format"
>>> 
>>> echo
>>> echo '=== Non-reconstructable filename ==='
>>> @@ -78,7 +78,7 @@ TEST_IMG="json:{
>>> }
>>> ]
>>> }
>>> -}" _img_info | _filter_img_info
>>> +}" _img_info | _filter_img_info | grep -v "backing file format"
>>> 
>>> echo
>>> echo '=== Backing name is always relative to the backed image ==='
>>> @@ -110,7 +110,7 @@ TEST_IMG="json:{
>>> }
>>> ]
>>> }
>>> -}" _img_info | _filter_img_info
>>> +}" _img_info | _filter_img_info | grep -v "backing file format"
>>> 
>>> 
>>> # success, all done
>>> diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
>>> index 96dc048d59..1f7618c8a5 100755
>>> --- a/tests/qemu-iotests/126
>>> +++ b/tests/qemu-iotests/126
>>> @@ -63,7 +63,7 @@ TEST_IMG=$BASE_IMG _make_test_img 64M
>>> TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT
>>> 
>>> # The default cluster size depends on the image format
>>> -TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
>>> +TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size\|backing file format'
>>> 
>>> _rm_test_img "$BASE_IMG"
>>> _rm_test_img "$TOP_IMG"
>>> @@ -79,7 +79,7 @@ TOP_IMG="file:image:top.$IMGFMT"
>>> TEST_IMG=$BASE_IMG _make_test_img 64M
>>> TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG"
>>> 
>>> -TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
>>> +TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size\|backing file format'
>>> 
>>> _rm_test_img "$BASE_IMG"
>>> _rm_test_img "image:top.$IMGFMT"
>>> 
>> 
>> ... so please just send a patch with these fixes!
> 
> I already did, it's here:
> 
> http://lists.nongnu.org/archive/html/qemu-block/2019-04/msg00442.html 
> 
> 
> Max



[Qemu-devel] [PULL 1/1] Update slirp submodule

2019-05-04 Thread Samuel Thibault
To fix Windows on ARM.
---
 slirp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp b/slirp
index 59a1b1f165..0e79ba4856 16
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit 59a1b1f165458c2acb7ff0525b543945f7416225
+Subproject commit 0e79ba48567ccfb3cc2cf2e98cce8811eee7e455
-- 
2.20.1




[Qemu-devel] [PULL 0/1] Update slirp submodule

2019-05-04 Thread Samuel Thibault
The following changes since commit 52ec9dcc1ed5609674e7b52198c18207bb193548:

  Update slirp submodule (2019-05-04 14:38:05 +0200)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 52ec9dcc1ed5609674e7b52198c18207bb193548:

  Update slirp submodule (2019-05-04 14:38:05 +0200)


Update slirp submodule

To fix Windows on ARM.





Re: [Qemu-devel] [PATCH v2 1/4] Initial Windows on ARM (AArch64 64-Bit) host support

2019-05-04 Thread Samuel Thibault
Hello,

Cao Jiaxi, le mer. 01 mai 2019 02:10:09 +0800, a ecrit:
> This series of patches is for initial support of Windows 10 on ARM as a QEMU 
> host.
> Currently only TCG intepreter is working correctly, it crashes when TCG JIT 
> is enabled.
> For now we assume it is built using the clang aarch64-w64-mingw32 toolchain, 
> you can get a prebuilt toolchain at https://github.com/mstorsjo/llvm-mingw.
> 
> QEMU_PACKED: Remove gcc_struct attribute in Windows non x86 targets
> This attribute is for x86 only, and it generates an warning on ARM64 
> Clang/MinGW targets.

I have applied it to the libslirp repo, thanks!

I'll submit a pull request to get it updated on qemu.

Samuel



[Qemu-devel] [PATCH] hw/net/ne2000: Extract the PCI device from the chipset common code

2019-05-04 Thread Philippe Mathieu-Daudé
The ne2000.c file contains functions common the the ISA and PCI
devices. To allow to build with one or another, extract the PCI
specific part into a new file.

This fix an issue where the NE2000_ISA Kconfig had to pull the
full PCI core objects.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/Kconfig   |   7 ++-
 hw/net/Makefile.objs |   3 +-
 hw/net/ne2000-pci.c  | 132 +++
 hw/net/ne2000.c  | 105 --
 4 files changed, 139 insertions(+), 108 deletions(-)
 create mode 100644 hw/net/ne2000-pci.c

diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 7d7bbc5d7c9..4ef86dc3a53 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -1,10 +1,14 @@
 config DP8393X
 bool
 
+config NE2000_COMMON
+bool
+
 config NE2000_PCI
 bool
 default y if PCI_DEVICES
 depends on PCI
+select NE2000_COMMON
 
 config EEPRO100_PCI
 bool
@@ -51,8 +55,7 @@ config NE2000_ISA
 bool
 default y
 depends on ISA_BUS
-depends on PCI # for NE2000State
-select NE2000_PCI
+select NE2000_COMMON
 
 config OPENCORES_ETH
 bool
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index ea637157802..9904273b060 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -1,8 +1,9 @@
 common-obj-$(CONFIG_DP8393X) += dp8393x.o
 common-obj-$(CONFIG_XEN) += xen_nic.o
+common-obj-$(CONFIG_NE2000_COMMON) += ne2000.o
 
 # PCI network cards
-common-obj-$(CONFIG_NE2000_PCI) += ne2000.o
+common-obj-$(CONFIG_NE2000_PCI) += ne2000-pci.o
 common-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o
 common-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o
 common-obj-$(CONFIG_PCNET_COMMON) += pcnet.o
diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c
new file mode 100644
index 000..cb05744f3c3
--- /dev/null
+++ b/hw/net/ne2000-pci.c
@@ -0,0 +1,132 @@
+/*
+ * QEMU NE2000 emulation (PCI bus)
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "ne2000.h"
+#include "sysemu/sysemu.h"
+
+typedef struct PCINE2000State {
+PCIDevice dev;
+NE2000State ne2000;
+} PCINE2000State;
+
+static const VMStateDescription vmstate_pci_ne2000 = {
+.name = "ne2000",
+.version_id = 3,
+.minimum_version_id = 3,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, PCINE2000State),
+VMSTATE_STRUCT(ne2000, PCINE2000State, 0, vmstate_ne2000, NE2000State),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static NetClientInfo net_ne2000_info = {
+.type = NET_CLIENT_DRIVER_NIC,
+.size = sizeof(NICState),
+.receive = ne2000_receive,
+};
+
+static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
+{
+PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+NE2000State *s;
+uint8_t *pci_conf;
+
+pci_conf = d->dev.config;
+pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
+
+s = >ne2000;
+ne2000_setup_io(s, DEVICE(pci_dev), 0x100);
+pci_register_bar(>dev, 0, PCI_BASE_ADDRESS_SPACE_IO, >io);
+s->irq = pci_allocate_irq(>dev);
+
+qemu_macaddr_default_if_unset(>c.macaddr);
+ne2000_reset(s);
+
+s->nic = qemu_new_nic(_ne2000_info, >c,
+  object_get_typename(OBJECT(pci_dev)),
+  pci_dev->qdev.id, s);
+qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
+}
+
+static void pci_ne2000_exit(PCIDevice *pci_dev)
+{
+PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+NE2000State *s = >ne2000;
+
+qemu_del_nic(s->nic);
+qemu_free_irq(s->irq);
+}
+
+static void ne2000_instance_init(Object *obj)
+{
+PCIDevice *pci_dev = PCI_DEVICE(obj);
+PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+NE2000State *s = >ne2000;
+
+device_add_bootindex_property(obj, >c.bootindex,
+  "bootindex", 

[Qemu-devel] [PATCH] hw/display/cirrus_vga: Update the documentation URL

2019-05-04 Thread Philippe Mathieu-Daudé
The documentation URL is not working, but is backed up by the
Wayback Machine on the Internet Archive.
Replace the outdated link by a captured one.
Add another link to the VGADOC4b.ZIP archive content.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/display/cirrus_vga.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index a0e71469f4d..a04440b3748 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -23,8 +23,13 @@
  * THE SOFTWARE.
  */
 /*
- * Reference: Finn Thogersons' VGADOC4b
- *   available at http://home.worldonline.dk/~finth/
+ * Reference: Finn Thogersons' VGADOC4b:
+ *
+ *  http://web.archive.org/web/20021019054927/http://home.worldonline.dk/finth/
+ *
+ * VGADOC4b.ZIP content available at:
+ *
+ *  https://pdos.csail.mit.edu/6.828/2005/readings/hardware/vgadoc
  */
 #include "qemu/osdep.h"
 #include "qemu/units.h"
-- 
2.20.1




[Qemu-devel] [PATCH 4/9] coroutine: add host specific coroutine backend for 64-bit ARM

2019-05-04 Thread Paolo Bonzini
The speedup is similar to x86, 120 ns vs 180 ns on an APM Mustang.

Signed-off-by: Paolo Bonzini 
---
 configure|  2 +-
 scripts/qemugdb/coroutine_asm.py |  6 -
 util/Makefile.objs   |  2 ++
 util/coroutine-asm.c | 45 
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index c01f57a3ae..26e62a4ab1 100755
--- a/configure
+++ b/configure
@@ -5200,7 +5200,7 @@ fi
 if test "$coroutine" = ""; then
   if test "$mingw32" = "yes"; then
 coroutine=win32
-  elif test "$cpu" = "x86_64"; then
+  elif test "$cpu" = "x86_64" || test "$cpu" = "aarch64"; then
  coroutine=asm
   elif test "$ucontext_works" = "yes"; then
 coroutine=ucontext
diff --git a/scripts/qemugdb/coroutine_asm.py b/scripts/qemugdb/coroutine_asm.py
index b4ac1291db..181b77287b 100644
--- a/scripts/qemugdb/coroutine_asm.py
+++ b/scripts/qemugdb/coroutine_asm.py
@@ -17,4 +17,8 @@ U64_PTR = gdb.lookup_type('uint64_t').pointer()
 def get_coroutine_regs(addr):
 addr = addr.cast(gdb.lookup_type('CoroutineAsm').pointer())
 rsp = addr['sp'].cast(U64_PTR)
-return {'sp': rsp, 'pc': rsp.dereference()}
+arch = gdb.selected_frame().architecture.name().split(':'):
+if arch[0] == 'i386' and arch[1] == 'x86-64':
+return {'rsp': rsp, 'pc': rsp.dereference()}
+else:
+return {'sp': rsp, 'pc': addr['scratch'].cast(U64_PTR) }
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 41a10539cf..2167ffc862 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -39,7 +39,9 @@ util-obj-$(CONFIG_MEMBARRIER) += sys_membarrier.o
 util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
 util-obj-y += qemu-coroutine-sleep.o
 util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
+ifeq ($(ARCH),x86_64)
 coroutine-asm.o-cflags := -mno-red-zone
+endif
 util-obj-y += buffer.o
 util-obj-y += timed-average.o
 util-obj-y += base64.o
diff --git a/util/coroutine-asm.c b/util/coroutine-asm.c
index a06ecbcb0a..de68e98622 100644
--- a/util/coroutine-asm.c
+++ b/util/coroutine-asm.c
@@ -40,6 +40,11 @@ typedef struct {
 Coroutine base;
 void *sp;
 
+/*
+ * aarch64: instruction pointer
+ */
+void *scratch;
+
 void *stack;
 size_t stack_size;
 
@@ -116,6 +121,49 @@ static void start_switch_fiber(void **fake_stack_save,
 /* Use "call" to ensure the stack  is aligned correctly.  */
 #define CO_SWITCH_NEW(from, to) CO_SWITCH(from, to, 0, "call 
coroutine_trampoline")
 #define CO_SWITCH_RET(from, to, action) CO_SWITCH(from, to, action, "ret")
+
+#elif defined __aarch64__
+/*
+ * GCC does not support clobbering the frame pointer, so we save it ourselves.
+ * Saving the link register as well generates slightly better code because then
+ * qemu_coroutine_switch can be treated as a leaf procedure.
+ */
+#define CO_SWITCH_RET(from, to, action) ({ 
   \
+register uintptr_t action_ __asm__("x0") = action; 
   \
+register void *from_ __asm__("x16") = from;
   \
+register void *to_ __asm__("x1") = to; 
   \
+asm volatile(  
   \
+".cfi_remember_state\n"
   \
+"stp x29, x30, [sp, #-16]!\n"/* GCC does not save it, do it 
ourselves */  \
+".cfi_adjust_cfa_offset 16\n"  
   \
+".cfi_def_cfa_register sp\n"   
   \
+"adr x30, 2f\n"  /* source PC will be after the BR */  
   \
+"str x30, [x16, %[SCRATCH]]\n"   /* save it */ 
   \
+"mov x30, sp\n"  /* save source SP */  
   \
+"str x30, [x16, %[SP]]\n"  
   \
+"ldr x30, [x1, %[SCRATCH]]\n"/* load destination PC */ 
   \
+"ldr x1, [x1, %[SP]]\n"  /* load destination SP */ 
   \
+"mov sp, x1\n" 
   \
+"br x30\n" 
   \
+"2: \n"
   \
+"ldp x29, x30, [sp], #16\n"
   \
+".cfi_restore_state\n" 
   \
+: "+r" (action_), "+r" (from_), "+r" (to_) 
   \
+: [SP] "i" (offsetof(CoroutineAsm, sp)),   
   \
+  [SCRATCH] "i" (offsetof(CoroutineAsm, scratch))  
   \
+: "x2", "x3", "x4", "x5", "x6", "x7", 

[Qemu-devel] [PATCH 10/9] coroutine-asm: add x86 CET shadow stack support

2019-05-04 Thread Paolo Bonzini
Note that the ABI is not yet part of Linux; this patch is
not intended to be committed until that is approved.

Signed-off-by: Paolo Bonzini 
---
 configure| 14 
 util/Makefile.objs   |  2 ++
 util/coroutine-asm.c | 82 ++--
 3 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index c02a5f4b79..8e81d08ef1 100755
--- a/configure
+++ b/configure
@@ -5192,6 +5192,20 @@ if test "$cf_protection" != no; then
   feature_not_found "cf_protection" 'Control-flow protection is not 
supported by your toolchain'
 fi
 cf_protection=no
+  else
+if test $cpu = x86_64; then
+  # only needed by coroutine-asm.c, however it should be rare to have
+  # CET support in the compiler but not in binutils
+  cat > $TMPC << EOF
+int main(void) { asm("rdsspq %%rax" : : : "rax"); }
+EOF
+  if ! compile_prog "" "" ; then
+if test "$cf_protection" = yes; then
+  feature_not_found "cf_protection" 'CET is not supported by your 
toolchain'
+fi
+cf_protection=no
+  fi
+fi
   fi
 fi
 if test "$cf_protection" = ""; then
diff --git a/util/Makefile.objs b/util/Makefile.objs
index d7add70b63..cf08b4d1c4 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -45,8 +45,10 @@ endif
 ifeq ($(CONFIG_CF_PROTECTION),y)
 coroutine-sigaltstack.o-cflags := -fcf-protection=branch
 coroutine-ucontext.o-cflags := -fcf-protection=branch
+ifneq ($(ARCH),x86_64)
 coroutine-asm.o-cflags += -fcf-protection=branch
 endif
+endif
 util-obj-y += buffer.o
 util-obj-y += timed-average.o
 util-obj-y += base64.o
diff --git a/util/coroutine-asm.c b/util/coroutine-asm.c
index a9a80e9c71..01875acfc4 100644
--- a/util/coroutine-asm.c
+++ b/util/coroutine-asm.c
@@ -22,6 +22,13 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/coroutine_int.h"
+#include "qemu/error-report.h"
+
+#ifdef CONFIG_CF_PROTECTION
+#include 
+#include 
+int arch_prctl(int code, unsigned long addr);
+#endif
 
 #ifdef CONFIG_VALGRIND_H
 #include 
@@ -42,12 +49,16 @@ typedef struct {
 
 /*
  * aarch64, s390x: instruction pointer
+ * x86: shadow stack pointer
  */
 void *scratch;
 
 void *stack;
 size_t stack_size;
 
+/* x86: CET shadow stack */
+void *sstack;
+size_t sstack_size;
 #ifdef CONFIG_VALGRIND_H
 unsigned int valgrind_stack_id;
 #endif
@@ -82,6 +93,35 @@ static void start_switch_fiber(void **fake_stack_save,
 #endif
 }
 
+static bool have_sstack(void)
+{
+#if defined CONFIG_CF_PROTECTION && defined __x86_64__
+uint64_t ssp;
+asm ("xor %0, %0; rdsspq %0\n" : "=r" (ssp));
+return !!ssp;
+#else
+return 0;
+#endif
+}
+
+static void *alloc_sstack(size_t sz)
+{
+#if defined CONFIG_CF_PROTECTION && defined __x86_64__
+#ifndef ARCH_X86_CET_ALLOC_SHSTK
+#define ARCH_X86_CET_ALLOC_SHSTK 0x3004
+#endif
+
+uint64_t arg = sz;
+if (arch_prctl(ARCH_X86_CET_ALLOC_SHSTK, (unsigned long) ) < 0) {
+abort();
+}
+
+return (void *)arg;
+#else
+abort();
+#endif
+}
+
 #ifdef __x86_64__
 /*
  * We hardcode all operands to specific registers so that we can write down 
all the
@@ -93,6 +133,26 @@ static void start_switch_fiber(void **fake_stack_save,
  * Note that push and call would clobber the red zone.  Makefile.objs compiles 
this
  * file with -mno-red-zone.  The alternative is to subtract/add 128 bytes from 
rsp
  * around the switch, with slightly lower cache performance.
+ *
+ * The RSTORSSP and SAVEPREVSSP instructions are intricate.  In a nutshell 
they are:
+ *
+ *  RSTORSSP(mem):oldSSP = SSP
+ *SSP = mem
+ **SSP = oldSSP
+ *
+ *  SAVEPREVSSP:  oldSSP = shadow_stack_pop()
+ **(oldSSP - 8) = oldSSP   # "push" to old shadow 
stack
+ *
+ * Therefore, RSTORSSP(mem) followed by SAVEPREVSSP is the same as
+ *
+ * shadow_stack_push(SSP)
+ * SSP = mem
+ * shadow_stack_pop()
+ *
+ * From the simplified description you can see that co->ssp, being stored 
before
+ * the RSTORSSP+SAVEPREVSSP sequence, points to the top actual entry of the 
shadow
+ * stack, not to the restore token.  Hence we use an offset of -8 in the 
operand
+ * of rstorssp.
  */
 #define CO_SWITCH(from, to, action, jump) ({   
   \
 int action_ = action;  
   \
@@ -105,7 +165,15 @@ static void start_switch_fiber(void **fake_stack_save,
 "jmp 2f\n"  /* switch back continues at label 
2 */\

   \
 "1: .cfi_adjust_cfa_offset 8\n"
   \
-"movq %%rsp, %c[SP](%[FROM])\n" /* save source SP */   
   \
+"xor %%rbp, %%rbp\n"/* use old frame pointer as 
scratch reg */ \
+ 

[Qemu-devel] [PATCH 6/9] configure: add control-flow protection support

2019-05-04 Thread Paolo Bonzini
Control-flow protection requires object files to note which features
are supported.  The linker will merge them to the set of features that
are supported by all object files.  The compiler creates these notes
when the -fcf-protection option is passed, but we have to blacklist
some object files that only support a subset of the full control-flow
protection feature set.

Even without any further host-specific patches, user-mode emulation
binaries can already use shadow stacks, because they don't need
coroutines and don't include the problematic util/coroutine-*.o
object files.  Likewise, system-mode emulation binaries will enable
indirect branch tracking if built without TCG support.

The next patches will improve the situation so that QEMU can be built
with full protection on x86 hosts.

Signed-off-by: Paolo Bonzini 
---
 Makefile.target|  3 +++
 configure  | 29 +
 util/Makefile.objs |  5 +
 3 files changed, 37 insertions(+)

diff --git a/Makefile.target b/Makefile.target
index ae02495951..667682779b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -111,6 +111,9 @@ obj-y += exec.o
 obj-y += accel/
 obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o
 obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o
+ifeq ($(CONFIG_CF_PROTECTION),y)
+tcg/tcg.o-cflags := -fcf-protection=return
+endif
 obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-$(CONFIG_TCG) += fpu/softfloat.o
diff --git a/configure b/configure
index 26e62a4ab1..946ff7825a 100755
--- a/configure
+++ b/configure
@@ -449,6 +449,7 @@ win_sdk="no"
 want_tools="yes"
 libiscsi=""
 libnfs=""
+cf_protection="no"  # leave it disabled until we can test performance
 coroutine=""
 coroutine_pool=""
 debug_stack_usage="no"
@@ -1267,6 +1268,10 @@ for opt do
   ;;
   --with-pkgversion=*) pkgversion="$optarg"
   ;;
+  --enable-cf-protection) cf_protection="yes"
+  ;;
+  --disable-cf-protection) cf_protection="no"
+  ;;
   --with-coroutine=*) coroutine="$optarg"
   ;;
   --disable-coroutine-pool) coroutine_pool="no"
@@ -1796,6 +1801,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   lzfse   support of lzfse compression library
   (for reading lzfse-compressed dmg images)
   seccomp seccomp support
+  cf-protection   Control-flow protection
   coroutine-pool  coroutine freelist (better performance)
   glusterfs   GlusterFS backend
   tpm TPM support
@@ -5176,6 +5182,25 @@ if have_backend "dtrace"; then
   fi
 fi
 
+##
+# detect Control-flow protection support in the toolchain
+
+if test "$cf_protection" != no; then
+  write_c_skeleton;
+  if ! compile_prog "-fcf-protection" "" ; then
+if test "$cf_protection" = yes; then
+  feature_not_found "cf_protection" 'Control-flow protection is not 
supported by your toolchain'
+fi
+cf_protection=no
+  fi
+fi
+if test "$cf_protection" = ""; then
+  cf_protection=yes
+fi
+if test "$cf_protection" = "yes"; then
+  QEMU_CFLAGS="-fcf-protection $QEMU_CFLAGS"
+fi
+
 ##
 # check and set a backend for coroutine
 
@@ -6361,6 +6386,7 @@ echo "netmap support$netmap"
 echo "Linux AIO support $linux_aio"
 echo "ATTR/XATTR support $attr"
 echo "Install blobs $blobs"
+echo "CF protection $cf_protection"
 echo "KVM support   $kvm"
 echo "HAX support   $hax"
 echo "HVF support   $hvf"
@@ -6571,6 +6597,9 @@ fi
 if test "$profiler" = "yes" ; then
   echo "CONFIG_PROFILER=y" >> $config_host_mak
 fi
+if test "$cf_protection" = "yes" ; then
+  echo "CONFIG_CF_PROTECTION=y" >> $config_host_mak
+fi
 if test "$slirp" != "no"; then
   echo "CONFIG_SLIRP=y" >> $config_host_mak
   echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 2167ffc862..d7add70b63 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -42,6 +42,11 @@ util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
 ifeq ($(ARCH),x86_64)
 coroutine-asm.o-cflags := -mno-red-zone
 endif
+ifeq ($(CONFIG_CF_PROTECTION),y)
+coroutine-sigaltstack.o-cflags := -fcf-protection=branch
+coroutine-ucontext.o-cflags := -fcf-protection=branch
+coroutine-asm.o-cflags += -fcf-protection=branch
+endif
 util-obj-y += buffer.o
 util-obj-y += timed-average.o
 util-obj-y += base64.o
-- 
2.21.0





[Qemu-devel] [PATCH 9/9] linux-user: add IBT support to x86 safe-syscall.S

2019-05-04 Thread Paolo Bonzini
Because safe-syscall.S does not go through the C compiler, the
.note.gnu.property note has to be added manually.  Safe syscalls do not
involve any indirect branch or stack unwinding, so they are trivially
safe for IBT or shadow stacks.

Reviewed-by: Richard Henderson 
Signed-off-by: Paolo Bonzini 
---
 linux-user/host/i386/safe-syscall.inc.S   | 19 +++
 linux-user/host/x86_64/safe-syscall.inc.S | 19 +++
 2 files changed, 38 insertions(+)

diff --git a/linux-user/host/i386/safe-syscall.inc.S 
b/linux-user/host/i386/safe-syscall.inc.S
index 9e58fc6504..6c6d568d62 100644
--- a/linux-user/host/i386/safe-syscall.inc.S
+++ b/linux-user/host/i386/safe-syscall.inc.S
@@ -98,3 +98,22 @@ safe_syscall_end:
.cfi_endproc
 
.size   safe_syscall_base, .-safe_syscall_base
+
+   .pushsection ".note.gnu.property", "a"
+   .p2align 2
+   .long 1f - 0f  /* name length.  */
+   .long 4f - 1f  /* data length.  */
+   .long 5/* NT_GNU_PROPERTY_TYPE_0.  */
+0:
+   .asciz "GNU"   /* vendor name.  */
+   .p2align 2
+1:
+/* GNU_PROPERTY_X86_FEATURE_1_AND.  */
+   .long 0xc002   /* pr_type.  */
+   .long 3f - 2f  /* pr_datasz.  */
+2:
+   .long 0x3  /* IBT, SHSTK */
+3:
+   .p2align 2
+4:
+   .popsection
diff --git a/linux-user/host/x86_64/safe-syscall.inc.S 
b/linux-user/host/x86_64/safe-syscall.inc.S
index f36992daa3..e1a57db338 100644
--- a/linux-user/host/x86_64/safe-syscall.inc.S
+++ b/linux-user/host/x86_64/safe-syscall.inc.S
@@ -89,3 +89,22 @@ safe_syscall_end:
 .cfi_endproc
 
 .size   safe_syscall_base, .-safe_syscall_base
+
+   .pushsection ".note.gnu.property", "a"
+   .p2align 3
+   .long 1f - 0f  /* name length.  */
+   .long 4f - 1f  /* data length.  */
+   .long 5/* NT_GNU_PROPERTY_TYPE_0.  */
+0:
+   .asciz "GNU"   /* vendor name.  */
+   .p2align 3
+1:
+/* GNU_PROPERTY_X86_FEATURE_1_AND.  */
+   .long 0xc002   /* pr_type.  */
+   .long 3f - 2f  /* pr_datasz.  */
+2:
+   .long 0x3  /* IBT, SHSTK */
+3:
+   .p2align 3
+4:
+   .popsection
-- 
2.21.0





[Qemu-devel] [PATCH 7/9] tcg: add tcg_out_start

2019-05-04 Thread Paolo Bonzini
This function is called at the beginning of any translation block.  We will
use it to emit ENDBR32 or ENDBR64 annotations for x86 CET.

Reviewed-by: Richard Henderson 
Signed-off-by: Paolo Bonzini 
---
 tcg/aarch64/tcg-target.inc.c | 4 
 tcg/arm/tcg-target.inc.c | 4 
 tcg/i386/tcg-target.inc.c| 4 
 tcg/mips/tcg-target.inc.c| 4 
 tcg/ppc/tcg-target.inc.c | 4 
 tcg/riscv/tcg-target.inc.c   | 4 
 tcg/s390/tcg-target.inc.c| 4 
 tcg/sparc/tcg-target.inc.c   | 4 
 tcg/tcg.c| 2 ++
 tcg/tci/tcg-target.inc.c | 4 
 10 files changed, 38 insertions(+)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index eefa929948..c66f3cb857 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -2539,6 +2539,10 @@ QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
 /* We're expecting to use a single ADDI insn.  */
 QEMU_BUILD_BUG_ON(FRAME_SIZE - PUSH_SIZE > 0xfff);
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
 TCGReg r;
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index abf0c444b4..8f919c7641 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -2284,6 +2284,10 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
 }
 }
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
and tcg_register_jit.  */
 
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index d5ed9f1ffd..b210977800 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -3510,6 +3510,10 @@ static const int tcg_target_callee_save_regs[] = {
   + TCG_TARGET_STACK_ALIGN - 1) \
  & ~(TCG_TARGET_STACK_ALIGN - 1))
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c
index 412cacdcb9..2bb976a9a5 100644
--- a/tcg/mips/tcg-target.inc.c
+++ b/tcg/mips/tcg-target.inc.c
@@ -2471,6 +2471,10 @@ static tcg_insn_unit *align_code_ptr(TCGContext *s)
 return s->code_ptr;
 }
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 /* Stack frame parameters.  */
 #define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
 #define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
index 36b4791707..f4efca8f7b 100644
--- a/tcg/ppc/tcg-target.inc.c
+++ b/tcg/ppc/tcg-target.inc.c
@@ -1904,6 +1904,10 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
 }
 }
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 /* Parameters for function call generation, used in tcg.c.  */
 #define TCG_TARGET_STACK_ALIGN   16
 #define TCG_TARGET_EXTEND_ARGS   1
diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
index 2932505094..5780537b73 100644
--- a/tcg/riscv/tcg-target.inc.c
+++ b/tcg/riscv/tcg-target.inc.c
@@ -1798,6 +1798,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 }
 }
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 static const int tcg_target_callee_save_regs[] = {
 TCG_REG_S0,   /* used for the global env (TCG_AREG0) */
 TCG_REG_S1,
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
index 3d6150b10e..924bd01afd 100644
--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -2499,6 +2499,10 @@ static void query_s390_facilities(void)
 }
 }
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 static void tcg_target_init(TCGContext *s)
 {
 query_s390_facilities();
diff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c
index 7a61839dc1..f795e78153 100644
--- a/tcg/sparc/tcg-target.inc.c
+++ b/tcg/sparc/tcg-target.inc.c
@@ -1004,6 +1004,10 @@ static void build_trampolines(TCGContext *s)
 }
 #endif
 
+static inline void tcg_out_start(TCGContext *s)
+{
+}
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index f7bef51de8..c8832c3ccf 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -101,6 +101,7 @@ static void tcg_register_jit_int(void *buf, size_t size,
 /* Forward declarations for functions declared and used in tcg-target.inc.c. */
 static const char *target_parse_constraint(TCGArgConstraint *ct,
const char *ct_str, TCGType type);
+static void tcg_out_start(TCGContext *s);
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
intptr_t arg2);
 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
@@ -3925,6 +3926,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
 #endif
 
 num_insns = -1;
+tcg_out_start(s);
 

[Qemu-devel] [PATCH 3/9] coroutine: add host specific coroutine backend for 64-bit x86

2019-05-04 Thread Paolo Bonzini
This backend is faster (100ns vs 150ns per switch on my laptop), but
especially it will be possible to add CET support to it.  Most of the
code is actually not architecture specific.

Signed-off-by: Paolo Bonzini 
---
 configure|  10 ++
 scripts/qemugdb/coroutine.py |   5 +-
 scripts/qemugdb/coroutine_asm.py |  20 +++
 util/Makefile.objs   |   1 +
 util/coroutine-asm.c | 230 +++
 5 files changed, 264 insertions(+), 2 deletions(-)
 create mode 100644 scripts/qemugdb/coroutine_asm.py
 create mode 100644 util/coroutine-asm.c

diff --git a/configure b/configure
index 5b183c2e39..c01f57a3ae 100755
--- a/configure
+++ b/configure
@@ -5200,6 +5200,8 @@ fi
 if test "$coroutine" = ""; then
   if test "$mingw32" = "yes"; then
 coroutine=win32
+  elif test "$cpu" = "x86_64"; then
+ coroutine=asm
   elif test "$ucontext_works" = "yes"; then
 coroutine=ucontext
   else
@@ -5225,6 +5227,14 @@ else
   error_exit "only the 'windows' coroutine backend is valid for Windows"
 fi
 ;;
+  asm)
+if test "$mingw32" = "yes"; then
+  error_exit "only the 'windows' coroutine backend is valid for Windows"
+fi
+if test "$cpu" != "x86_64"; then
+  error_exit "the 'asm' backend is only valid for x86_64 hosts"
+fi
+;;
   *)
 error_exit "unknown coroutine backend $coroutine"
 ;;
diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index 076f6808ab..dc760235e7 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -10,14 +10,15 @@
 # This work is licensed under the terms of the GNU GPL, version 2
 # or later.  See the COPYING file in the top-level directory.
 
-from . import coroutine_ucontext
+from . import coroutine_ucontext, coroutine_asm
 import gdb
 
 VOID_PTR = gdb.lookup_type('void').pointer()
 UINTPTR_T = gdb.lookup_type('uintptr_t')
 
 backends = {
-'CoroutineUContext': coroutine_ucontext
+'CoroutineUContext': coroutine_ucontext,
+'CoroutineAsm': coroutine_asm
 }
 
 def coroutine_backend():
diff --git a/scripts/qemugdb/coroutine_asm.py b/scripts/qemugdb/coroutine_asm.py
new file mode 100644
index 00..b4ac1291db
--- /dev/null
+++ b/scripts/qemugdb/coroutine_asm.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+# GDB debugging support
+#
+# Copyright 2019 Red Hat, Inc.
+#
+# Authors:
+#  Paolo Bonzini 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+import gdb
+
+U64_PTR = gdb.lookup_type('uint64_t').pointer()
+
+def get_coroutine_regs(addr):
+addr = addr.cast(gdb.lookup_type('CoroutineAsm').pointer())
+rsp = addr['sp'].cast(U64_PTR)
+return {'sp': rsp, 'pc': rsp.dereference()}
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 9206878dec..41a10539cf 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -39,6 +39,7 @@ util-obj-$(CONFIG_MEMBARRIER) += sys_membarrier.o
 util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
 util-obj-y += qemu-coroutine-sleep.o
 util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
+coroutine-asm.o-cflags := -mno-red-zone
 util-obj-y += buffer.o
 util-obj-y += timed-average.o
 util-obj-y += base64.o
diff --git a/util/coroutine-asm.c b/util/coroutine-asm.c
new file mode 100644
index 00..a06ecbcb0a
--- /dev/null
+++ b/util/coroutine-asm.c
@@ -0,0 +1,230 @@
+/*
+ * Host-specific coroutine initialization code
+ *
+ * Copyright (C) 2006  Anthony Liguori 
+ * Copyright (C) 2011  Kevin Wolf 
+ * Copyright (C) 2019  Paolo Bonzini 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/coroutine_int.h"
+
+#ifdef CONFIG_VALGRIND_H
+#include 
+#endif
+
+#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+#ifdef CONFIG_ASAN_IFACE_FIBER
+#define CONFIG_ASAN 1
+#include 
+#endif
+#endif
+
+#define COROUTINE_SHADOW_STACK_SIZE4096
+
+typedef struct {
+Coroutine base;
+void *sp;
+
+void *stack;
+size_t stack_size;
+
+#ifdef CONFIG_VALGRIND_H
+unsigned int valgrind_stack_id;
+#endif
+} CoroutineAsm;
+
+/**
+ * Per-thread coroutine bookkeeping
+ */
+static __thread CoroutineAsm leader;
+static __thread Coroutine *current;
+
+static void 

[Qemu-devel] [PATCH 2/9] qemugdb: allow adding support for other architectures

2019-05-04 Thread Paolo Bonzini
$sp and $pc are standard register names that are available
on most machines, use them instead of $rsp and $rip so that
other architectures can use qemu_coroutine_sp and
qemu_coroutine_pc.

Signed-off-by: Paolo Bonzini 
---
 scripts/qemugdb/coroutine.py  | 4 ++--
 scripts/qemugdb/coroutine_ucontext.py | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index db2753d949..076f6808ab 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -62,11 +62,11 @@ class CoroutineSPFunction(gdb.Function):
 gdb.Function.__init__(self, 'qemu_coroutine_sp')
 
 def invoke(self, addr):
-return 
coroutine_backend().get_coroutine_regs(addr)['rsp'].cast(VOID_PTR)
+return 
coroutine_backend().get_coroutine_regs(addr)['sp'].cast(VOID_PTR)
 
 class CoroutinePCFunction(gdb.Function):
 def __init__(self):
 gdb.Function.__init__(self, 'qemu_coroutine_pc')
 
 def invoke(self, addr):
-return 
coroutine_backend().get_coroutine_regs(addr)['rip'].cast(VOID_PTR)
+return 
coroutine_backend().get_coroutine_regs(addr)['pc'].cast(VOID_PTR)
diff --git a/scripts/qemugdb/coroutine_ucontext.py 
b/scripts/qemugdb/coroutine_ucontext.py
index a2f8c1dbbf..eed095be22 100644
--- a/scripts/qemugdb/coroutine_ucontext.py
+++ b/scripts/qemugdb/coroutine_ucontext.py
@@ -57,12 +57,12 @@ def get_jmpbuf_regs(jmpbuf):
 pointer_guard = get_glibc_pointer_guard()
 return {'rbx': jmpbuf[JB_RBX],
 'rbp': glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard),
-'rsp': glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard),
+'sp': glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard),
 'r12': jmpbuf[JB_R12],
 'r13': jmpbuf[JB_R13],
 'r14': jmpbuf[JB_R14],
 'r15': jmpbuf[JB_R15],
-'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) }
+'pc': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) }
 
 def get_coroutine_regs(addr):
 co = addr.cast(gdb.lookup_type('CoroutineUContext').pointer())
-- 
2.21.0





[Qemu-devel] [PATCH 8/9] tcg/i386: add support for IBT

2019-05-04 Thread Paolo Bonzini
Add endbr annotations before indirect branch targets.  This lets QEMU enable
IBT even for TCG-enabled builds.

Signed-off-by: Paolo Bonzini 
---
 Makefile.target   |  2 ++
 configure |  9 +
 include/qemu/cpuid.h  |  5 +
 tcg/i386/tcg-target.inc.c | 19 +++
 4 files changed, 35 insertions(+)

diff --git a/Makefile.target b/Makefile.target
index 667682779b..d168ee7555 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -112,8 +112,10 @@ obj-y += accel/
 obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o
 obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o
 ifeq ($(CONFIG_CF_PROTECTION),y)
+ifneq ($(CONFIG_CF_PROTECTION_TCG),y)
 tcg/tcg.o-cflags := -fcf-protection=return
 endif
+endif
 obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-$(CONFIG_TCG) += fpu/softfloat.o
diff --git a/configure b/configure
index 946ff7825a..c02a5f4b79 100755
--- a/configure
+++ b/configure
@@ -5200,6 +5200,11 @@ fi
 if test "$cf_protection" = "yes"; then
   QEMU_CFLAGS="-fcf-protection $QEMU_CFLAGS"
 fi
+if test "$cpu" = "x86_64"; then
+  cf_protection_tcg=yes
+else
+  cf_protection_tcg=no
+fi
 
 ##
 # check and set a backend for coroutine
@@ -6395,6 +6400,7 @@ echo "TCG support   $tcg"
 if test "$tcg" = "yes" ; then
 echo "TCG debug enabled $debug_tcg"
 echo "TCG interpreter   $tcg_interpreter"
+echo "TCG CF protection $cf_protection_tcg"
 fi
 echo "malloc trim support $malloc_trim"
 echo "RDMA support  $rdma"
@@ -6600,6 +6606,9 @@ fi
 if test "$cf_protection" = "yes" ; then
   echo "CONFIG_CF_PROTECTION=y" >> $config_host_mak
 fi
+if test "$cf_protection_tcg" = "yes" ; then
+  echo "CONFIG_CF_PROTECTION_TCG=y" >> $config_host_mak
+fi
 if test "$slirp" != "no"; then
   echo "CONFIG_SLIRP=y" >> $config_host_mak
   echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 69301700bd..e32fb209f5 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -49,6 +49,11 @@
 #define bit_BMI2(1 << 8)
 #endif
 
+/* Leaf 7, %edx */
+#ifndef bit_IBT
+#define bit_IBT (1 << 20)
+#endif
+
 /* Leaf 0x8001, %ecx */
 #ifndef bit_LZCNT
 #define bit_LZCNT   (1 << 5)
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index b210977800..cb3de2f7ac 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -159,10 +159,12 @@ bool have_avx2;
 static bool have_movbe;
 static bool have_bmi2;
 static bool have_lzcnt;
+static bool have_ibt;
 #else
 # define have_movbe 0
 # define have_bmi2 0
 # define have_lzcnt 0
+# define have_ibt 1
 #endif
 
 static tcg_insn_unit *tb_ret_addr;
@@ -809,6 +811,19 @@ static inline void tgen_arithr(TCGContext *s, int subop, 
int dest, int src)
 tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
 }
 
+static void tcg_out_endbr(TCGContext *s)
+{
+if (have_ibt) {
+#if defined __CET__ && (__CET__ & 1)
+#ifdef __x86_64__
+tcg_out32(s, 0xfa1e0ff3);
+#else
+tcg_out32(s, 0xfb1e0ff3);
+#endif
+#endif
+}
+}
+
 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
 {
 int rexw = 0;
@@ -3512,6 +3527,7 @@ static const int tcg_target_callee_save_regs[] = {
 
 static inline void tcg_out_start(TCGContext *s)
 {
+tcg_out_endbr(s);
 }
 
 /* Generate global QEMU prologue and epilogue code */
@@ -3520,6 +3536,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 int i, stack_addend;
 
 /* TB prologue */
+tcg_out_endbr(s);
 
 /* Reserve some stack space, also for TCG temps.  */
 stack_addend = FRAME_SIZE - PUSH_SIZE;
@@ -3566,6 +3583,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
  * and fall through to the rest of the epilogue.
  */
 s->code_gen_epilogue = s->code_ptr;
+tcg_out_endbr(s);
 tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0);
 
 /* TB epilogue */
@@ -3598,6 +3616,7 @@ static void tcg_target_init(TCGContext *s)
 __cpuid_count(7, 0, a, b7, c, d);
 have_bmi1 = (b7 & bit_BMI) != 0;
 have_bmi2 = (b7 & bit_BMI2) != 0;
+have_ibt = (d & bit_IBT) != 0;
 }
 
 if (max >= 1) {
-- 
2.21.0





[Qemu-devel] [PATCH 5/9] coroutine: add host specific coroutine backend for 64-bit s390

2019-05-04 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 util/coroutine-asm.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/util/coroutine-asm.c b/util/coroutine-asm.c
index de68e98622..a9a80e9c71 100644
--- a/util/coroutine-asm.c
+++ b/util/coroutine-asm.c
@@ -41,7 +41,7 @@ typedef struct {
 void *sp;
 
 /*
- * aarch64: instruction pointer
+ * aarch64, s390x: instruction pointer
  */
 void *scratch;
 
@@ -161,6 +161,40 @@ static void start_switch_fiber(void **fake_stack_save,
   (to)->scratch = (void *) coroutine_trampoline;   
   \
   (void) CO_SWITCH_RET(from, to, (uintptr_t) to);  
   \
 } while(0)
+
+#elif defined __s390x__
+#define CO_SWITCH_RET(from, to, action) ({ 
   \
+register uintptr_t action_ __asm__("r2") = action; 
   \
+register void *from_ __asm__("r1") = from; 
   \
+register void *to_ __asm__("r3") = to; 
   \
+register void *pc_ __asm__("r4") = to->scratch;
   \
+void *save_r13;
   \
+asm volatile(  
   \
+"stg %%r13, %[SAVE_R13]\n" 
   \
+"stg %%r15, %[SP](%%r1)\n"   /* save source SP */  
   \
+"lg %%r15, %[SP](%%r3)\n"/* load destination SP */ 
   \
+"bras %%r3, 1f\n"/* source PC will be after the BR */  
   \
+"1: aghi %%r3, 12\n" /* 4 */   
   \
+"stg %%r3, %[SCRATCH](%%r1)\n"   /* 6 save switch-back PC */   
   \
+"br %%r4\n"  /* 2 jump to destination PC */
   \
+"lg %%r13, %[SAVE_R13]\n"  
   \
+: "+r" (action_), "+r" (from_), "+r" (to_), "+r" (pc_),
   \
+  [SAVE_R13] "+m" (r13)
   \
+: [SP] "i" (offsetof(CoroutineAsm, sp)),   
   \
+  [SCRATCH] "i" (offsetof(CoroutineAsm, scratch))  
   \
+: "r0", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14",  
   \
+  "a2", "a3", "a4", "a5", "a6", "a7",  
   \
+  "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
   \
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  
   \
+  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "memory"); 
   \
+action_;   
   \
+})
+
+#define CO_SWITCH_NEW(from, to) do {   
   \
+  (to)->scratch = (void *) coroutine_trampoline;   
   \
+  (to)->sp -= 160; 
   \
+  (void) CO_SWITCH_RET(from, to, (uintptr_t) to);  
   \
+} while(0)
 #else
 #error coroutine-asm.c not ported to this architecture.
 #endif
-- 
2.21.0





[Qemu-devel] [PATCH 0/9] Assembly coroutine backend and x86 CET support

2019-05-04 Thread Paolo Bonzini
*** BLURB HERE ***

Paolo Bonzini (10):
  qemugdb: allow adding support for other coroutine backends
  qemugdb: allow adding support for other architectures
  coroutine: add host specific coroutine backend for 64-bit x86
  coroutine: add host specific coroutine backend for 64-bit ARM
  coroutine: add host specific coroutine backend for 64-bit s390
  configure: add control-flow protection support
  tcg: add tcg_out_start
  tcg/i386: add support for IBT
  linux-user: add IBT support to x86 safe-syscall.S
  coroutine-asm: add x86 CET shadow stack support

 Makefile.target   |   5 +
 configure |  62 
 include/qemu/cpuid.h  |   5 +
 linux-user/host/i386/safe-syscall.inc.S   |  19 ++
 linux-user/host/x86_64/safe-syscall.inc.S |  19 ++
 scripts/qemugdb/coroutine.py  | 107 ++
 scripts/qemugdb/coroutine_asm.py  |  24 ++
 scripts/qemugdb/coroutine_ucontext.py |  69 
 tcg/aarch64/tcg-target.inc.c  |   4 +
 tcg/arm/tcg-target.inc.c  |   4 +
 tcg/i386/tcg-target.inc.c |  23 ++
 tcg/mips/tcg-target.inc.c |   4 +
 tcg/ppc/tcg-target.inc.c  |   4 +
 tcg/riscv/tcg-target.inc.c|   4 +
 tcg/s390/tcg-target.inc.c |   4 +
 tcg/sparc/tcg-target.inc.c|   4 +
 tcg/tcg.c |   2 +
 tcg/tci/tcg-target.inc.c  |   4 +
 util/Makefile.objs|  10 +
 util/coroutine-asm.c  | 387 ++
 20 files changed, 689 insertions(+), 75 deletions(-)
 create mode 100644 scripts/qemugdb/coroutine_asm.py
 create mode 100644 scripts/qemugdb/coroutine_ucontext.py
 create mode 100644 util/coroutine-asm.c

-- 
2.21.0




[Qemu-devel] [PATCH 1/9] qemugdb: allow adding support for other coroutine backends

2019-05-04 Thread Paolo Bonzini
Split the jmpbuf access to a separate module and dispatch based
on which CoroutineXYZ type is defined.

Signed-off-by: Paolo Bonzini 
---
 scripts/qemugdb/coroutine.py  | 106 --
 scripts/qemugdb/coroutine_ucontext.py |  69 +
 2 files changed, 100 insertions(+), 75 deletions(-)
 create mode 100644 scripts/qemugdb/coroutine_ucontext.py

diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
index 41e079d0e2..db2753d949 100644
--- a/scripts/qemugdb/coroutine.py
+++ b/scripts/qemugdb/coroutine.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 
-# GDB debugging support
+# GDB debugging support, coroutine dispatch
 #
 # Copyright 2012 Red Hat, Inc. and/or its affiliates
 #
@@ -10,82 +10,25 @@
 # This work is licensed under the terms of the GNU GPL, version 2
 # or later.  See the COPYING file in the top-level directory.
 
+from . import coroutine_ucontext
 import gdb
 
 VOID_PTR = gdb.lookup_type('void').pointer()
+UINTPTR_T = gdb.lookup_type('uintptr_t')
 
-def get_fs_base():
-'''Fetch %fs base value using arch_prctl(ARCH_GET_FS).  This is
-   pthread_self().'''
-# %rsp - 120 is scratch space according to the SystemV ABI
-old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
-gdb.execute('call (int)arch_prctl(0x1003, $rsp - 120)', False, True)
-fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
-gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True)
-return fs_base
-
-def pthread_self():
-'''Fetch pthread_self() from the glibc start_thread function.'''
-f = gdb.newest_frame()
-while f.name() != 'start_thread':
-f = f.older()
-if f is None:
-return get_fs_base()
-
-try:
-return f.read_var("arg")
-except ValueError:
-return get_fs_base()
-
-def get_glibc_pointer_guard():
-'''Fetch glibc pointer guard value'''
-fs_base = pthread_self()
-return gdb.parse_and_eval('*(uint64_t*)((uint64_t)%s + 0x30)' % fs_base)
-
-def glibc_ptr_demangle(val, pointer_guard):
-'''Undo effect of glibc's PTR_MANGLE()'''
-return gdb.parse_and_eval('(((uint64_t)%s >> 0x11) | ((uint64_t)%s << (64 
- 0x11))) ^ (uint64_t)%s' % (val, val, pointer_guard))
-
-def get_jmpbuf_regs(jmpbuf):
-JB_RBX  = 0
-JB_RBP  = 1
-JB_R12  = 2
-JB_R13  = 3
-JB_R14  = 4
-JB_R15  = 5
-JB_RSP  = 6
-JB_PC   = 7
-
-pointer_guard = get_glibc_pointer_guard()
-return {'rbx': jmpbuf[JB_RBX],
-'rbp': glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard),
-'rsp': glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard),
-'r12': jmpbuf[JB_R12],
-'r13': jmpbuf[JB_R13],
-'r14': jmpbuf[JB_R14],
-'r15': jmpbuf[JB_R15],
-'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) }
-
-def bt_jmpbuf(jmpbuf):
-'''Backtrace a jmpbuf'''
-regs = get_jmpbuf_regs(jmpbuf)
-old = dict()
-
-for i in regs:
-old[i] = gdb.parse_and_eval('(uint64_t)$%s' % i)
-
-for i in regs:
-gdb.execute('set $%s = %s' % (i, regs[i]))
-
-gdb.execute('bt')
-
-for i in regs:
-gdb.execute('set $%s = %s' % (i, old[i]))
-
-def coroutine_to_jmpbuf(co):
-coroutine_pointer = co.cast(gdb.lookup_type('CoroutineUContext').pointer())
-return coroutine_pointer['env']['__jmpbuf']
+backends = {
+'CoroutineUContext': coroutine_ucontext
+}
 
+def coroutine_backend():
+for k, v in backends.items():
+try:
+gdb.lookup_type(k)
+except:
+continue
+return v
+
+raise Exception('could not find coroutine backend')
 
 class CoroutineCommand(gdb.Command):
 '''Display coroutine backtrace'''
@@ -99,18 +42,31 @@ class CoroutineCommand(gdb.Command):
 gdb.write('usage: qemu coroutine \n')
 return
 
-bt_jmpbuf(coroutine_to_jmpbuf(gdb.parse_and_eval(argv[0])))
+addr = gdb.parse_and_eval(argv[0])
+regs = coroutine_backend().get_coroutine_regs(addr)
+old = dict()
+
+for i in regs:
+old[i] = gdb.parse_and_eval('(uint64_t)$%s' % i)
+
+for i in regs:
+gdb.execute('set $%s = %s' % (i, regs[i].cast(UINTPTR_T)))
+
+gdb.execute('bt')
+
+for i in regs:
+gdb.execute('set $%s = %s' % (i, old[i].cast(UINTPTR_T)))
 
 class CoroutineSPFunction(gdb.Function):
 def __init__(self):
 gdb.Function.__init__(self, 'qemu_coroutine_sp')
 
 def invoke(self, addr):
-return get_jmpbuf_regs(coroutine_to_jmpbuf(addr))['rsp'].cast(VOID_PTR)
+return 
coroutine_backend().get_coroutine_regs(addr)['rsp'].cast(VOID_PTR)
 
 class CoroutinePCFunction(gdb.Function):
 def __init__(self):
 gdb.Function.__init__(self, 'qemu_coroutine_pc')
 
 def invoke(self, addr):
-return get_jmpbuf_regs(coroutine_to_jmpbuf(addr))['rip'].cast(VOID_PTR)
+return 
coroutine_backend().get_coroutine_regs(addr)['rip'].cast(VOID_PTR)

Re: [Qemu-devel] [PATCH v2 0/2] Acceptance Tests: Test the Raspberry Pi 2 board

2019-05-04 Thread Philippe Mathieu-Daudé
On 3/13/19 12:45 AM, Philippe Mathieu-Daudé wrote:
> Add the raspi2 to the list of boards tested by the
> boot_linux_console Avocado test.
> 
> Based on "Acceptance Tests: target architecture support" v5:
> https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg04111.html
> Based-on: <20190312171824.5134-1-cr...@redhat.com>
> 
> Philippe Mathieu-Daudé (2):
>   BootLinuxConsoleTest: Let extract_from_deb handle various compressions
>   Boot Linux Console Test: add a test for the Raspberry Pi 2
> 
>  tests/acceptance/boot_linux_console.py | 34 --
>  1 file changed, 32 insertions(+), 2 deletions(-)

I was hoping this series would be included in "Acceptance Tests: target
architecture support" by Eduardo (removing the 'print' debug line) but I
just realized I forgot to Cc him :S



Re: [Qemu-devel] [PATCH] tests/tcg/alpha: add system boot.S

2019-05-04 Thread Alex Bennée


Richard Henderson  writes:

> On 5/3/19 10:07 AM, Alex Bennée wrote:
>> +ldah$sp, $stack_end($gp)!gprelhigh
>> +lda $sp, $stack_end($gp)!gprellow
>
> Bah.    $sp
>
> As is, this works only because the test case is tiny, and this happens to
> evaluate to the middle of the stack allocation.

cool. that fixes the exception I was seeing while running the
cleaned up memory test.

--
Alex Bennée



Re: [Qemu-devel] [PULL 19/19] configure: automatically pick python3 is available

2019-05-04 Thread Thomas Huth
On 03/05/2019 23.34, Eduardo Habkost wrote:
> On Fri, May 03, 2019 at 06:00:11PM -0300, Eduardo Habkost wrote:
>> On Fri, May 03, 2019 at 06:41:43PM +0200, Thomas Huth wrote:
>>> On 03/05/2019 02.41, Eduardo Habkost wrote:
 From: Daniel P. Berrangé 

 Unless overridden via an env var or configure arg, QEMU will only look
 for the 'python' binary in $PATH. This is unhelpful on distros which
 are only shipping Python 3.x (eg Fedora) in their default install as,
 if they comply with PEP 394, the bare 'python' binary won't exist.

 This changes configure so that by default it will search for all three
 common python binaries, preferring to find Python 3.x versions.

 Signed-off-by: Daniel P. Berrangé 
 Message-Id: <20190327170701.23798-1-berra...@redhat.com>
 Signed-off-by: Eduardo Habkost 
 ---
  configure | 18 +++---
  1 file changed, 15 insertions(+), 3 deletions(-)
>>>
>>> I haven't bisected it, but I think this patch here broke the gitlab-ci 
>>> tests:
>>>
>>>  https://gitlab.com/huth/qemu/-/jobs/206806257
>>>
>>> Seems like the test is now failing when you don't have an UTF-8 locale:
>>>
>>>  LANG=C make check-qapi-schema
>>
>> I couldn't reproduce it this way, probably because I'm running Python 3.7 
>> which
>> implements PEP 538 ("Coercing the legacy C locale to a UTF-8 based locale").
>>
>> But I can force it to break using:
>>
>>   PYTHONIOENCODING=ascii make check-qapi-schema
>>
>>>  [...]
>>>  TESTtests/qapi-schema/union-base-empty.out
>>>  --- /builds/huth/qemu/tests/qapi-schema/unicode-str.err2019-05-03 
>>> 15:21:39.0 +
>>>  +++ -  2019-05-03 15:42:01.561762978 +
>>>  @@ -1 +1 @@
>>>  -tests/qapi-schema/unicode-str.json:2: 'command' uses invalid name 'é'
>>>  +tests/qapi-schema/unicode-str.json:2: 'command' uses invalid name '\xe9'
>>>  /builds/huth/qemu/tests/Makefile.include:1105: recipe for target 
>>> 'check-tests/qapi-schema/unicode-str.json' failed
>>>  make: *** [check-tests/qapi-schema/unicode-str.json] Error 1
>>>
>>> Any ideas how to fix this?
>>
>> Probably we just need to specify an explicit encoding at the statement that
>> prints the error message to stderr.  I will give it a try.
> 
> Forcing a specific encoding inside test-qapi.py would very easy
> on Python 3.7+ (sys.stderr.reconfigure(...)), but tricky on older
> versions.  I believe this is the simplest way to fix the problem
> on Python 3.5 and 3.6.
> 
> Can somebody confirm this really fixes the problem on gitlab-ci?
> 
> ---
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 7c8b9c84b2..af88ab6f8b 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -1103,7 +1103,7 @@ check-tests/qemu-iotests-quick.sh: 
> tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
>  .PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
>  $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: 
> $(SRC_PATH)/%.json
>   $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
> - $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
> + PYTHONIOENCODING=utf-8 $(PYTHON) 
> $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
>   $^ >$*.test.out 2>$*.test.err; \
>   echo $$? >$*.test.exit, \
>   "TEST","$*.out")

Yes, thanks, this seems to fix this issue:

 https://gitlab.com/huth/qemu/-/jobs/207041381

It also works on my laptop now (which uses Python 3.6).

 Thomas



Re: [Qemu-devel] Failing QEMU iotest 175

2019-05-04 Thread Thomas Huth
On 03/05/2019 22.21, Eric Blake wrote:
> On 5/2/19 11:37 PM, Thomas Huth wrote:
>> On 02/05/2019 23.56, Eric Blake wrote:
>>> On 4/28/19 10:18 AM, Thomas Huth wrote:
 QEMU iotest 175 is failing for me when I run it with -raw:

  == creating image with default preallocation ==
  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 -size=1048576, blocks=0
 +size=1048576, blocks=2
>>>
>>> What filesystem?
>>
>> ext4
> 
> Hmm, it's passing for me on ext4, but that probably means we have
> different configuration parameters. I'm not sure how to easily show what
> parameters a particular ext4 partition uses to compare the differences
> between your setup and mine (mine is tuned to whatever defaults Fedora's
> installer chose on my behalf), so maybe someone else can chime in.

$ sudo tune2fs -l /dev/mapper/Home
tune2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   
Last mounted on:  /home
Filesystem magic number:  0xEF53
Filesystem revision #:1 (dynamic)
Filesystem features:  has_journal ext_attr dir_index filetype
needs_recovery meta_bg extent 64bit flex_bg sparse_super large_file
huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options:user_xattr acl
Filesystem state: clean
Errors behavior:  Continue
Filesystem OS type:   Linux
Inode count:  36700160
Block count:  146800640
Reserved block count: 5873663
Free blocks:  56266267
Free inodes:  35403275
First block:  1
Block size:   1024
Fragment size:1024
Group descriptor size:64
Blocks per group: 8192
Fragments per group:  8192
Inodes per group: 2048
Inode blocks per group:   256
First meta block group:   258
Flex block group size:16
Filesystem created:   Thu Apr 19 18:34:33 2018
Last mount time:  Sat May  4 08:20:36 2019
Last write time:  Sat May  4 08:20:36 2019
Mount count:  224
Maximum mount count:  -1
Last checked: Thu Apr 19 18:34:33 2018
Check interval:   0 ()
Lifetime writes:  1826 GB
Reserved blocks uid:  0 (user root)
Reserved blocks gid:  0 (group root)
First inode:  11
Inode size:   128
Journal inode:8
First orphan inode:   11076944
Default directory hash:   half_md4
Directory Hash Seed:  08e1be04-c3a3-4c37-a059-cf54af5c4bc0
Journal backup:   inode blocks

IIRC I talked to stefanha on IRC about this some weeks ago already, and
he was able to reproduce the problem when using a certain parameter to
create the file system. However, I fail to remember which parameter it
was. Maybe Stefan still remembers...

 Thomas



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PULL 19/19] configure: automatically pick python3 is available

2019-05-04 Thread Thomas Huth
On 03/05/2019 19.04, Philippe Mathieu-Daudé wrote:
> On 5/3/19 6:41 PM, Thomas Huth wrote:
>> On 03/05/2019 02.41, Eduardo Habkost wrote:
>>> From: Daniel P. Berrangé 
>>>
>>> Unless overridden via an env var or configure arg, QEMU will only look
>>> for the 'python' binary in $PATH. This is unhelpful on distros which
>>> are only shipping Python 3.x (eg Fedora) in their default install as,
>>> if they comply with PEP 394, the bare 'python' binary won't exist.
>>>
>>> This changes configure so that by default it will search for all three
>>> common python binaries, preferring to find Python 3.x versions.
>>>
>>> Signed-off-by: Daniel P. Berrangé 
>>> Message-Id: <20190327170701.23798-1-berra...@redhat.com>
>>> Signed-off-by: Eduardo Habkost 
>>> ---
>>>  configure | 18 +++---
>>>  1 file changed, 15 insertions(+), 3 deletions(-)
>>
>> I haven't bisected it, but I think this patch here broke the gitlab-ci tests:
>>
>>  https://gitlab.com/huth/qemu/-/jobs/206806257
> 
> What's the easier way to notice that automatically?

Maybe Peter could tweak one of his acceptance test environments to use a
non-UTF-8 locale?

 Thomas



Re: [Qemu-devel] [PATCH] Deprecate Python 2 support

2019-05-04 Thread Thomas Huth
On 03/05/2019 21.37, Eduardo Habkost wrote:
> Python 2 will reach end of life in January 1 2020.  Declare it as
> deprecated.
> 
> Signed-off-by: Eduardo Habkost 
> ---
>  configure| 8 
>  qemu-deprecated.texi | 8 
>  2 files changed, 16 insertions(+)
> 
> diff --git a/configure b/configure
> index 5b183c2e39..50385061ed 100755
> --- a/configure
> +++ b/configure
> @@ -6461,6 +6461,14 @@ if test "$supported_os" = "no"; then
>  echo "us upstream at qemu-devel@nongnu.org."
>  fi
>  
> +# Note that if the Python conditional here evaluates True we will exit
> +# with status 1 which is a shell 'false' value.
> +if ! $python -c 'import sys; sys.exit(sys.version_info < (3,0))'; then
> +  echo
> +  echo "WARNING: Python 2 support is deprecated" >&2
> +  echo "WARNING: Python 3 will be required for building future versions of 
> QEMU" >&2
> +fi
> +
>  config_host_mak="config-host.mak"
>  
>  echo "# Automatically generated by configure - do not modify" 
> >config-all-disas.mak
> diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
> index 842e71b11d..2f2d9a3e95 100644
> --- a/qemu-deprecated.texi
> +++ b/qemu-deprecated.texi
> @@ -206,3 +206,11 @@ Note that if you are exposing the export via /dev/nbd0, 
> it is easier
>  to just export the entire image and then mount only /dev/nbd0p1 than
>  it is to reinvoke @command{qemu-nbd -c /dev/nbd0} limited to just a
>  subset of the image.
> +
> +@section Build system
> +
> +@subsection Python 2 support (since 4.1.0)
> +
> +In the future, QEMU will require Python 3 to be available at
> +build time.  Support for Python 2 in scripts shipped with QEMU
> +is deprecated.

Reviewed-by: Thomas Huth 



Re: [Qemu-devel] [PATCH] tests/tcg/alpha: add system boot.S

2019-05-04 Thread Richard Henderson
On 5/3/19 10:07 AM, Alex Bennée wrote:
> + ldah$sp, $stack_end($gp)!gprelhigh
> + lda $sp, $stack_end($gp)!gprellow

Bah.    $sp

As is, this works only because the test case is tiny, and this happens to
evaluate to the middle of the stack allocation.


r~



[Qemu-devel] [PATCH] tests/docker: Test more components on the Fedora default image

2019-05-04 Thread Philippe Mathieu-Daudé
Install optional dependencies of QEMU to get better coverage.

The following components are now enabled:

  $ ./configure
  ...
  Multipath support yes
  VNC SASL support  yes
  RDMA support  yes
  PVRDMA supportyes
  libiscsi support  yes
  seccomp support   yes
  libpmem support   yes
  libudev   yes

Note: The udev-devel package is provided by systemd-devel.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/docker/dockerfiles/fedora.docker | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/tests/docker/dockerfiles/fedora.docker 
b/tests/docker/dockerfiles/fedora.docker
index 69d4a7f5d75..afbba29adaa 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -8,6 +8,7 @@ ENV PACKAGES \
 bzip2-devel \
 ccache \
 clang \
+cyrus-sasl-devel \
 device-mapper-multipath-devel \
 findutils \
 flex \
@@ -23,13 +24,17 @@ ENV PACKAGES \
 libaio-devel \
 libasan \
 libattr-devel \
+libblockdev-mpath-devel \
 libcap-devel \
 libcap-ng-devel \
 libcurl-devel \
 libfdt-devel \
+libiscsi-devel \
 libjpeg-devel \
+libpmem-devel \
 libpng-devel \
 librbd-devel \
+libseccomp-devel \
 libssh2-devel \
 libubsan \
 libusbx-devel \
@@ -74,10 +79,12 @@ ENV PACKAGES \
 pixman-devel \
 python3 \
 PyYAML \
+rdma-core-devel \
 SDL2-devel \
 snappy-devel \
 sparse \
 spice-server-devel \
+systemd-devel \
 systemtap-sdt-devel \
 tar \
 usbredir-devel \
-- 
2.20.1




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

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

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

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




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

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

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

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




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

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

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




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

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

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

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




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

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

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




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

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

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

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




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

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

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




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

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

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




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

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

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




[Qemu-devel] [PATCH v3 16/31] tcg/i386: Support vector variable shift opcodes

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

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 241bf19413..b240633455 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -184,7 +184,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_neg_vec  0
 #define TCG_TARGET_HAS_shi_vec  1
 #define TCG_TARGET_HAS_shs_vec  0
-#define TCG_TARGET_HAS_shv_vec  0
+#define TCG_TARGET_HAS_shv_vec  have_avx2
 #define TCG_TARGET_HAS_cmp_vec  1
 #define TCG_TARGET_HAS_mul_vec  1
 #define TCG_TARGET_HAS_sat_vec  1
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 5b33bbd99b..c9448b6d84 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -467,6 +467,11 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_VPBROADCASTQ (0x59 | P_EXT38 | P_DATA16)
 #define OPC_VPERMQ  (0x00 | P_EXT3A | P_DATA16 | P_REXW)
 #define OPC_VPERM2I128  (0x46 | P_EXT3A | P_DATA16 | P_VEXL)
+#define OPC_VPSLLVD (0x47 | P_EXT38 | P_DATA16)
+#define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_REXW)
+#define OPC_VPSRAVD (0x46 | P_EXT38 | P_DATA16)
+#define OPC_VPSRLVD (0x45 | P_EXT38 | P_DATA16)
+#define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_REXW)
 #define OPC_VZEROUPPER  (0x77 | P_EXT)
 #define OPC_XCHG_ax_r32(0x90)
 
@@ -2707,6 +2712,18 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 static int const umax_insn[4] = {
 OPC_PMAXUB, OPC_PMAXUW, OPC_PMAXUD, OPC_UD2
 };
+static int const shlv_insn[4] = {
+/* TODO: AVX512 adds support for MO_16.  */
+OPC_UD2, OPC_UD2, OPC_VPSLLVD, OPC_VPSLLVQ
+};
+static int const shrv_insn[4] = {
+/* TODO: AVX512 adds support for MO_16.  */
+OPC_UD2, OPC_UD2, OPC_VPSRLVD, OPC_VPSRLVQ
+};
+static int const sarv_insn[4] = {
+/* TODO: AVX512 adds support for MO_16, MO_64.  */
+OPC_UD2, OPC_UD2, OPC_VPSRAVD, OPC_UD2
+};
 
 TCGType type = vecl + TCG_TYPE_V64;
 int insn, sub;
@@ -2759,6 +2776,15 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_umax_vec:
 insn = umax_insn[vece];
 goto gen_simd;
+case INDEX_op_shlv_vec:
+insn = shlv_insn[vece];
+goto gen_simd;
+case INDEX_op_shrv_vec:
+insn = shrv_insn[vece];
+goto gen_simd;
+case INDEX_op_sarv_vec:
+insn = sarv_insn[vece];
+goto gen_simd;
 case INDEX_op_x86_punpckl_vec:
 insn = punpckl_insn[vece];
 goto gen_simd;
@@ -3136,6 +3162,9 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_umin_vec:
 case INDEX_op_smax_vec:
 case INDEX_op_umax_vec:
+case INDEX_op_shlv_vec:
+case INDEX_op_shrv_vec:
+case INDEX_op_sarv_vec:
 case INDEX_op_cmp_vec:
 case INDEX_op_x86_shufps_vec:
 case INDEX_op_x86_blend_vec:
@@ -3193,6 +3222,12 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 }
 return 1;
 
+case INDEX_op_shlv_vec:
+case INDEX_op_shrv_vec:
+return have_avx2 && vece >= MO_32;
+case INDEX_op_sarv_vec:
+return have_avx2 && vece == MO_32;
+
 case INDEX_op_mul_vec:
 if (vece == MO_8) {
 /* We can expand the operation for MO_8.  */
-- 
2.17.1




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

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

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

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

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

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




[Qemu-devel] [PATCH] tests/docker: Update the Fedora image to Fedora 30

2019-05-04 Thread Philippe Mathieu-Daudé
Fedora 30 got released:

  https://fedoramagazine.org/announcing-fedora-30/

Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: <20190408201203.28924-1-marcandre.lur...@redhat.com>
  qxl: fix -Waddress-of-packed-member

Based-on: <20190503112654.4393-1-laur...@vivier.eu>
  Pull request trivial branch 2019-05-03
---
 tests/docker/dockerfiles/fedora.docker | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/docker/dockerfiles/fedora.docker 
b/tests/docker/dockerfiles/fedora.docker
index 69d4a7f5d75..1496b68ba15 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,4 +1,4 @@
-FROM fedora:29
+FROM fedora:30
 ENV PACKAGES \
 bc \
 bison \
-- 
2.20.1




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

2019-05-04 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

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




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

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

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

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

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

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

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




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

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

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




[Qemu-devel] [PATCH v3 04/31] tcg: Specify optional vector requirements with a list

2019-05-04 Thread Richard Henderson
Replace the single opcode in .opc with a null-terminated
array in .opt_opc.  We still require that all opcodes be
used with the same .vece.

Validate the contents of this list with CONFIG_DEBUG_TCG.
All tcg_gen_*_vec functions will check any list active
during .fniv expansion.  Swap the active list in and out
as we expand other opcodes, or take control away from the
front-end function.

Convert all existing vector aware front ends.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op-gvec.h   |  24 +--
 tcg/tcg.h   |  20 +++
 target/arm/translate-sve.c  |   9 +-
 target/arm/translate.c  | 123 +-
 target/ppc/translate/vmx-impl.inc.c |   7 +-
 tcg/tcg-op-gvec.c   | 249 
 tcg/tcg-op-vec.c| 102 
 7 files changed, 372 insertions(+), 162 deletions(-)

diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index c093243c4c..ac744ff7c9 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -91,8 +91,8 @@ typedef struct {
 void (*fniv)(unsigned, TCGv_vec, TCGv_vec);
 /* Expand out-of-line helper w/descriptor.  */
 gen_helper_gvec_2 *fno;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The data argument to the out-of-line helper.  */
 int32_t data;
 /* The vector element size, if applicable.  */
@@ -112,8 +112,8 @@ typedef struct {
 gen_helper_gvec_2 *fno;
 /* Expand out-of-line helper w/descriptor, data as argument.  */
 gen_helper_gvec_2i *fnoi;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The vector element size, if applicable.  */
 uint8_t vece;
 /* Prefer i64 to v64.  */
@@ -131,8 +131,8 @@ typedef struct {
 void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
 /* Expand out-of-line helper w/descriptor.  */
 gen_helper_gvec_2i *fno;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The data argument to the out-of-line helper.  */
 uint32_t data;
 /* The vector element size, if applicable.  */
@@ -152,8 +152,8 @@ typedef struct {
 void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
 /* Expand out-of-line helper w/descriptor.  */
 gen_helper_gvec_3 *fno;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The data argument to the out-of-line helper.  */
 int32_t data;
 /* The vector element size, if applicable.  */
@@ -175,8 +175,8 @@ typedef struct {
 void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
 /* Expand out-of-line helper w/descriptor, data in descriptor.  */
 gen_helper_gvec_3 *fno;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The vector element size, if applicable.  */
 uint8_t vece;
 /* Prefer i64 to v64.  */
@@ -194,8 +194,8 @@ typedef struct {
 void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec);
 /* Expand out-of-line helper w/descriptor.  */
 gen_helper_gvec_4 *fno;
-/* The opcode, if any, to which this corresponds.  */
-TCGOpcode opc;
+/* The optional opcodes, if any, utilized by .fniv.  */
+const TCGOpcode *opt_opc;
 /* The data argument to the out-of-line helper.  */
 int32_t data;
 /* The vector element size, if applicable.  */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index cfc57110a1..2c7315da25 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -692,6 +692,7 @@ struct TCGContext {
 #ifdef CONFIG_DEBUG_TCG
 int temps_in_use;
 int goto_tb_issue_mask;
+const TCGOpcode *vecop_list;
 #endif
 
 /* Code generation.  Note that we specifically do not use tcg_insn_unit
@@ -1492,4 +1493,23 @@ void helper_atomic_sto_le_mmu(CPUArchState *env, 
target_ulong addr, Int128 val,
 void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
   TCGMemOpIdx oi, uintptr_t retaddr);
 
+#ifdef CONFIG_DEBUG_TCG
+void tcg_assert_listed_vecop(TCGOpcode);
+#else
+static inline void tcg_assert_listed_vecop(TCGOpcode op) { }
+#endif
+
+static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n)
+{
+#ifdef CONFIG_DEBUG_TCG
+const TCGOpcode *o = tcg_ctx->vecop_list;
+tcg_ctx->vecop_list = n;
+return o;
+#else
+return NULL;
+#endif
+}
+
+bool tcg_can_emit_vecop_list(const TCGOpcode *, TCGType, unsigned);
+
 #endif /* TCG_H */
diff --git a/target/arm/translate-sve.c 

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

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

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

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




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

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

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

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

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

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

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