[Qemu-devel] [PATCH] hw: edu: drop DO_UPCAST

2018-10-12 Thread Li Qiang
Signed-off-by: Li Qiang 
---
 hw/misc/edu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index 0687ffd343..cdcf550dd7 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -342,7 +342,7 @@ static void *edu_fact_thread(void *opaque)
 
 static void pci_edu_realize(PCIDevice *pdev, Error **errp)
 {
-EduState *edu = DO_UPCAST(EduState, pdev, pdev);
+EduState *edu = EDU(pdev);
 uint8_t *pci_conf = pdev->config;
 
 pci_config_set_interrupt_pin(pci_conf, 1);
@@ -365,7 +365,7 @@ static void pci_edu_realize(PCIDevice *pdev, Error **errp)
 
 static void pci_edu_uninit(PCIDevice *pdev)
 {
-EduState *edu = DO_UPCAST(EduState, pdev, pdev);
+EduState *edu = EDU(pdev);
 
 qemu_mutex_lock(>thr_mutex);
 edu->stopping = true;
-- 
2.17.1





[Qemu-devel] [RFC] Require Python 3 for building QEMU

2018-10-12 Thread Eduardo Habkost
Signed-off-by: Eduardo Habkost 
---
I'd like to do this in QEMU 3.1.  I think it's time to drop
support for old systems that have only Python 2.

We still have a few scripts that are not required for building
QEMU that still work only with Python 2 (iotests being the most
relevant set).  Requiring Python 3 for building QEMU won't
prevent people from using those scripts with Python 2 until they
are finally ported.
---
 configure   | 8 
 .travis.yml | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index f89d293585..43b45745dc 100755
--- a/configure
+++ b/configure
@@ -885,7 +885,7 @@ fi
 
 : ${make=${MAKE-make}}
 : ${install=${INSTALL-install}}
-: ${python=${PYTHON-python}}
+: ${python=${PYTHON-python3}}
 : ${smbd=${SMBD-/usr/sbin/smbd}}
 
 # Default objcc to clang if available, otherwise use CC
@@ -1730,13 +1730,13 @@ exit 0
 fi
 
 if ! has $python; then
-  error_exit "Python not found. Use --python=/path/to/python"
+  error_exit "Python 3 not found. Use --python=/path/to/python"
 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 < (2,7))'; then
-  error_exit "Cannot use '$python', Python 2 >= 2.7 or Python 3 is required." \
+if ! $python -c 'import sys; sys.exit(sys.version_info < (3,0))'; then
+  error_exit "Cannot use '$python', Python 3 is required." \
   "Use --python=/path/to/python to specify a supported Python."
 fi
 
diff --git a/.travis.yml b/.travis.yml
index 95be6ec59f..caca9685fa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ sudo: false
 dist: trusty
 language: c
 python:
-  - "2.6"
+  - "3.6"
 compiler:
   - gcc
 cache: ccache
-- 
2.18.0.rc1.1.g3f1ff2140




[Qemu-devel] [PATCH v2 1/2] libnvdimm: nd_region flush callback support

2018-10-12 Thread Pankaj Gupta
This patch adds functionality to perform flush from guest
to host over VIRTIO. We are registering a callback based
on 'nd_region' type. virtio_pmem driver requires this special
flush function. For rest of the region types we are registering
existing flush function. Report error returned by host fsync
failure to userspace. 

This also handles asynchronous flush requests from the block layer 
by creating a child bio and chaining it with parent bio.

Signed-off-by: Pankaj Gupta 
---
 drivers/acpi/nfit/core.c |  4 ++--
 drivers/nvdimm/claim.c   |  6 --
 drivers/nvdimm/nd.h  |  1 +
 drivers/nvdimm/pmem.c| 12 
 drivers/nvdimm/region_devs.c | 38 --
 include/linux/libnvdimm.h|  5 -
 6 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index b072cfc..f154852 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2234,7 +2234,7 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, 
unsigned int bw,
offset = to_interleave_offset(offset, mmio);
 
writeq(cmd, mmio->addr.base + offset);
-   nvdimm_flush(nfit_blk->nd_region);
+   nvdimm_flush(nfit_blk->nd_region, NULL, false);
 
if (nfit_blk->dimm_flags & NFIT_BLK_DCR_LATCH)
readq(mmio->addr.base + offset);
@@ -2283,7 +2283,7 @@ static int acpi_nfit_blk_single_io(struct nfit_blk 
*nfit_blk,
}
 
if (rw)
-   nvdimm_flush(nfit_blk->nd_region);
+   nvdimm_flush(nfit_blk->nd_region, NULL, false);
 
rc = read_blk_stat(nfit_blk, lane) ? -EIO : 0;
return rc;
diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
index fb667bf..a1dfa06 100644
--- a/drivers/nvdimm/claim.c
+++ b/drivers/nvdimm/claim.c
@@ -263,7 +263,7 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
struct nd_namespace_io *nsio = to_nd_namespace_io(>dev);
unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
sector_t sector = offset >> 9;
-   int rc = 0;
+   int rc = 0, ret = 0;
 
if (unlikely(!size))
return 0;
@@ -301,7 +301,9 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
}
 
memcpy_flushcache(nsio->addr + offset, buf, size);
-   nvdimm_flush(to_nd_region(ndns->dev.parent));
+   ret = nvdimm_flush(to_nd_region(ndns->dev.parent), NULL, false);
+   if (ret)
+   rc = ret;
 
return rc;
 }
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 98317e7..d53a2d1 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -160,6 +160,7 @@ struct nd_region {
struct nd_interleave_set *nd_set;
struct nd_percpu_lane __percpu *lane;
struct nd_mapping mapping[0];
+   int (*flush)(struct nd_region *nd_region);
 };
 
 struct nd_blk_region {
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 6071e29..5d6a4a1 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -192,6 +192,7 @@ static blk_status_t pmem_do_bvec(struct pmem_device *pmem, 
struct page *page,
 
 static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
 {
+   int ret = 0;
blk_status_t rc = 0;
bool do_acct;
unsigned long start;
@@ -201,7 +202,7 @@ static blk_qc_t pmem_make_request(struct request_queue *q, 
struct bio *bio)
struct nd_region *nd_region = to_region(pmem);
 
if (bio->bi_opf & REQ_PREFLUSH)
-   nvdimm_flush(nd_region);
+   ret = nvdimm_flush(nd_region, bio, true);
 
do_acct = nd_iostat_start(bio, );
bio_for_each_segment(bvec, bio, iter) {
@@ -216,7 +217,10 @@ static blk_qc_t pmem_make_request(struct request_queue *q, 
struct bio *bio)
nd_iostat_end(bio, start);
 
if (bio->bi_opf & REQ_FUA)
-   nvdimm_flush(nd_region);
+   ret = nvdimm_flush(nd_region, bio, true);
+
+   if (ret)
+   bio->bi_status = errno_to_blk_status(ret);
 
bio_endio(bio);
return BLK_QC_T_NONE;
@@ -528,14 +532,14 @@ static int nd_pmem_remove(struct device *dev)
sysfs_put(pmem->bb_state);
pmem->bb_state = NULL;
}
-   nvdimm_flush(to_nd_region(dev->parent));
+   nvdimm_flush(to_nd_region(dev->parent), NULL, false);
 
return 0;
 }
 
 static void nd_pmem_shutdown(struct device *dev)
 {
-   nvdimm_flush(to_nd_region(dev->parent));
+   nvdimm_flush(to_nd_region(dev->parent), NULL, false);
 }
 
 static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index fa37afc..5508727 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -290,7 +290,9 @@ static ssize_t deep_flush_store(struct device *dev, struct 
device_attribute *att
return rc;

[Qemu-devel] [PATCH v2 2/2] virtio-pmem: Add virtio pmem driver

2018-10-12 Thread Pankaj Gupta
This patch adds virtio-pmem driver for KVM guest.

Guest reads the persistent memory range information from
Qemu over VIRTIO and registers it on nvdimm_bus. It also
creates a nd_region object with the persistent memory
range information so that existing 'nvdimm/pmem' driver
can reserve this into system memory map. This way
'virtio-pmem' driver uses existing functionality of pmem
driver to register persistent memory compatible for DAX
capable filesystems.

This also provides function to perform guest flush over
VIRTIO from 'pmem' driver when userspace performs flush
on DAX memory range.

Signed-off-by: Pankaj Gupta 
---
 drivers/nvdimm/virtio_pmem.c |  84 ++
 drivers/virtio/Kconfig   |  10 
 drivers/virtio/Makefile  |   1 +
 drivers/virtio/pmem.c| 124 +++
 include/linux/virtio_pmem.h  |  60 +++
 include/uapi/linux/virtio_ids.h  |   1 +
 include/uapi/linux/virtio_pmem.h |  10 
 7 files changed, 290 insertions(+)
 create mode 100644 drivers/nvdimm/virtio_pmem.c
 create mode 100644 drivers/virtio/pmem.c
 create mode 100644 include/linux/virtio_pmem.h
 create mode 100644 include/uapi/linux/virtio_pmem.h

diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c
new file mode 100644
index 000..2a1b1ba
--- /dev/null
+++ b/drivers/nvdimm/virtio_pmem.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * virtio_pmem.c: Virtio pmem Driver
+ *
+ * Discovers persistent memory range information
+ * from host and provides a virtio based flushing
+ * interface.
+ */
+#include 
+#include "nd.h"
+
+ /* The interrupt handler */
+void host_ack(struct virtqueue *vq)
+{
+   unsigned int len;
+   unsigned long flags;
+   struct virtio_pmem_request *req, *req_buf;
+   struct virtio_pmem *vpmem = vq->vdev->priv;
+
+   spin_lock_irqsave(>pmem_lock, flags);
+   while ((req = virtqueue_get_buf(vq, )) != NULL) {
+   req->done = true;
+   wake_up(>host_acked);
+
+   if (!list_empty(>req_list)) {
+   req_buf = list_first_entry(>req_list,
+   struct virtio_pmem_request, list);
+   list_del(>req_list);
+   req_buf->wq_buf_avail = true;
+   wake_up(_buf->wq_buf);
+   }
+   }
+   spin_unlock_irqrestore(>pmem_lock, flags);
+}
+EXPORT_SYMBOL_GPL(host_ack);
+
+ /* The request submission function */
+int virtio_pmem_flush(struct nd_region *nd_region)
+{
+   int err;
+   unsigned long flags;
+   struct scatterlist *sgs[2], sg, ret;
+   struct virtio_device *vdev = nd_region->provider_data;
+   struct virtio_pmem *vpmem = vdev->priv;
+   struct virtio_pmem_request *req;
+
+   might_sleep();
+   req = kmalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   req->done = req->wq_buf_avail = false;
+   strcpy(req->name, "FLUSH");
+   init_waitqueue_head(>host_acked);
+   init_waitqueue_head(>wq_buf);
+   sg_init_one(, req->name, strlen(req->name));
+   sgs[0] = 
+   sg_init_one(, >ret, sizeof(req->ret));
+   sgs[1] = 
+
+   spin_lock_irqsave(>pmem_lock, flags);
+   err = virtqueue_add_sgs(vpmem->req_vq, sgs, 1, 1, req, GFP_ATOMIC);
+   if (err) {
+   dev_err(>dev, "failed to send command to virtio pmem 
device\n");
+
+   list_add_tail(>req_list, >list);
+   spin_unlock_irqrestore(>pmem_lock, flags);
+
+   /* When host has read buffer, this completes via host_ack */
+   wait_event(req->wq_buf, req->wq_buf_avail);
+   spin_lock_irqsave(>pmem_lock, flags);
+   }
+   virtqueue_kick(vpmem->req_vq);
+   spin_unlock_irqrestore(>pmem_lock, flags);
+
+   /* When host has read buffer, this completes via host_ack */
+   wait_event(req->host_acked, req->done);
+   err = req->ret;
+   kfree(req);
+
+   return err;
+};
+EXPORT_SYMBOL_GPL(virtio_pmem_flush);
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 3589764..9f634a2 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -42,6 +42,16 @@ config VIRTIO_PCI_LEGACY
 
  If unsure, say Y.
 
+config VIRTIO_PMEM
+   tristate "Support for virtio pmem driver"
+   depends on VIRTIO
+   depends on LIBNVDIMM
+   help
+   This driver provides support for virtio based flushing interface
+   for persistent memory range.
+
+   If unsure, say M.
+
 config VIRTIO_BALLOON
tristate "Virtio balloon driver"
depends on VIRTIO
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 3a2b5c5..143ce91 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -6,3 +6,4 @@ virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
 

[Qemu-devel] [PATCH v2 0/2] kvm "fake DAX" device

2018-10-12 Thread Pankaj Gupta
 This patch series has implementation for "fake DAX". 
 "fake DAX" is fake persistent memory(nvdimm) in guest 
 which allows to bypass the guest page cache. This also
 implements a VIRTIO based asynchronous flush mechanism.  
 
 Sharing guest kernel driver in this patchset with the 
 changes suggested in v1. Tested with Qemu side device 
 emulation for virtio-pmem [4]. 
 
 Details of project idea for 'fake DAX' flushing interface 
 is shared [2] & [3].

 Implementation is divided into two parts:
 New virtio pmem guest driver and qemu code changes for new 
 virtio pmem paravirtualized device.

1. Guest virtio-pmem kernel driver
-
   - Reads persistent memory range from paravirt device and 
 registers with 'nvdimm_bus'.  
   - 'nvdimm/pmem' driver uses this information to allocate 
 persistent memory region and setup filesystem operations 
 to the allocated memory. 
   - virtio pmem driver implements asynchronous flushing 
 interface to flush from guest to host.

2. Qemu virtio-pmem device
-
   - Creates virtio pmem device and exposes a memory range to 
 KVM guest. 
   - At host side this is file backed memory which acts as 
 persistent memory. 
   - Qemu side flush uses aio thread pool API's and virtio 
 for asynchronous guest multi request handling. 

   David Hildenbrand CCed also posted a modified version[5] of 
   qemu virtio-pmem code based on updated Qemu memory device API. 

 Virtio-pmem errors handling:
 
  Checked behaviour of virtio-pmem for below types of errors
  Need suggestions on expected behaviour for handling these errors?

  - Hardware Errors: Uncorrectable recoverable Errors: 
  a] virtio-pmem: 
- As per current logic if error page belongs to Qemu process, 
  host MCE handler isolates(hwpoison) that page and send SIGBUS. 
  Qemu SIGBUS handler injects exception to KVM guest. 
- KVM guest then isolates the page and send SIGBUS to guest 
  userspace process which has mapped the page. 
  
  b] Existing implementation for ACPI pmem driver: 
- Handles such errors with MCE notifier and creates a list 
  of bad blocks. Read/direct access DAX operation return EIO 
  if accessed memory page fall in bad block list.
- It also starts backgound scrubbing.  
- Similar functionality can be reused in virtio-pmem with MCE 
  notifier but without scrubbing(no ACPI/ARS)? Need inputs to 
  confirm if this behaviour is ok or needs any change?

Changes from PATCH v1: [1]
- 0-day build test for build dependency on libnvdimm 

 Changes suggested by - [Dan Williams]
- Split the driver into two parts virtio & pmem  
- Move queuing of async block request to block layer
- Add "sync" parameter in nvdimm_flush function
- Use indirect call for nvdimm_flush
- Don’t move declarations to common global header e.g nd.h
- nvdimm_flush() return 0 or -EIO if it fails
- Teach nsio_rw_bytes() that the flush can fail
- Rename nvdimm_flush() to generic_nvdimm_flush()
- Use 'nd_region->provider_data' for long dereferencing
- Remove virtio_pmem_freeze/restore functions
- Remove BSD license text with SPDX license text

- Add might_sleep() in virtio_pmem_flush - [Luiz]
- Make spin_lock_irqsave() narrow

Changes from RFC v3
- Rebase to latest upstream - Luiz
- Call ndregion->flush in place of nvdimm_flush- Luiz
- kmalloc return check - Luiz
- virtqueue full handling - Stefan
- Don't map entire virtio_pmem_req to device - Stefan
- request leak, correct sizeof req- Stefan
- Move declaration to virtio_pmem.c

Changes from RFC v2:
- Add flush function in the nd_region in place of switching
  on a flag - Dan & Stefan
- Add flush completion function with proper locking and wait
  for host side flush completion - Stefan & Dan
- Keep userspace API in uapi header file - Stefan, MST
- Use LE fields & New device id - MST
- Indentation & spacing suggestions - MST & Eric
- Remove extra header files & add licensing - Stefan

Changes from RFC v1:
- Reuse existing 'pmem' code for registering persistent 
  memory and other operations instead of creating an entirely 
  new block driver.
- Use VIRTIO driver to register memory information with 
  nvdimm_bus and create region_type accordingly. 
- Call VIRTIO flush from existing pmem driver.

Pankaj Gupta (2):
   libnvdimm: nd_region flush callback support
   virtio-pmem: Add virtio-pmem guest driver

[1] https://lkml.org/lkml/2018/8/31/407
[2] https://www.spinics.net/lists/kvm/msg149761.html
[3] https://www.spinics.net/lists/kvm/msg153095.html  
[4] https://lkml.org/lkml/2018/8/31/413
[5] https://marc.info/?l=qemu-devel=153555721901824=2

 drivers/acpi/nfit/core.c |8 ++--
 drivers/nvdimm/claim.c   |   12 --
 drivers/nvdimm/nd.h  |2 +
 drivers/nvdimm/pmem.c|   24 +
 drivers/nvdimm/region_devs.c |   76 ---
 include/linux/libnvdimm.h|   10 

Re: [Qemu-devel] [PATCH 1/1] i386: Add new model of Cascadelake-Server

2018-10-12 Thread Eduardo Habkost
On Wed, Sep 19, 2018 at 11:11:22AM +0800, Tao Xu wrote:
> New CPU models mostly inherit features from ancestor Skylake-Server,
> while addin new features: AVX512_VNNI, Intel PT.
> SSBD support for speculative execution
> side channel mitigations.

Comparing to Skylake-Server, the following features are being
added:

CPUID_7_0_EBX_INTEL_PT, CPUID_7_0_ECX_PKU, CPUID_7_0_ECX_OSPKE,
CPUID_7_0_ECX_AVX512VNNI, CPUID_7_0_EDX_SPEC_CTRL,
CPUID_7_0_EDX_SPEC_CTRL_SSBD.

>From that list, only PKU/OSPKE is not mentioned in the commit
message.  Is this intentional?

Is family/model really supposed to be the same as the one on
Skylake-Server?

> 
> Note:
> 
> On Cascadelake, some capabilities (RDCL_NO, IBRS_ALL, RSBA,
> SKIP_L1DFL_VMENTRY and SSB_NO) are enumerated by MSR.
> These features rely on MSR based feature support patch. 
> Will be added later after that patch's in.
> http://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg00074.html
> 
> Signed-off-by: Tao Xu 
> ---
>  target/i386/cpu.c | 54 +++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index f24295e6e4..670898f32d 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -2386,6 +2386,60 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  .xlevel = 0x8008,
>  .model_id = "Intel Xeon Processor (Skylake, IBRS)",
>  },
> +{
> +.name = "Cascadelake-Server",
> +.level = 0xd,
> +.vendor = CPUID_VENDOR_INTEL,
> +.family = 6,
> +.model = 85,
> +.stepping = 5,
> +.features[FEAT_1_EDX] =
> +CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> +CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA 
> |
> +CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> +CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> +CPUID_DE | CPUID_FP87,
> +.features[FEAT_1_ECX] =
> +CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> +CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
> +CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> +CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
> +CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
> +CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
> +.features[FEAT_8000_0001_EDX] =
> +CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
> +CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> +.features[FEAT_8000_0001_ECX] =
> +CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
> +.features[FEAT_7_0_EBX] =
> +CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
> +CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
> +CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
> +CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
> +CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
> +CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> +CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
> +CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
> +CPUID_7_0_EBX_INTEL_PT,
> +.features[FEAT_7_0_ECX] =
> +CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
> +CPUID_7_0_ECX_AVX512VNNI,
> +.features[FEAT_7_0_EDX] =
> +CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> +/* Missing: XSAVES (not supported by some Linux versions,
> +* including v4.1 to v4.12).
> +* KVM doesn't yet expose any XSAVES state save component,
> +* and the only one defined in Skylake (processor tracing)
> +* probably will block migration anyway.
> +*/
> +.features[FEAT_XSAVE] =
> +CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
> +CPUID_XSAVE_XGETBV1,
> +.features[FEAT_6_EAX] =
> +CPUID_6_EAX_ARAT,
> +.xlevel = 0x8008,
> +.model_id = "Intel Xeon Processor (Cascadelake)",
> +},
>  {
>  .name = "Icelake-Client",
>  .level = 0xd,
> -- 
> 2.17.1
> 
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v4 1/3] Bootstrap Python venv for tests

2018-10-12 Thread Eduardo Habkost
On Fri, Oct 12, 2018 at 11:30:39PM +0200, Philippe Mathieu-Daudé wrote:
> Hi Cleber,
> 
> On 12/10/2018 18:53, Cleber Rosa wrote:
> > A number of QEMU tests are written in Python, and may benefit
> > from an untainted Python venv.
> > 
> > By using make rules, tests that depend on specific Python libs
> > can set that rule as a requirement, along with rules that require
> > the presence or installation of specific libraries.
> > 
> > The tests/venv-requirements.txt is supposed to contain the
> > Python requirements that should be added to the venv created
> > by check-venv.
> 
> Maybe you (or Eduardo...) what you wrote in the cover:
> 
>  There's one current caveat: it requires Python 3, as it's based on the
>  venv module.
> 
> To explain:
> 
> $ make check-acceptance
> /usr/bin/python2: No module named venv
> make: *** [/home/phil/source/qemu/tests/Makefile.include:1033:] Error 1

Oops, this doesn't look very friendly.

But note that this would become a non-issue if we start requiring
Python 3 for building QEMU.


> 
> > 
> > Signed-off-by: Cleber Rosa 
> > ---
> >  tests/Makefile.include  | 20 
> >  tests/venv-requirements.txt |  3 +++
> >  2 files changed, 23 insertions(+)
> >  create mode 100644 tests/venv-requirements.txt
> > 
> > diff --git a/tests/Makefile.include b/tests/Makefile.include
> > index 5eadfd52f9..b66180efa1 100644
> > --- a/tests/Makefile.include
> > +++ b/tests/Makefile.include
> > @@ -12,6 +12,7 @@ check-help:
> > @echo " $(MAKE) check-block  Run block tests"
> > @echo " $(MAKE) check-tcgRun TCG tests"
> > @echo " $(MAKE) check-report.htmlGenerates an HTML test report"
> > +   @echo " $(MAKE) check-venv   Creates a Python venv for tests"
> > @echo " $(MAKE) check-clean  Clean the tests"
> > @echo
> > @echo "Please note that HTML reports do not regenerate if the unit 
> > tests"
> > @@ -1017,6 +1018,24 @@ check-decodetree:
> >./check.sh "$(PYTHON)" "$(SRC_PATH)/scripts/decodetree.py", \
> >TEST, decodetree.py)
> >  
> > +# Python venv for running tests
> > +
> > +.PHONY: check-venv
> > +
> > +TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
> > +TESTS_VENV_REQ=$(SRC_PATH)/tests/venv-requirements.txt
> > +
> > +$(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
> > +   $(call quiet-command, \
> > +$(PYTHON) -m venv --system-site-packages $@, \
> > +VENV, $@)
> > +   $(call quiet-command, \
> > +$(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
> > $(TESTS_VENV_REQ), \
> > +PIP, $(TESTS_VENV_REQ))
> > +   $(call quiet-command, touch $@)
> 
> Hmm maybe we should print something like:
> 
>   "You can now activate this virtual environment using:
> source $(TESTS_VENV_DIR)/tests/venv/bin/activate"

I'm not sure this would be necessary: I expect usage of the venv
to be completely transparent.

If we require people to learn what venv is and manually activate
it, I'd say we have failed to provide usable tools for running
the tests.


> 
> > +
> > +check-venv: $(TESTS_VENV_DIR)
> > +
> >  # Consolidated targets
> >  
> >  .PHONY: check-qapi-schema check-qtest check-unit check check-clean
> > @@ -1030,6 +1049,7 @@ check-clean:
> > rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
> > rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), 
> > $(check-qtest-$(target)-y)) $(check-qtest-generic-y))
> > rm -f tests/test-qapi-gen-timestamp
> > +   rm -rf $(TESTS_VENV_DIR)
> >  
> >  clean: check-clean
> >  
> > diff --git a/tests/venv-requirements.txt b/tests/venv-requirements.txt
> > new file mode 100644
> > index 00..d39f9d1576
> > --- /dev/null
> > +++ b/tests/venv-requirements.txt
> > @@ -0,0 +1,3 @@
> > +# Add Python module requirements, one per line, to be installed
> > +# in the tests/venv Python virtual environment. For more info,
> > +# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
> > 
> 
> Tested-by: Philippe Mathieu-Daudé 

-- 
Eduardo



[Qemu-devel] [PATCH] virtio: Provide version-specific variants of virtio PCI devices

2018-10-12 Thread Eduardo Habkost
The current virtio-*-pci device types actually represent 3
different types of devices:
* virtio 1.0 non-transitional devices
* virtio 1.0 transitional devices
* virtio 0.9 ("legacy device" in virtio 1.0 terminology)

That would be just an annoyance if it didn't break our device/bus
compatibility QMP interfaces.  With this multi-purpose device
type, there's no way to tell management software that
transitional devices and legacy devices require a Conventional
PCI bus.

The multi-purpose device types would also prevent us from telling
management software what's the PCI vendor/device ID for them,
because their PCI IDs change at runtime depending on the bus
where they were is plugged.

This patch adds separate device types for each of those virtio
device flavors:

- virtio-*-pci: the existing multi-purpose device types
  - Configurable using `disable-legacy` and `disable-modern`
properties
  - Legacy driver support is automatically enabled/disabled
depending on the bus where it is plugged
  - Supports Conventional PCI and PCI Express buses
(but Conventional PCI is incompatible with
disable-legacy=off)
  - Changes PCI vendor/device IDs at runtime
- virtio-*-pci-0.9: legacy virtio device
  - Supports Conventional PCI buses only, because
it has a PIO BAR
- virtio-*-pci-1.0-transitional: virtio-1.0 device supporting legacy drivers
  - Supports Conventional PCI buses only, because
it has a PIO BAR
- virtio-*-pci-1.0: modern-only
  - Supports both Conventional PCI and PCI Express buses

All the types above will inherit from an abstract
"virtio-*-pci-base" type, so existing code that doesn't care
about the virtio version can use "virtio-*-pci-base" on type
casts.

A simple test script (tests/acceptance/virtio_version.py) is
included, to check if the new device types are equivalent to
using the `disable-legacy` and `disable-modern` options.

Signed-off-by: Eduardo Habkost 
---
Reference to previous discussion that originated this idea:
  https://www.mail-archive.com/qemu-devel@nongnu.org/msg558389.html
---
 hw/virtio/virtio-pci.h |  93 +---
 hw/display/virtio-gpu-pci.c|   8 +-
 hw/display/virtio-vga.c|  11 +-
 hw/virtio/virtio-crypto-pci.c  |   8 +-
 hw/virtio/virtio-pci.c | 225 +
 tests/acceptance/virtio_version.py | 138 ++
 6 files changed, 390 insertions(+), 93 deletions(-)
 create mode 100644 tests/acceptance/virtio_version.py

diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 813082b0d7..f1cfb60277 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -216,7 +216,8 @@ static inline void virtio_pci_disable_modern(VirtIOPCIProxy 
*proxy)
 /*
  * virtio-scsi-pci: This extends VirtioPCIProxy.
  */
-#define TYPE_VIRTIO_SCSI_PCI "virtio-scsi-pci"
+#define TYPE_VIRTIO_SCSI_PCI_PREFIX "virtio-scsi-pci"
+#define TYPE_VIRTIO_SCSI_PCI (TYPE_VIRTIO_SCSI_PCI_PREFIX "-base")
 #define VIRTIO_SCSI_PCI(obj) \
 OBJECT_CHECK(VirtIOSCSIPCI, (obj), TYPE_VIRTIO_SCSI_PCI)
 
@@ -229,7 +230,8 @@ struct VirtIOSCSIPCI {
 /*
  * vhost-scsi-pci: This extends VirtioPCIProxy.
  */
-#define TYPE_VHOST_SCSI_PCI "vhost-scsi-pci"
+#define TYPE_VHOST_SCSI_PCI_PREFIX "vhost-scsi-pci"
+#define TYPE_VHOST_SCSI_PCI (TYPE_VHOST_SCSI_PCI_PREFIX "-base")
 #define VHOST_SCSI_PCI(obj) \
 OBJECT_CHECK(VHostSCSIPCI, (obj), TYPE_VHOST_SCSI_PCI)
 
@@ -239,7 +241,8 @@ struct VHostSCSIPCI {
 };
 #endif
 
-#define TYPE_VHOST_USER_SCSI_PCI "vhost-user-scsi-pci"
+#define TYPE_VHOST_USER_SCSI_PCI_PREFIX "vhost-user-scsi-pci"
+#define TYPE_VHOST_USER_SCSI_PCI (TYPE_VHOST_USER_SCSI_PCI_PREFIX "-base")
 #define VHOST_USER_SCSI_PCI(obj) \
 OBJECT_CHECK(VHostUserSCSIPCI, (obj), TYPE_VHOST_USER_SCSI_PCI)
 
@@ -252,7 +255,8 @@ struct VHostUserSCSIPCI {
 /*
  * vhost-user-blk-pci: This extends VirtioPCIProxy.
  */
-#define TYPE_VHOST_USER_BLK_PCI "vhost-user-blk-pci"
+#define TYPE_VHOST_USER_BLK_PCI_PREFIX "vhost-user-blk-pci"
+#define TYPE_VHOST_USER_BLK_PCI (TYPE_VHOST_USER_BLK_PCI_PREFIX "-base")
 #define VHOST_USER_BLK_PCI(obj) \
 OBJECT_CHECK(VHostUserBlkPCI, (obj), TYPE_VHOST_USER_BLK_PCI)
 
@@ -265,7 +269,8 @@ struct VHostUserBlkPCI {
 /*
  * virtio-blk-pci: This extends VirtioPCIProxy.
  */
-#define TYPE_VIRTIO_BLK_PCI "virtio-blk-pci"
+#define TYPE_VIRTIO_BLK_PCI_PREFIX "virtio-blk-pci"
+#define TYPE_VIRTIO_BLK_PCI (TYPE_VIRTIO_BLK_PCI_PREFIX "-base")
 #define VIRTIO_BLK_PCI(obj) \
 OBJECT_CHECK(VirtIOBlkPCI, (obj), TYPE_VIRTIO_BLK_PCI)
 
@@ -277,7 +282,8 @@ struct VirtIOBlkPCI {
 /*
  * virtio-balloon-pci: This extends VirtioPCIProxy.
  */
-#define TYPE_VIRTIO_BALLOON_PCI "virtio-balloon-pci"
+#define TYPE_VIRTIO_BALLOON_PCI_PREFIX "virtio-balloon-pci"
+#define TYPE_VIRTIO_BALLOON_PCI (TYPE_VIRTIO_BALLOON_PCI_PREFIX "-base")
 #define VIRTIO_BALLOON_PCI(obj) \
 OBJECT_CHECK(VirtIOBalloonPCI, (obj), TYPE_VIRTIO_BALLOON_PCI)
 
@@ -289,7 +295,8 @@ struct 

[Qemu-devel] [PATCH v3 7/8] tests/vm: Do not use -enable-kvm if HOST != TARGET architecture

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/basevm.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b2e0de2022..9f4794898a 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -74,7 +74,7 @@ class BaseVM(object):
 "-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
 if vcpus and vcpus > 1:
 self._args += ["-smp", str(vcpus)]
-if kvm_available():
+if kvm_available(self.arch):
 self._args += ["-enable-kvm"]
 else:
 logging.info("KVM not available, not using -enable-kvm")
-- 
2.19.1




[Qemu-devel] [PATCH v3 5/8] tests/vm: Add a BaseVM::arch property

2018-10-12 Thread Philippe Mathieu-Daudé
The 'arch' property gives a hint on which architecture the guest image runs.

This can be use to select the correct QEMU binary path.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/basevm.py   | 4 +++-
 tests/vm/centos  | 1 +
 tests/vm/freebsd | 1 +
 tests/vm/netbsd  | 1 +
 tests/vm/openbsd | 1 +
 tests/vm/ubuntu.i386 | 1 +
 6 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 81a1cb05dd..b2e0de2022 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -42,6 +42,8 @@ class BaseVM(object):
 BUILD_SCRIPT = ""
 # The guest name, to be overridden by subclasses
 name = "#base"
+# The guest architecture, to be overridden by subclasses
+arch = "#arch"
 def __init__(self, debug=False, vcpus=None):
 self._guest = None
 self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -151,7 +153,7 @@ class BaseVM(object):
 "-device", "virtio-blk,drive=drive0,bootindex=0"]
 args += self._data_args + extra_args
 logging.debug("QEMU args: %s", " ".join(args))
-qemu_bin = os.environ.get("QEMU", "qemu-system-x86_64")
+qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch)
 guest = QEMUMachine(binary=qemu_bin, args=args)
 try:
 guest.launch()
diff --git a/tests/vm/centos b/tests/vm/centos
index afd560c564..daa2dbca03 100755
--- a/tests/vm/centos
+++ b/tests/vm/centos
@@ -19,6 +19,7 @@ import time
 
 class CentosVM(basevm.BaseVM):
 name = "centos"
+arch = "x86_64"
 BUILD_SCRIPT = """
 set -e;
 cd $(mktemp -d);
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index b6983127d0..19a3729172 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -18,6 +18,7 @@ import basevm
 
 class FreeBSDVM(basevm.BaseVM):
 name = "freebsd"
+arch = "x86_64"
 BUILD_SCRIPT = """
 set -e;
 rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index a4e25820d5..fac6a7ce51 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -18,6 +18,7 @@ import basevm
 
 class NetBSDVM(basevm.BaseVM):
 name = "netbsd"
+arch = "x86_64"
 BUILD_SCRIPT = """
 set -e;
 rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/openbsd b/tests/vm/openbsd
index 52500ee52b..cfe0572c59 100755
--- a/tests/vm/openbsd
+++ b/tests/vm/openbsd
@@ -18,6 +18,7 @@ import basevm
 
 class OpenBSDVM(basevm.BaseVM):
 name = "openbsd"
+arch = "x86_64"
 BUILD_SCRIPT = """
 set -e;
 rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/ubuntu.i386 b/tests/vm/ubuntu.i386
index 3f6ed48b74..1b7e1ab8f0 100755
--- a/tests/vm/ubuntu.i386
+++ b/tests/vm/ubuntu.i386
@@ -19,6 +19,7 @@ import time
 
 class UbuntuX86VM(basevm.BaseVM):
 name = "ubuntu.i386"
+arch = "i386"
 BUILD_SCRIPT = """
 set -e;
 cd $(mktemp -d);
-- 
2.19.1




[Qemu-devel] [PATCH v3 4/8] tests/vm: Display remaining seconds to wait for a VM to start

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/basevm.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 9415e7c33a..81a1cb05dd 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -177,11 +177,14 @@ class BaseVM(object):
 
 def wait_ssh(self, seconds=300):
 starttime = datetime.datetime.now()
+endtime = starttime + datetime.timedelta(seconds=seconds)
 guest_up = False
-while (datetime.datetime.now() - starttime).total_seconds() < seconds:
+while datetime.datetime.now() < endtime:
 if self.ssh("exit 0") == 0:
 guest_up = True
 break
+seconds = (endtime - datetime.datetime.now()).total_seconds()
+logging.debug("%ds before timeout", seconds)
 time.sleep(1)
 if not guest_up:
 raise Exception("Timeout while waiting for guest ssh")
-- 
2.19.1




[Qemu-devel] [PATCH v3 3/8] tests/vm: Do not use the -smp option with a single cpu

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/basevm.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 2bd32dc6ce..9415e7c33a 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -70,7 +70,7 @@ class BaseVM(object):
 "-device", "virtio-net-pci,netdev=vnet",
 "-vnc", "127.0.0.1:0,to=20",
 "-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
-if vcpus:
+if vcpus and vcpus > 1:
 self._args += ["-smp", str(vcpus)]
 if kvm_available():
 self._args += ["-enable-kvm"]
-- 
2.19.1




[Qemu-devel] [PATCH v3 8/8] tests/vm: Do not abuse parallelism when HOST != TARGET architecture

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/basevm.py | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 9f4794898a..5caf77d6b8 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -200,10 +200,10 @@ class BaseVM(object):
 def qmp(self, *args, **kwargs):
 return self._guest.qmp(*args, **kwargs)
 
-def parse_args(vm_name):
+def parse_args(vmcls):
 
 def get_default_jobs():
-if kvm_available():
+if kvm_available(vmcls.arch):
 return multiprocessing.cpu_count() / 2
 else:
 return 1
@@ -216,7 +216,7 @@ def parse_args(vm_name):
 "3 = test command failed")
 parser.add_option("--debug", "-D", action="store_true",
   help="enable debug output")
-parser.add_option("--image", "-i", default="%s.img" % vm_name,
+parser.add_option("--image", "-i", default="%s.img" % vmcls.name,
   help="image file name")
 parser.add_option("--force", "-f", action="store_true",
   help="force build image even if image exists")
@@ -237,7 +237,7 @@ def parse_args(vm_name):
 
 def main(vmcls):
 try:
-args, argv = parse_args(vmcls.name)
+args, argv = parse_args(vmcls)
 if not argv and not args.build_qemu and not args.build_image:
 print("Nothing to do?")
 return 1
-- 
2.19.1




[Qemu-devel] [PATCH v3 1/8] tests/vm: Extract the kvm_available() handy function

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 scripts/qemu.py| 4 
 tests/vm/basevm.py | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/qemu.py b/scripts/qemu.py
index f099ce7278..9fc0be4828 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -26,6 +26,10 @@ import tempfile
 LOG = logging.getLogger(__name__)
 
 
+def kvm_available(target_arch=None):
+return os.access("/dev/kvm", os.R_OK | os.W_OK)
+
+
 #: Maps machine types to the preferred console device types
 CONSOLE_DEV_TYPES = {
 r'^clipper$': 'isa-serial',
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index cafbc6b3a5..834bc90cc1 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -18,7 +18,7 @@ import logging
 import time
 import datetime
 sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
-from qemu import QEMUMachine
+from qemu import QEMUMachine, kvm_available
 import subprocess
 import hashlib
 import optparse
@@ -72,7 +72,7 @@ class BaseVM(object):
 "-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
 if vcpus:
 self._args += ["-smp", str(vcpus)]
-if os.access("/dev/kvm", os.R_OK | os.W_OK):
+if kvm_available():
 self._args += ["-enable-kvm"]
 else:
 logging.info("KVM not available, not using -enable-kvm")
-- 
2.19.1




[Qemu-devel] [PATCH v3 6/8] tests/vm: Let kvm_available() work in cross environments

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 scripts/qemu.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/scripts/qemu.py b/scripts/qemu.py
index 9fc0be4828..bcd24aad82 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -27,6 +27,8 @@ LOG = logging.getLogger(__name__)
 
 
 def kvm_available(target_arch=None):
+if target_arch and target_arch != os.uname()[4]:
+return False
 return os.access("/dev/kvm", os.R_OK | os.W_OK)
 
 
-- 
2.19.1




[Qemu-devel] [PATCH v3 2/8] tests/vm: Do not abuse parallelism when KVM is not available

2018-10-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Use default args.jobs
v2: Add get_default_jobs (Fam suggestion)
---
 tests/vm/basevm.py | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 834bc90cc1..2bd32dc6ce 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -196,6 +196,13 @@ class BaseVM(object):
 return self._guest.qmp(*args, **kwargs)
 
 def parse_args(vm_name):
+
+def get_default_jobs():
+if kvm_available():
+return multiprocessing.cpu_count() / 2
+else:
+return 1
+
 parser = optparse.OptionParser(
 description="VM test utility.  Exit codes: "
 "0 = success, "
@@ -208,7 +215,7 @@ def parse_args(vm_name):
   help="image file name")
 parser.add_option("--force", "-f", action="store_true",
   help="force build image even if image exists")
-parser.add_option("--jobs", type=int, default=multiprocessing.cpu_count() 
/ 2,
+parser.add_option("--jobs", type=int, default=get_default_jobs(),
   help="number of virtual CPUs")
 parser.add_option("--verbose", "-V", action="store_true",
   help="Pass V=1 to builds within the guest")
-- 
2.19.1




[Qemu-devel] [PATCH v3 0/8] tests/vm: Improvements when KVM is not available

2018-10-12 Thread Philippe Mathieu-Daudé
Hi Fam,

Few patches I added while testing the VM tests without KVM access.
I doubt many people want to suffer using TCG for VM testing, but
it was handy to debug/support aarch64 VM tests.

Also this could be a useful TCG stress test...?

Since v2: https://lists.gnu.org/archive/html/qemu-devel/2018-09/msg04084.html
- use default args.jobs (Fam)
- move kvm_available() to scripts/QEMU so it can be used by Avocado
- do not use -smp 1
- add a BaseVM::arch property to help cross vm testing

Since v1: http://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg03411.html
- rebased on master
- added get_default_jobs (Fam)
- dropped 'When using TCG, wait longer for a VM to start'

Regards,

Phil.

Philippe Mathieu-Daudé (8):
  tests/vm: Extract the kvm_available() handy function
  tests/vm: Do not abuse parallelism when KVM is not available
  tests/vm: Do not use the -smp option with a single cpu
  tests/vm: Display remaining seconds to wait for a VM to start
  tests/vm: Add a BaseVM::arch property
  tests/vm: Let kvm_available() work in cross environments
  tests/vm: Do not use -enable-kvm if HOST != TARGET architecture
  tests/vm: Do not abuse parallelism when HOST != TARGET architecture

 scripts/qemu.py  |  6 ++
 tests/vm/basevm.py   | 30 +-
 tests/vm/centos  |  1 +
 tests/vm/freebsd |  1 +
 tests/vm/netbsd  |  1 +
 tests/vm/openbsd |  1 +
 tests/vm/ubuntu.i386 |  1 +
 7 files changed, 32 insertions(+), 9 deletions(-)

-- 
2.19.1




[Qemu-devel] [PATCH] tests/vm: Use subprocess.Popen() with to uncompress XZ files

2018-10-12 Thread Philippe Mathieu-Daudé
Avoiding the file copy greatly speeds the process up.

Comparison with network file already cached, stopping after build_image():

Before:
  $ time make vm-build-freebsd
  real1m38.153s
  user1m16.871s
  sys 0m19.325s

After:
  $ time make vm-build-freebsd
  real0m13.512s
  user0m9.520s
  sys 0m3.685s

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/vm/centos  | 5 ++---
 tests/vm/freebsd | 9 ++---
 tests/vm/netbsd  | 9 ++---
 tests/vm/openbsd | 9 ++---
 4 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/tests/vm/centos b/tests/vm/centos
index afd560c564..fa653c1650 100755
--- a/tests/vm/centos
+++ b/tests/vm/centos
@@ -63,9 +63,8 @@ class CentosVM(basevm.BaseVM):
 
 def build_image(self, img):
 cimg = 
self._download_with_cache("https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1802.qcow2.xz;)
-img_tmp = img + ".tmp"
-subprocess.check_call(["cp", "-f", cimg, img_tmp + ".xz"])
-subprocess.check_call(["xz", "-df", img_tmp + ".xz"])
+with open(img, 'wb', 0644) as output:
+subprocess.Popen(["xz", "--threads=0", "--decompress", "--force", 
"--to-stdout", cimg], stdout=output)
 subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"])
 self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()])
 self.wait_ssh()
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index b6983127d0..7ec43a4c5c 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -31,13 +31,8 @@ class FreeBSDVM(basevm.BaseVM):
 def build_image(self, img):
 cimg = 
self._download_with_cache("http://download.patchew.org/freebsd-11.1-amd64.img.xz;,
 
sha256sum='adcb771549b37bc63826c501f05121a206ed3d9f55f49145908f7e1432d65891')
-img_tmp_xz = img + ".tmp.xz"
-img_tmp = img + ".tmp"
-subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
-subprocess.check_call(["xz", "-df", img_tmp_xz])
-if os.path.exists(img):
-os.remove(img)
-os.rename(img_tmp, img)
+with open(img, 'wb', 0644) as output:
+subprocess.Popen(["xz", "--threads=0", "--decompress", "--force", 
"--to-stdout", cimg], stdout=output)
 
 if __name__ == "__main__":
 sys.exit(basevm.main(FreeBSDVM))
diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index a4e25820d5..99023344b7 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -31,13 +31,8 @@ class NetBSDVM(basevm.BaseVM):
 def build_image(self, img):
 cimg = 
self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz;,
  
sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
-img_tmp_xz = img + ".tmp.xz"
-img_tmp = img + ".tmp"
-subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
-subprocess.check_call(["xz", "-df", img_tmp_xz])
-if os.path.exists(img):
-os.remove(img)
-os.rename(img_tmp, img)
+with open(img, 'wb', 0644) as output:
+subprocess.Popen(["xz", "--threads=0", "--decompress", "--force", 
"--to-stdout", cimg], stdout=output)
 
 if __name__ == "__main__":
 sys.exit(basevm.main(NetBSDVM))
diff --git a/tests/vm/openbsd b/tests/vm/openbsd
index 52500ee52b..57604bb43d 100755
--- a/tests/vm/openbsd
+++ b/tests/vm/openbsd
@@ -32,13 +32,8 @@ class OpenBSDVM(basevm.BaseVM):
 def build_image(self, img):
 cimg = 
self._download_with_cache("http://download.patchew.org/openbsd-6.1-amd64.img.xz;,
 
sha256sum='8c6cedc483e602cfee5e04f0406c64eb99138495e8ca580bc0293bcf0640c1bf')
-img_tmp_xz = img + ".tmp.xz"
-img_tmp = img + ".tmp"
-subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
-subprocess.check_call(["xz", "-df", img_tmp_xz])
-if os.path.exists(img):
-os.remove(img)
-os.rename(img_tmp, img)
+with open(img, 'wb', 0644) as output:
+subprocess.Popen(["xz", "--threads=0", "--decompress", "--force", 
"--to-stdout", cimg], stdout=output)
 
 if __name__ == "__main__":
 sys.exit(basevm.main(OpenBSDVM))
-- 
2.19.1




[Qemu-devel] [RFC PATCH v1 8/8] multi-process QEMU: synchronize RAM between QEMU & remote device

2018-10-12 Thread Jagannathan Raman
- Setup MemoryListener in QEMU to get all updates to sysmem, and
  forward all RAM updates to remote device process
- Remote device process updates its "system_memory" container using
  shared file descriptors provided by SYNC_SYSMEM message

Signed-off-by: Jagannathan Raman 
---
 hw/qemu-proxy.c | 156 
 hw/scsi/qemu-scsi-dev.c |  10 
 include/hw/qemu-proxy.h |   3 +
 3 files changed, 169 insertions(+)

diff --git a/hw/qemu-proxy.c b/hw/qemu-proxy.c
index 1712b41..79cdd3f 100644
--- a/hw/qemu-proxy.c
+++ b/hw/qemu-proxy.c
@@ -159,6 +159,8 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error 
**errp)
 printf("Proxy link is not set\n");
 }
 
+configure_memory_listener(dev);
+
 pci_conf[PCI_LATENCY_TIMER] = 0xff;
 
 memory_region_init_io(>mmio_io, OBJECT(dev), _device_mmio_ops,
@@ -213,3 +215,157 @@ void init_emulation_process(PCIProxyDev *pdev, char 
*command, Error **errp)
 }
 
 type_init(pci_proxy_dev_register_types)
+
+static void proxy_ml_begin(MemoryListener *listener)
+{
+int mrs;
+struct proxy_device *pdev = container_of(listener, struct proxy_device,
+ memory_listener);
+
+for (mrs = 0; mrs < pdev->n_mr_sections; mrs++) {
+memory_region_unref(pdev->mr_sections[mrs].mr);
+}
+
+g_free(pdev->mr_sections);
+pdev->mr_sections = NULL;
+pdev->n_mr_sections = 0;
+}
+
+static bool proxy_mrs_can_merge(uint64_t host, uint64_t prev_host, size_t size)
+{
+bool merge;
+ram_addr_t offset;
+int fd1, fd2;
+MemoryRegion *mr;
+
+mr = memory_region_from_host((void *)(uintptr_t)host, );
+fd1 = memory_region_get_fd(mr);
+
+mr = memory_region_from_host((void *)(uintptr_t)prev_host, );
+fd2 = memory_region_get_fd(mr);
+
+merge = (fd1 == fd2);
+
+merge &= ((prev_host + size) == host);
+
+return merge;
+}
+
+static void proxy_ml_region_addnop(MemoryListener *listener,
+   MemoryRegionSection *section)
+{
+bool need_add = true;
+uint64_t mrs_size, mrs_gpa, mrs_page;
+uintptr_t mrs_host;
+RAMBlock *mrs_rb;
+MemoryRegionSection *prev_sec;
+struct proxy_device *pdev = container_of(listener, struct proxy_device,
+ memory_listener);
+
+if (!(memory_region_is_ram(section->mr) &&
+  !memory_region_is_rom(section->mr))) {
+return;
+}
+
+mrs_rb = section->mr->ram_block;
+mrs_page = (uint64_t)qemu_ram_pagesize(mrs_rb);
+mrs_size = int128_get64(section->size);
+mrs_gpa = section->offset_within_address_space;
+mrs_host = (uintptr_t)memory_region_get_ram_ptr(section->mr) +
+   section->offset_within_region;
+
+mrs_host = mrs_host & ~(mrs_page - 1);
+mrs_gpa = mrs_gpa & ~(mrs_page - 1);
+mrs_size = ROUND_UP(mrs_size, mrs_page);
+
+if (pdev->n_mr_sections) {
+prev_sec = pdev->mr_sections + (pdev->n_mr_sections - 1);
+uint64_t prev_gpa_start = prev_sec->offset_within_address_space;
+uint64_t prev_size = int128_get64(prev_sec->size);
+uint64_t prev_gpa_end   = range_get_last(prev_gpa_start, prev_size);
+uint64_t prev_host_start =
+(uintptr_t)memory_region_get_ram_ptr(prev_sec->mr) +
+prev_sec->offset_within_region;
+uint64_t prev_host_end = range_get_last(prev_host_start, prev_size);
+
+if (mrs_gpa <= (prev_gpa_end + 1)) {
+if (mrs_gpa < prev_gpa_start) {
+assert(0);
+}
+
+if ((section->mr == prev_sec->mr) &&
+proxy_mrs_can_merge(mrs_host, prev_host_start,
+(mrs_gpa - prev_gpa_start))) {
+uint64_t max_end = MAX(prev_host_end, mrs_host + mrs_size);
+   need_add = false;
+prev_sec->offset_within_address_space =
+MIN(prev_gpa_start, mrs_gpa);
+prev_sec->offset_within_region =
+MIN(prev_host_start, mrs_host) -
+(uintptr_t)memory_region_get_ram_ptr(prev_sec->mr);
+prev_sec->size = int128_make64(max_end - MIN(prev_host_start,
+ mrs_host));
+}
+}
+}
+
+if (need_add) {
+++pdev->n_mr_sections;
+pdev->mr_sections = g_renew(MemoryRegionSection, pdev->mr_sections,
+pdev->n_mr_sections);
+pdev->mr_sections[pdev->n_mr_sections - 1] = *section;
+pdev->mr_sections[pdev->n_mr_sections - 1].fv = NULL;
+memory_region_ref(section->mr);
+}
+}
+
+static void proxy_ml_commit(MemoryListener *listener)
+{
+ProcMsg msg;
+ram_addr_t offset;
+MemoryRegion *mr;
+MemoryRegionSection section;
+uintptr_t host_addr;
+int region;
+struct proxy_device *pdev = container_of(listener, struct 

[Qemu-devel] [RFC PATCH v1 2/8] multi-process QEMU: define proxy-link object

2018-10-12 Thread Jagannathan Raman
- Define proxy-link object which forms the communication link between
  QEMU & emulation program.
- Add functions to configure members of proxy-link object instance.
- Add functions to send and receive messages over the communication
  channel.
- Add GMainLoop to handle events received on the communication channel.

Signed-off-by: Jagannathan Raman 
---
 include/glib-compat.h   |   4 +
 include/io/proxy-link.h | 103 +++
 io/Makefile.objs|   1 +
 io/proxy-link.c | 263 
 4 files changed, 371 insertions(+)
 create mode 100644 include/io/proxy-link.h
 create mode 100644 io/proxy-link.c

diff --git a/include/glib-compat.h b/include/glib-compat.h
index fdf95a2..5e61d82 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -19,12 +19,16 @@
 /* Ask for warnings for anything that was marked deprecated in
  * the defined version, or before. It is a candidate for rewrite.
  */
+#ifndef GLIB_VERSION_MIN_REQUIRED
 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40
+#endif
 
 /* Ask for warnings if code tries to use function that did not
  * exist in the defined version. These risk breaking builds
  */
+#ifndef GLIB_VERSION_MAX_ALLOWED
 #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40
+#endif
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
new file mode 100644
index 000..6ce6c10
--- /dev/null
+++ b/include/io/proxy-link.h
@@ -0,0 +1,103 @@
+/*
+ * Communication channel between QEMU and remote device process
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PROXY_LINK_H
+#define PROXY_LINK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+
+typedef struct ProxyLinkState ProxyLinkState;
+
+#define TYPE_PROXY_LINK "proxy-link"
+#define PROXY_LINK(obj) \
+OBJECT_CHECK(ProxyLinkState, (obj), TYPE_PROXY_LINK)
+
+#define MAX_FDS 8
+
+#define PROC_HDR_SIZE offsetof(ProcMsg, data1.u64)
+
+typedef enum {
+INIT = 0,
+CONF_READ,
+CONF_WRITE,
+MAX,
+} proc_cmd_t;
+
+typedef struct {
+proc_cmd_t cmd;
+int bytestream;
+size_t size;
+
+union {
+uint64_t u64;
+} data1;
+
+int fds[MAX_FDS];
+int num_fds;
+
+uint8_t *data2;
+} ProcMsg;
+
+struct conf_data_msg {
+uint32_t addr;
+uint32_t val;
+int l;
+};
+
+typedef void (*proxy_link_callback)(GIOCondition cond);
+
+typedef struct ProxySrc {
+GSource gsrc;
+GPollFD gpfd;
+} ProxySrc;
+
+struct ProxyLinkState {
+Object obj;
+
+GMainContext *ctx;
+GMainLoop *loop;
+ProxySrc *src;
+
+int sock;
+pthread_mutex_t lock;
+
+proxy_link_callback callback;
+};
+
+ProxyLinkState *proxy_link_create(void);
+void proxy_link_finalize(ProxyLinkState *s);
+
+void proxy_proc_send(ProxyLinkState *s, ProcMsg *msg);
+int proxy_proc_recv(ProxyLinkState *s, ProcMsg *msg);
+void proxy_link_set_sock(ProxyLinkState *s, int fd);
+void proxy_link_set_callback(ProxyLinkState *s, proxy_link_callback callback);
+void start_handler(ProxyLinkState *s);
+
+#endif
diff --git a/io/Makefile.objs b/io/Makefile.objs
index 9a20fce..141e9ed 100644
--- a/io/Makefile.objs
+++ b/io/Makefile.objs
@@ -10,3 +10,4 @@ io-obj-y += channel-util.o
 io-obj-y += dns-resolver.o
 io-obj-y += net-listener.o
 io-obj-y += task.o
+io-obj-y += proxy-link.o
diff --git a/io/proxy-link.c b/io/proxy-link.c
new file mode 100644
index 000..f5f7887
--- /dev/null
+++ b/io/proxy-link.c
@@ -0,0 +1,263 @@
+/*
+ * Communication channel between QEMU and remote device process
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files 

[Qemu-devel] [RFC PATCH v1 5/8] multi-process QEMU: setup memory manager for remote device

2018-10-12 Thread Jagannathan Raman
- sync_sysmem_msg_t message format is defined. It is used to send
  file descriptors of the RAM regions to remote device
- RAM on the remote device is configured with a set of file descriptors.
  Old RAM regions are deleted and new regions, each with an fd, is
  added to the RAM.

Signed-off-by: Jagannathan Raman 
---
 include/io/proxy-link.h |  9 +
 include/remote/memory.h | 34 ++
 remote/Makefile.objs|  1 +
 remote/memory.c | 93 +
 4 files changed, 137 insertions(+)
 create mode 100644 include/remote/memory.h
 create mode 100644 remote/memory.c

diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index 6ce6c10..1eeabae 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -39,6 +39,8 @@ typedef struct ProxyLinkState ProxyLinkState;
 #define PROXY_LINK(obj) \
 OBJECT_CHECK(ProxyLinkState, (obj), TYPE_PROXY_LINK)
 
+#include "exec/hwaddr.h"
+
 #define MAX_FDS 8
 
 #define PROC_HDR_SIZE offsetof(ProcMsg, data1.u64)
@@ -47,16 +49,23 @@ typedef enum {
 INIT = 0,
 CONF_READ,
 CONF_WRITE,
+SYNC_SYSMEM,
 MAX,
 } proc_cmd_t;
 
 typedef struct {
+hwaddr gpas[MAX_FDS];
+uint64_t sizes[MAX_FDS];
+} sync_sysmem_msg_t;
+
+typedef struct {
 proc_cmd_t cmd;
 int bytestream;
 size_t size;
 
 union {
 uint64_t u64;
+sync_sysmem_msg_t sync_sysmem;
 } data1;
 
 int fds[MAX_FDS];
diff --git a/include/remote/memory.h b/include/remote/memory.h
new file mode 100644
index 000..4500192
--- /dev/null
+++ b/include/remote/memory.h
@@ -0,0 +1,34 @@
+/*
+ * Memory manager for remote device
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_MEMORY_H
+#define REMOTE_MEMORY_H
+
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "io/proxy-link.h"
+
+void remote_sysmem_reconfig(ProcMsg *msg, Error **errp);
+
+#endif
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index e90ae20..c52d500 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1,2 +1,3 @@
 remote-obj-y += pcihost.o
 remote-obj-y += machine.o
+remote-obj-y += memory.o
diff --git a/remote/memory.c b/remote/memory.c
new file mode 100644
index 000..f4cf2d2
--- /dev/null
+++ b/remote/memory.c
@@ -0,0 +1,93 @@
+/*
+ * Memory manager for remote device
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 
+#include 
+
+#include "qemu/osdep.h"
+#include "qemu/queue.h"
+#include "qemu-common.h"
+#include "remote/memory.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "cpu.h"
+#include "exec/ram_addr.h"
+#include "io/proxy-link.h"
+#include "qemu/main-loop.h"
+
+static void remote_ram_destructor(MemoryRegion *mr)
+{
+  

[Qemu-devel] [RFC PATCH v1 0/8] multi-process QEMU

2018-10-12 Thread Jagannathan Raman
Hi

The multi-process QEMU project proposal written by John Johnson
is copied below.

This patchset implements part of the proposal.

The goal is to run emulated devices as standalone processes. To begin
with, we've chosen to run lsi53c895a as a standalone process /remote
device, based on the architecture described in the proposal.

This patchset implements some of the fundamental parts necessary to
implement the remote device. The remote device sets up a PCI host
bridge. Future patches would add leaf devices to the PCI host.

A "proxy device" is implemented, which acts as proxy for the remote
device. It provides the remote device with access to the RAM, which
is needed to perform DMA. It also handles PCI BAR & config space
accesses.

Thanks!

From: John G Johnson 
Date: Mon, 24 Sep 2018 13:23:03 -0700
Subject: multi-process QEMU

Greetings,

At last year's KVM forum, Konrad Wilk and Marc-Andre Lureau
presented on multi-prcess QEMU:
https://www.linux-kvm.org/images/f/fc/KVM_FORUM_multi-process.pdf

At Oracle, we've started a project to implement this concept.  When we
shared the proposal with Marc-Andre, he suggested we also share it with you.

The current proposal is attached.  We are working on coding, and expect
to have an initial set of patches in a couple weeks.  These patches will just
cover setting up the same PCI tree in both processes.

Jag Raman will attend this year's KVM forum, and will propose a
BoF session on the subject.  By this time we will have send out another
set of patches that cover separating a PCI leaf device.

We'd appreciate any comments you have, both in the proposal itself, and
on the above plan.  Many thanks for your time on this.


JJ


Disaggregating QEMU

QEMU is often used as the hypervisor for virtual machines
running in the Oracle cloud.  Since one of the advantages of cloud
computing is the ability to run many VMs from different tenants in the
same cloud infrastructure, a guest that compromised its hypervisor
could potentially use the hypervisor's access privileges to access
data it is not authorized for.

QEMU can be susceptible to security attack because it is a
large, monolithic program that provides many features to the VMs it
services.  Many of these feature can be configured out of QEMU, but
even a reduced configuration QEMU has a large amount of code a guest
can potentially attack in order to gain additional privileges.


1. QEMU services

QEMU can be broadly described as providing three main
services.  One is a VM control point, where VMs can be created,
migrated, re-configured, and destroyed.  A second is to emulate the
CPU instructions within the VM, often accelerated by HW virtualization
features such as Intel's VT extensions.  Finally, it provides IO
services to the VM by emulating HW IO devices, such as disk and
network devices.

1.1 A disaggregated QEMU

A disaggregated QEMU involves separating QEMU services into
separate host processes.  Each of these processes can be given only
the privileges it needs to provide its service, e.g., a disk service
could be given access only the the disk images it provides, and not be
allowed to access other files, or any network devices.  An attacker
who compromised this service would not be able to use this exploit to
access files or devices beyond what the disk service was given access
to.

A control QEMU process would remain, but in disaggregated
mode, it would be a control point that exec()s the processes needed to
support the VM being created, but have no direct interface to the VM.
During VM execution, it would still provide the user interface to
hot-plug devices or live migrate the VM.

A first step in creating a disaggregated QEMU is to separate
IO services from the main QEMU program, which would continue to
provide CPU emulation. i.e., the control process would also be the CPU
emulation process.  In a later phase, CPU emulation could be separated
from the QEMU control process.


2. Disaggregating IO services

Disaggregating IO services is a good place to begin QEMU
disaggregating for a couple of reasons.  One is the sheer number of IO
devices QEMU can emulate provides a large surface of interfaces which
could potentially be exploited, and, indeed, have been a source of
exploits in the past.  Another is the modular nature of QEMU device
emulation code provides interface points where the QEMU functions that
perform device emulation can be separated from the QEMU functions that
manage the emulation of guest CPU instructions.

2.1 QEMU device emulation

QEMU uses a object oriented SW architecture for device
emulation code.  Configured objects are all compiled into the QEMU
binary, then objects are instantiated by name when used by the guest
VM.  For example, the code to emulate a device named "foo" is always
present in QEMU, but its instantiation code is only run when a device
named "foo" is included in the 

[Qemu-devel] [RFC PATCH v1 7/8] multi-process QEMU: introduce proxy object

2018-10-12 Thread Jagannathan Raman
From: Elena Ufimtseva 

Define PCI Device proxy object as a parent of TYPE_PCI_DEVICE.
PCI Proxy Object will register PCI BARs, MemoryRegionOps to handle
access to the BARs and forward those to the remote device.
PCI Proxy object intercepts config space reads and writes. In case
of pci config write it forwards it to the remote device using
communication channel.

TODO:
- Handle interrupt messages from the emulation program and implement
  DMA operations.

Signed-off-by: Elena Ufimtseva 
---
 hw/Makefile.objs|   2 +
 hw/qemu-proxy.c | 215 
 include/hw/qemu-proxy.h |  56 +
 3 files changed, 273 insertions(+)
 create mode 100644 hw/qemu-proxy.c
 create mode 100644 include/hw/qemu-proxy.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 9c99c29..6bb2eb0 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -44,3 +44,5 @@ scsi-dev-obj-y += scsi/
 scsi-dev-obj-y += block/
 scsi-dev-obj-y += pci/
 scsi-dev-obj-y += nvram/
+
+common-obj-y += qemu-proxy.o
diff --git a/hw/qemu-proxy.c b/hw/qemu-proxy.c
new file mode 100644
index 000..1712b41
--- /dev/null
+++ b/hw/qemu-proxy.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "io/proxy-link.h"
+#include "exec/memory.h"
+#include "exec/cpu-common.h"
+#include "exec/address-spaces.h"
+#include "qemu/int128.h"
+#include "qemu/range.h"
+#include "hw/pci/pci.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qstring.h"
+#include "sysemu/sysemu.h"
+#include "hw/qemu-proxy.h"
+
+char command[] = "qemu-scsi-dev";
+
+static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
+
+int config_op_send(PCIProxyDev *dev, uint32_t addr, uint32_t val, int l,
+unsigned int op)
+{
+ProcMsg msg;
+struct conf_data_msg conf_data;
+
+conf_data.addr = addr;
+conf_data.val = val;
+conf_data.l = l;
+
+
+msg.data2 = (uint8_t *)malloc(sizeof(conf_data));
+if (!msg.data2) {
+printf("Failed to allocate memory for msg.data2\n");
+return -ENOMEM;
+}
+memcpy(msg.data2, (const uint8_t *)_data, sizeof(conf_data));
+msg.size = sizeof(conf_data);
+msg.num_fds = 0;
+msg.cmd = op;
+msg.bytestream = 1;
+
+proxy_proc_send(dev->proxy_dev.proxy_link, );
+free(msg.data2);
+
+return 0;
+}
+
+static uint32_t pci_proxy_read_config(PCIDevice *d,
+   uint32_t addr, int len)
+{
+config_op_send(PCI_PROXY_DEV(d), addr, 0, 0, CONF_READ);
+return pci_default_read_config(d, addr, len);
+}
+
+static void pci_proxy_write_config(PCIDevice *d, uint32_t addr, uint32_t val,
+int l)
+{
+pci_default_write_config(d, addr, val, l);
+config_op_send(PCI_PROXY_DEV(d), addr, val, l, CONF_WRITE);
+}
+
+
+static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->realize = pci_proxy_dev_realize;
+k->class_id = PCI_CLASS_SYSTEM_OTHER;
+k->vendor_id = PCI_VENDOR_ID_REDHAT;
+k->device_id = PCI_DEVICE_ID_REDHAT_TEST;
+k->config_read = pci_proxy_read_config;
+k->config_write = pci_proxy_write_config;
+
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+dc->desc = "PCI Proxy Device";
+}
+
+static const TypeInfo pci_proxy_dev_type_info = {
+.name  = TYPE_PCI_PROXY_DEV,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PCIProxyDev),
+.class_init= pci_proxy_dev_class_init,
+.interfaces = (InterfaceInfo[]) {
+{ 

[Qemu-devel] [RFC PATCH v1 6/8] multi-process QEMU: remote process initialization

2018-10-12 Thread Jagannathan Raman
Initialize remote process main loop and add the message
handling logic. Handle SYNC_SYSMEM message by updating
its "system_memory" container using shared file descriptors
received from QEMU.

Signed-off-by: Jagannathan Raman 
---
 hw/scsi/qemu-scsi-dev.c | 71 +
 1 file changed, 71 insertions(+)

diff --git a/hw/scsi/qemu-scsi-dev.c b/hw/scsi/qemu-scsi-dev.c
index 21aba91..ede0c4b 100644
--- a/hw/scsi/qemu-scsi-dev.c
+++ b/hw/scsi/qemu-scsi-dev.c
@@ -23,22 +23,93 @@
  */
 
 #include 
+#include 
+#include 
 
 #include "qemu/osdep.h"
 #include "qemu/module.h"
 #include "remote/pcihost.h"
 #include "remote/machine.h"
 #include "hw/boards.h"
+#include "remote/memory.h"
+#include "io/proxy-link.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "sysemu/cpus.h"
+#include "qemu-common.h"
 
 static RemMachineState *machine;
+static ProxyLinkState *proxy_link;
+
+static void process_msg(GIOCondition cond)
+{
+ProcMsg *msg = NULL;
+Error *err = NULL;
+
+if ((cond & G_IO_HUP) || (cond & G_IO_ERR)) {
+error_setg(, "socket closed, cond is %d", cond);
+goto finalize_loop;
+}
+
+msg = g_malloc0(sizeof(ProcMsg));
+
+if (proxy_proc_recv(proxy_link, msg)) {
+error_setg(, "Failed to receive message");
+goto finalize_loop;
+}
+
+switch (msg->cmd) {
+case INIT:
+break;
+case CONF_WRITE:
+break;
+case CONF_READ:
+break;
+default:
+error_setg(, "Unknown command");
+goto finalize_loop;
+}
+
+g_free(msg);
+
+return;
+
+finalize_loop:
+error_report_err(err);
+g_free(msg);
+proxy_link_finalize(proxy_link);
+proxy_link = NULL;
+}
 
 int main(int argc, char *argv[])
 {
+Error *err = NULL;
+
 module_call_init(MODULE_INIT_QOM);
 
 machine = REMOTE_MACHINE(object_new(TYPE_REMOTE_MACHINE));
 
 current_machine = MACHINE(machine);
 
+if (qemu_init_main_loop()) {
+error_report_err(err);
+return -EBUSY;
+}
+
+qemu_init_cpu_loop();
+
+page_size_init();
+
+proxy_link = proxy_link_create();
+if (!proxy_link) {
+printf("Could not create proxy link\n");
+return -1;
+}
+
+proxy_link_set_sock(proxy_link, STDIN_FILENO);
+proxy_link_set_callback(proxy_link, process_msg);
+
+start_handler(proxy_link);
+
 return 0;
 }
-- 
1.8.3.1




[Qemu-devel] [RFC PATCH v1 3/8] multi-process QEMU: setup PCI host bridge for remote device

2018-10-12 Thread Jagannathan Raman
- PCI host bridge is setup for the remote device process. It is
  implemented using remote-pcihost object. It is an extension of the PCI
  host bridge setup by QEMU.
- remote-pcihost configures a PCI bus which could be used by the remote
  PCI device to latch on to.

Signed-off-by: Jagannathan Raman 
---
 Makefile |  1 +
 Makefile.objs|  4 +++
 Makefile.target  |  3 ++
 hw/pci/Makefile.objs |  2 +-
 include/remote/pcihost.h | 58 +
 remote/Makefile.objs |  1 +
 remote/pcihost.c | 84 
 7 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 include/remote/pcihost.h
 create mode 100644 remote/Makefile.objs
 create mode 100644 remote/pcihost.c

diff --git a/Makefile b/Makefile
index b6cac08..fe4244a 100644
--- a/Makefile
+++ b/Makefile
@@ -429,6 +429,7 @@ dummy := $(call unnest-vars,, \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
+remote-obj-y \
 scsi-dev-obj-y \
 common-obj-m \
 ui-obj-y \
diff --git a/Makefile.objs b/Makefile.objs
index 0a3799c..41a8c77 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -89,6 +89,10 @@ scsi-dev-obj-y += qdev-monitor.o
 scsi-dev-obj-y += bootdevice.o
 scsi-dev-obj-y += iothread.o
 
+#
+# remote-obj-y is code used by all remote devices
+remote-obj-y += remote/
+
 ###
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index c5feda2..74aab39 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -190,6 +190,7 @@ block-obj-y :=
 common-obj-y :=
 chardev-obj-y :=
 scsi-dev-obj-y :=
+remote-obj-y :=
 include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,,target-obj-y)
 target-obj-y-save := $(target-obj-y)
@@ -202,6 +203,7 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
+   remote-obj-y \
scsi-dev-obj-y \
common-obj-m)
 target-obj-y := $(target-obj-y-save)
@@ -217,6 +219,7 @@ all-scsi-dev-obj-y += $(block-obj-y)
 all-scsi-dev-obj-y += $(crypto-obj-y)
 all-scsi-dev-obj-y += $(io-obj-y)
 all-scsi-dev-obj-y += $(chardev-obj-y)
+all-scsi-dev-obj-y += $(remote-obj-y)
 all-scsi-dev-obj-y += $(scsi-dev-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 46af40a..f779285 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -8,6 +8,6 @@ common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o
 common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o
 common-obj-$(CONFIG_ALL) += pci-stub.o
 
-scsi-dev-obj-y += pci.o pci_bridge.o
+scsi-dev-obj-y += pci.o pci_bridge.o pci_host.o pcie_host.o
 scsi-dev-obj-y += msi.o msix.o
 scsi-dev-obj-y += pcie.o
diff --git a/include/remote/pcihost.h b/include/remote/pcihost.h
new file mode 100644
index 000..7357445
--- /dev/null
+++ b/include/remote/pcihost.h
@@ -0,0 +1,58 @@
+/*
+ * PCI Host for remote device
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_PCIHOST_H
+#define REMOTE_PCIHOST_H
+
+#include 
+#include 
+
+#include "exec/memory.h"
+#include "hw/pci/pcie_host.h"
+
+#define TYPE_REMOTE_HOST_DEVICE "remote-pcihost"
+#define REMOTE_HOST_DEVICE(obj) \
+OBJECT_CHECK(RemPCIHost, (obj), TYPE_REMOTE_HOST_DEVICE)
+
+typedef struct RemPCIHost {
+/*< private >*/
+PCIExpressHost parent_obj;
+/*< public >*/
+
+/* Memory Controller Hub (MCH) may not be necessary for the emulation
+ * program. The two important reasons for implementing a PCI host in the
+ * emulation program are:
+ 

[Qemu-devel] [RFC PATCH v1 4/8] multi-process QEMU: setup a machine for remote device process

2018-10-12 Thread Jagannathan Raman
- remote-machine object sets up various subsystems of the remote device
  process.
- PCI host bridge is instantiated
- RAM, IO & PCI memory regions are initialized

Signed-off-by: Jagannathan Raman 
---
 exec.c|  3 +-
 hw/scsi/qemu-scsi-dev.c   |  9 +
 include/exec/address-spaces.h |  2 ++
 include/remote/machine.h  | 43 
 remote/Makefile.objs  |  1 +
 remote/machine.c  | 78 +++
 6 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 include/remote/machine.h
 create mode 100644 remote/machine.c

diff --git a/exec.c b/exec.c
index d0821e6..7dafc0b 100644
--- a/exec.c
+++ b/exec.c
@@ -192,7 +192,6 @@ typedef struct subpage_t {
 #define PHYS_SECTION_WATCH 3
 
 static void io_mem_init(void);
-static void memory_map_init(void);
 static void tcg_commit(MemoryListener *listener);
 
 static MemoryRegion io_mem_watch;
@@ -3070,7 +3069,7 @@ static void tcg_commit(MemoryListener *listener)
 tlb_flush(cpuas->cpu);
 }
 
-static void memory_map_init(void)
+void memory_map_init(void)
 {
 system_memory = g_malloc(sizeof(*system_memory));
 
diff --git a/hw/scsi/qemu-scsi-dev.c b/hw/scsi/qemu-scsi-dev.c
index 3cb8698..21aba91 100644
--- a/hw/scsi/qemu-scsi-dev.c
+++ b/hw/scsi/qemu-scsi-dev.c
@@ -26,10 +26,19 @@
 
 #include "qemu/osdep.h"
 #include "qemu/module.h"
+#include "remote/pcihost.h"
+#include "remote/machine.h"
+#include "hw/boards.h"
+
+static RemMachineState *machine;
 
 int main(int argc, char *argv[])
 {
 module_call_init(MODULE_INIT_QOM);
 
+machine = REMOTE_MACHINE(object_new(TYPE_REMOTE_MACHINE));
+
+current_machine = MACHINE(machine);
+
 return 0;
 }
diff --git a/include/exec/address-spaces.h b/include/exec/address-spaces.h
index db8bfa9..56a877b 100644
--- a/include/exec/address-spaces.h
+++ b/include/exec/address-spaces.h
@@ -33,6 +33,8 @@ MemoryRegion *get_system_memory(void);
  */
 MemoryRegion *get_system_io(void);
 
+void memory_map_init(void);
+
 extern AddressSpace address_space_memory;
 extern AddressSpace address_space_io;
 
diff --git a/include/remote/machine.h b/include/remote/machine.h
new file mode 100644
index 000..92f9793
--- /dev/null
+++ b/include/remote/machine.h
@@ -0,0 +1,43 @@
+/*
+ * Remote machine configuration
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_MACHINE_H
+#define REMOTE_MACHINE_H
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/boards.h"
+#include "remote/pcihost.h"
+
+typedef struct RemMachineState {
+MachineState parent_obj;
+
+RemPCIHost *host;
+} RemMachineState;
+
+#define TYPE_REMOTE_MACHINE "remote-machine"
+#define REMOTE_MACHINE(obj) \
+OBJECT_CHECK(RemMachineState, (obj), TYPE_REMOTE_MACHINE)
+
+#endif
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index 3072f95..e90ae20 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1 +1,2 @@
 remote-obj-y += pcihost.o
+remote-obj-y += machine.o
diff --git a/remote/machine.c b/remote/machine.c
new file mode 100644
index 000..9aea0ba
--- /dev/null
+++ b/remote/machine.c
@@ -0,0 +1,78 @@
+/*
+ * Machine for remote device
+ *
+ * Copyright 2018, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.

[Qemu-devel] [RFC PATCH v1 1/8] multi-process QEMU: build system for remote device process

2018-10-12 Thread Jagannathan Raman
- Makefile changes necessary to support the building of the remote device
  process is added
- functions that are necessary to compile the code, but are not needed at
  run-time are stubbed out
- main() function of remote SCSI device process is implemented

Signed-off-by: Jagannathan Raman 
---
 Makefile|  3 +-
 Makefile.objs   | 16 ++
 Makefile.target | 39 +++-
 accel/stubs/kvm-stub.c  |  5 +++
 accel/stubs/tcg-stub.c  | 81 +
 backends/Makefile.objs  |  2 ++
 block/Makefile.objs |  2 ++
 hw/Makefile.objs|  6 
 hw/block/Makefile.objs  |  2 ++
 hw/core/Makefile.objs   | 14 +
 hw/nvram/Makefile.objs  |  2 ++
 hw/pci/Makefile.objs|  4 +++
 hw/scsi/Makefile.objs   |  3 ++
 hw/scsi/qemu-scsi-dev.c | 35 +
 migration/Makefile.objs |  2 ++
 qom/Makefile.objs   |  4 +++
 stubs/monitor.c | 25 +++
 stubs/net-stub.c| 31 +++
 stubs/replay.c  | 14 +
 stubs/vl-stub.c | 79 +++
 stubs/vmstate.c | 20 
 21 files changed, 387 insertions(+), 2 deletions(-)
 create mode 100644 hw/scsi/qemu-scsi-dev.c
 create mode 100644 stubs/net-stub.c
 create mode 100644 stubs/vl-stub.c

diff --git a/Makefile b/Makefile
index 1144d6e..b6cac08 100644
--- a/Makefile
+++ b/Makefile
@@ -429,6 +429,7 @@ dummy := $(call unnest-vars,, \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
+scsi-dev-obj-y \
 common-obj-m \
 ui-obj-y \
 ui-obj-m \
@@ -507,7 +508,7 @@ CAP_CFLAGS += -DCAPSTONE_HAS_X86
 subdir-capstone: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no 
BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) 
$(BUILD_DIR)/capstone/$(LIBCAPSTONE))
 
-$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
+$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) 
$(scsi-dev-obj-y) \
$(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
diff --git a/Makefile.objs b/Makefile.objs
index 1e1ff38..0a3799c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -73,6 +73,22 @@ block-obj-$(CONFIG_REPLICATION) += replication.o
 
 block-obj-m = block/
 
+
+# scsi-dev-obj-y is code used by remote SCSI device
+
+scsi-dev-obj-y += hw/
+scsi-dev-obj-y += qom/
+scsi-dev-obj-y += backends/
+scsi-dev-obj-y += block/
+scsi-dev-obj-y += migration/
+
+scsi-dev-obj-y += cpus-common.o
+scsi-dev-obj-y += dma-helpers.o
+scsi-dev-obj-y += blockdev.o
+scsi-dev-obj-y += qdev-monitor.o
+scsi-dev-obj-y += bootdevice.o
+scsi-dev-obj-y += iothread.o
+
 ###
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index 4d56298..c5feda2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -19,21 +19,26 @@ ifdef CONFIG_USER_ONLY
 # user emulator name
 QEMU_PROG=qemu-$(TARGET_NAME)
 QEMU_PROG_BUILD = $(QEMU_PROG)
+SCSI_DEV_PROG=qemu-scsi-dev
+SCSI_DEV_BUILD = $(SCSI_DEV_PROG)
 else
 # system emulator name
 QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
+SCSI_DEV_PROG=qemu-scsi-dev
 ifneq (,$(findstring -mwindows,$(SDL_LIBS)))
 # Terminate program name with a 'w' because the linker builds a windows 
executable.
 QEMU_PROGW=qemu-system-$(TARGET_NAME)w$(EXESUF)
 $(QEMU_PROG): $(QEMU_PROGW)
$(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) 
$(QEMU_PROG),"GEN","$(TARGET_DIR)$(QEMU_PROG)")
 QEMU_PROG_BUILD = $(QEMU_PROGW)
+SCSI_DEV_BUILD = $(SCSI_DEV_PROG)
 else
 QEMU_PROG_BUILD = $(QEMU_PROG)
+SCSI_DEV_BUILD = $(SCSI_DEV_PROG)
 endif
 endif
 
-PROGS=$(QEMU_PROG) $(QEMU_PROGW)
+PROGS=$(QEMU_PROG) $(QEMU_PROGW) $(SCSI_DEV_PROG)
 STPFILES=
 
 # Makefile Tests
@@ -107,6 +112,13 @@ obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 
+scsi-dev-tgt-obj-y += accel/stubs/kvm-stub.o
+scsi-dev-tgt-obj-y += accel/stubs/tcg-stub.o
+scsi-dev-tgt-obj-y += stubs/vl-stub.o
+scsi-dev-tgt-obj-y += stubs/net-stub.o
+scsi-dev-tgt-obj-y += stubs/monitor.o
+scsi-dev-tgt-obj-y += stubs/replay.o
+
 #
 # Linux user emulator target
 
@@ -164,10 +176,20 @@ endif # CONFIG_SOFTMMU
 dummy := $(call unnest-vars,,obj-y)
 all-obj-y := $(obj-y)
 
+dummy := $(call unnest-vars,..,scsi-dev-tgt-obj-y)
+all-scsi-dev-obj-y := $(scsi-dev-tgt-obj-y)
+
+all-scsi-dev-obj-y += memory.o
+all-scsi-dev-obj-y += exec.o
+all-scsi-dev-obj-y += numa.o
+all-scsi-dev-obj-y += ioport.o
+all-scsi-dev-obj-y += cpus.o
+
 target-obj-y :=

Re: [Qemu-devel] [PATCH v4 3/3] Travis support for the acceptance tests

2018-10-12 Thread Philippe Mathieu-Daudé
Hi Cleber,

On 12/10/2018 18:53, Cleber Rosa wrote:
> This enables the execution of the acceptance tests on Travis.
> 
> Because the Travis environment is based on Ubuntu Trusty, it requires
> the python3-pip and python3.4-venv packages.
> 
> Signed-off-by: Cleber Rosa 
> ---
>  .travis.yml | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/.travis.yml b/.travis.yml
> index 95be6ec59f..f55f799c52 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -36,6 +36,8 @@ addons:
>- liburcu-dev
>- libusb-1.0-0-dev
>- libvte-2.90-dev
> +  - python3-pip
> +  - python3.4-venv

I'd prefer not put Python specific version in the generic addons list...

>- sparse
>- uuid-dev
>- gcovr
> @@ -117,6 +119,9 @@ matrix:
>  - env: CONFIG="--target-list=x86_64-softmmu"
>python:
>  - "3.6"
> +# Acceptance (Functional) tests
> +- env: CONFIG="--python=/usr/bin/python3 --target-list=x86_64-softmmu"
> +   TEST_CMD="make AVOCADO_SHOW=app check-acceptance"

... but rather in the single test that requires it:

 addons:
   apt:
 packages:
   - python3-pip
   - python3.4-venv

Alex what do you prefer?

>  # Using newer GCC with sanitizers
>  - addons:
>  apt:
> 

Both configs:
Tested-by: Philippe Mathieu-Daudé 



Re: [Qemu-devel] [PATCH v4 0/3] Bootstrap Python venv and acceptance/functional tests

2018-10-12 Thread Philippe Mathieu-Daudé
On 12/10/2018 18:53, Cleber Rosa wrote:
> TL;DR
> =
> 
> Allow acceptance tests to be run with `make check-acceptance`.
> 
> Details
> ===
> 
> This introduces a Python virtual environment that will be setup within
> the QEMU build directory, that will contain the exact environment that
> tests may require.
> 
> There's one current caveat: it requires Python 3, as it's based on the
> venv module.  This was based on some discussions and perception about
> standardizing on Python 3, but can easily be made to accommodate Python
> 2 as well.
> 
> Example of bootstrap and test execution on Travis-CI:
> 
> https://travis-ci.org/qemu/qemu/jobs/439331028#L2508

If you activate Travis on your github account, you can test that in your
namespace without having to open zombie pull requests there... A simple
push to your repository will trigger a full Travis build.

This is how I use it btw, canceling the jobs I'm not interested in, to
quickly run the others.
i.e. https://travis-ci.org/philmd/qemu/jobs/439573299#L5600

> 
>...
>   VENV/home/travis/build/qemu/qemu/tests/venv
>   MKDIR   /home/travis/build/qemu/qemu/tests/results
>   PIP /home/travis/build/qemu/qemu/tests/venv-requirements.txt
>   AVOCADO tests/acceptance
> JOB ID : 920e4fcf55a1782f1ae77bee64b20ccdc2ed
> JOB LOG: 
> /home/travis/build/qemu/qemu/tests/results/job-2018-10-09T21.42-920e4fc/job.log
>  (1/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/boot_linux_console.py:BootLinuxConsole.test:
>   PASS (3.57 s)
>  (2/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/version.py:Version.test_qmp_human_info_version:
>   PASS (0.04 s)
>  (3/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_no_vnc:  PASS 
> (0.04 s)
>  (4/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_no_vnc_change_password:
>   PASS (0.04 s)
>  (5/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_vnc_change_password_requires_a_password:
>   PASS (0.04 s)
>  (6/6) 
> /home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_vnc_change_password:
>   PASS (0.04 s)
> RESULTS: PASS 6 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
> CANCEL 0
> JOB TIME   : 3.90 s
>...
> 
> Changes from v3:
> 
> 
>  * Fixed typo in commit message (s/requiment/requirement/).  (Eric)
> 
> Changes from v2:
> 
> 
>  * Make the $(TESTS_VENV_DIR) target depend on the
>venv-requirements.txt file, and touch $(TESTS_VENV_DIR) after venv
>runs.  With this, updates on the file are reflected on the
>venv. (Philippe)
> 
>  * Run pip with "python -m pip".  It may have been installed reusing
>the system wide packages, and then the script may not be available
>on the venv. (Philippe)
> 
>  * Dropped Python version on Travis, and using the version supplied
>by the distro (3.4). (Philippe)
> 
>  * Added "python3.4-venv" package requirement on Travis. (Philippe)
> 
>  * Added variable (AVOCADO_SHOW) with logging streams to be shown
>while running the acceptance tests.  By default it's set to none,
>the equivalent of the quiet mode used on previous versions.
>(Philippe)
> 
>  * On Travis, set the AVOCADO_SHOW variable to "app", so that the
>individual test results can be easily seen.  (Philippe)
> 
> Ideas discussed, but not implemented:
> 
>   * Run pip with "$(PYTHON) -m pip -q install ..." because it points
> to the system wide Python installation. (Philippe)
> 
>   * Drop the "--system-site-packages" flag.  Waiting on another round
> of tests to determine if they are really the cause of some package
> installation problems.
> 
> Changes from v1:
> 
> 
>  * TESTS_VENV_REQ (the path of "venv-requirements.txt") now points to
>the source path ($SRC_PATH instead of $BUILD_DIR)
> 
>  * Create the venv with "--system-site-packages", which allows the
>reuse of packages (and no additional downloads) in case there's a
>package installed system wide providing the same package and
>version.
> 
>  * Run Avocado with "python -m avocado".  It may have been installed
>reusing the system wide packages, and then the script may not
>be available on the venv.
> 
>  * Improved documentation describing the Python 3, venv and pip
>requirements.
> 
>  * Updated avocado-framework requirement to latest released version
>(65.0)
> 
>  * (New commit) Added support for running the acceptance tests on
>Travis.
> 
> Ideas discussed, but not implemented:
> 
>  * Install external packages such as python3-pip on Debian based
>systems, deemed too invasive on developer's systems.
> 
>  * Allow the use of Python 2, and consequently the "virtualenv"
>module.
> 
> Cleber Rosa (3):
>   Bootstrap Python venv for tests
>   Acceptance tests: add make rule for running them
>   Travis support for the acceptance tests
> 
>  .travis.yml |  5 +
>  

Re: [Qemu-devel] [PATCH v4 2/3] Acceptance tests: add make rule for running them

2018-10-12 Thread Philippe Mathieu-Daudé
On 12/10/2018 18:53, Cleber Rosa wrote:
> The acceptance (aka functional, aka Avocado-based) tests are
> Python files located in "tests/acceptance" that need to be run
> with the Avocado libs and test runner.
> 
> Let's provide a convenient way for QEMU developers to run them,
> by making use of the tests-venv with the required setup.
> 
> Also, while the Avocado test runner will take care of creating a
> location to save test results to, it was understood that it's better
> if the results are kept within the build tree.
> 
> Signed-off-by: Cleber Rosa 
> ---
>  docs/devel/testing.rst  | 35 ++-
>  tests/Makefile.include  | 21 +++--
>  tests/venv-requirements.txt |  1 +
>  3 files changed, 50 insertions(+), 7 deletions(-)
> 
> diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
> index 727c4019b5..b992a2961d 100644
> --- a/docs/devel/testing.rst
> +++ b/docs/devel/testing.rst
> @@ -545,10 +545,31 @@ Tests based on ``avocado_qemu.Test`` can easily:
> - 
> http://avocado-framework.readthedocs.io/en/latest/api/test/avocado.html#avocado.Test
> - 
> http://avocado-framework.readthedocs.io/en/latest/api/utils/avocado.utils.html
>  
> -Installation
> -
> +Running tests
> +-
>  
> -To install Avocado and its dependencies, run:
> +You can run the acceptance tests simply by executing:
> +
> +.. code::
> +
> +  make check-acceptance
> +
> +This involves the automatic creation of Python virtual environment
> +within the build tree (at ``tests/venv``) which will have all the
> +right dependencies, and will save tests results also within the
> +build tree (at ``tests/results``).

Missing: how to activate the virtualenv.

> +
> +Note: the build environment must be using a Python 3 stack, and have
> +the ``venv`` and ``pip`` packages installed.  If necessary, make sure
> +``configure`` is called with ``--python=`` and that those modules are
> +available.  On Debian and Ubuntu based systems, depending on the
> +specific version, they may be on packages named ``python3-venv`` and
> +``python3-pip``.
> +
> +Manual Installation
> +---
> +
> +To manually install Avocado and its dependencies, run:
>  
>  .. code::
>  
> @@ -689,11 +710,15 @@ The exact QEMU binary to be used on QEMUMachine.
>  Uninstalling Avocado
>  
>  
> -If you've followed the installation instructions above, you can easily
> -uninstall Avocado.  Start by listing the packages you have installed::
> +If you've followed the manual installation instructions above, you can
> +easily uninstall Avocado.  Start by listing the packages you have
> +installed::
>  
>pip list --user
>  
>  And remove any package you want with::
>  
>pip uninstall 
> +
> +If you've used ``make check-acceptance``, the Python virtual environment 
> where
> +Avocado is installed will be cleaned up as part of ``make check-clean``.

Add a line about deactivating the venv?

> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index b66180efa1..75547fc947 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -11,6 +11,7 @@ check-help:
>   @echo " $(MAKE) check-qapi-schemaRun QAPI schema tests"
>   @echo " $(MAKE) check-block  Run block tests"
>   @echo " $(MAKE) check-tcgRun TCG tests"
> + @echo " $(MAKE) check-acceptance Run all acceptance (functional) 
> tests"
>   @echo " $(MAKE) check-report.htmlGenerates an HTML test report"
>   @echo " $(MAKE) check-venv   Creates a Python venv for tests"
>   @echo " $(MAKE) check-clean  Clean the tests"
> @@ -1020,10 +1021,15 @@ check-decodetree:
>  
>  # Python venv for running tests
>  
> -.PHONY: check-venv
> +.PHONY: check-venv check-acceptance
>  
>  TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
>  TESTS_VENV_REQ=$(SRC_PATH)/tests/venv-requirements.txt
> +TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
> +# Controls the output generated by Avocado when running tests.
> +# Any number of command separated loggers are accepted.  For more
> +# information please refer to "avocado --help".
> +AVOCADO_SHOW=none
>  
>  $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>   $(call quiet-command, \
> @@ -1034,8 +1040,19 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
>  PIP, $(TESTS_VENV_REQ))
>   $(call quiet-command, touch $@)
>  
> +$(TESTS_RESULTS_DIR):
> + $(call quiet-command, mkdir -p $@, \
> +MKDIR, $@)
> +
>  check-venv: $(TESTS_VENV_DIR)
>  
> +check-acceptance: check-venv $(TESTS_RESULTS_DIR)
> + $(call quiet-command, \
> +$(TESTS_VENV_DIR)/bin/python -m avocado \
> +--show=$(AVOCADO_SHOW) run 
> --job-results-dir=$(TESTS_RESULTS_DIR) \
> +--failfast=on $(SRC_PATH)/tests/acceptance, \
> +"AVOCADO", "tests/acceptance")
> +
>  # Consolidated targets
>  
>  .PHONY: check-qapi-schema check-qtest check-unit check check-clean
> @@ -1049,7 +1066,7 @@ 

Re: [Qemu-devel] [PATCH v4 1/3] Bootstrap Python venv for tests

2018-10-12 Thread Philippe Mathieu-Daudé
Hi Cleber,

On 12/10/2018 18:53, Cleber Rosa wrote:
> A number of QEMU tests are written in Python, and may benefit
> from an untainted Python venv.
> 
> By using make rules, tests that depend on specific Python libs
> can set that rule as a requirement, along with rules that require
> the presence or installation of specific libraries.
> 
> The tests/venv-requirements.txt is supposed to contain the
> Python requirements that should be added to the venv created
> by check-venv.

Maybe you (or Eduardo...) what you wrote in the cover:

 There's one current caveat: it requires Python 3, as it's based on the
 venv module.

To explain:

$ make check-acceptance
/usr/bin/python2: No module named venv
make: *** [/home/phil/source/qemu/tests/Makefile.include:1033:] Error 1

> 
> Signed-off-by: Cleber Rosa 
> ---
>  tests/Makefile.include  | 20 
>  tests/venv-requirements.txt |  3 +++
>  2 files changed, 23 insertions(+)
>  create mode 100644 tests/venv-requirements.txt
> 
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 5eadfd52f9..b66180efa1 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -12,6 +12,7 @@ check-help:
>   @echo " $(MAKE) check-block  Run block tests"
>   @echo " $(MAKE) check-tcgRun TCG tests"
>   @echo " $(MAKE) check-report.htmlGenerates an HTML test report"
> + @echo " $(MAKE) check-venv   Creates a Python venv for tests"
>   @echo " $(MAKE) check-clean  Clean the tests"
>   @echo
>   @echo "Please note that HTML reports do not regenerate if the unit 
> tests"
> @@ -1017,6 +1018,24 @@ check-decodetree:
>./check.sh "$(PYTHON)" "$(SRC_PATH)/scripts/decodetree.py", \
>TEST, decodetree.py)
>  
> +# Python venv for running tests
> +
> +.PHONY: check-venv
> +
> +TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
> +TESTS_VENV_REQ=$(SRC_PATH)/tests/venv-requirements.txt
> +
> +$(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
> + $(call quiet-command, \
> +$(PYTHON) -m venv --system-site-packages $@, \
> +VENV, $@)
> + $(call quiet-command, \
> +$(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
> $(TESTS_VENV_REQ), \
> +PIP, $(TESTS_VENV_REQ))
> + $(call quiet-command, touch $@)

Hmm maybe we should print something like:

  "You can now activate this virtual environment using:
source $(TESTS_VENV_DIR)/tests/venv/bin/activate"

> +
> +check-venv: $(TESTS_VENV_DIR)
> +
>  # Consolidated targets
>  
>  .PHONY: check-qapi-schema check-qtest check-unit check check-clean
> @@ -1030,6 +1049,7 @@ check-clean:
>   rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
>   rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), 
> $(check-qtest-$(target)-y)) $(check-qtest-generic-y))
>   rm -f tests/test-qapi-gen-timestamp
> + rm -rf $(TESTS_VENV_DIR)
>  
>  clean: check-clean
>  
> diff --git a/tests/venv-requirements.txt b/tests/venv-requirements.txt
> new file mode 100644
> index 00..d39f9d1576
> --- /dev/null
> +++ b/tests/venv-requirements.txt
> @@ -0,0 +1,3 @@
> +# Add Python module requirements, one per line, to be installed
> +# in the tests/venv Python virtual environment. For more info,
> +# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
> 

Tested-by: Philippe Mathieu-Daudé 



Re: [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence insns to decodetree

2018-10-12 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +%pred   24:4
> +%succ   20:4
...
> +@noargs  
...
> +@fence      .  ... . ... %pred %succ
...
> +fence     0 000 0 000 @fence
> +fence_i   0 001 0 000 @noargs

@noargs is useless, even as documentation, since by its omission there are no
arguments.

Also, "the unused fields in the FENCE instruction, imm[11:8], rs1, and rd, are
reserved for finer-grain fences in future extensions. For forward
compatibility, base implementations shall ignore these fields, and standard
software shall zero these fields."

Therefore "-" not "0" in the relevant portions.  And for clarity I would simply
fold it all together as

fence    pred:4 succ:4 - 000 - 000
fence_i        - 001 - 000

Or just use "@i", which is the underlying format and ignore the rs1 and rd
fields in the trans_ expanders, and pull pred+succ out of imm there.


r~



Re: [Qemu-devel] [PATCH v3 2/3] linux-user: Define ordinary usbfs ioctls.

2018-10-12 Thread Laurent Vivier
On 08/10/2018 18:35, Cortland Tölva wrote:
> Provide ioctl definitions for the generic thunk mechanism to
> convert most usbfs calls.  Calculate arg size at runtime.
> 
> Signed-off-by: Cortland Tölva 
> ---
> Changes from v1:
>   move some type definitions to patch 3/3
> Changes from v2:
>   calculate ioctl arg size at runtime
> 
>  linux-user/ioctls.h| 38 
>  linux-user/syscall.c   |  3 +++
>  linux-user/syscall_defs.h  | 24 +++
>  linux-user/syscall_types.h | 48 
> ++
>  4 files changed, 113 insertions(+)
> 

Reviewed-by: Laurent Vivier 





[Qemu-devel] [PATCH v4 0/3] Dynamic TLB sizing

2018-10-12 Thread Emilio G. Cota
RFC v3: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg01753.html

Changes since RFC v3:

- This is now a proper patch series, since it should not (knowingly)
  break anything.

- Rebase on top of rth's tcg-next (ffd8994b90f5), which includes
  patch 1 from RFC v3.

- Make the feature optional, so that we don't need to change
  all TCG backends right now. For this, define
  TCG_TARGET_IMPLEMENTS_DYN_TLB, which follows a similar approach
  to what we do with TCG instructions with TCG_TARGET_HAS_foo.

- Merge most changes into a single patch to ease review.
  Alex: as a result I dropped two of your R-b's, but note that the
  only change is the addition of inline helpers to hide whether the
  TCG backend implements the feature.

The series is checkpatch-clean. You can fetch it from:
  https://github.com/cota/qemu/tree/tlb-dyn-v4

Thanks,

Emilio





[Qemu-devel] [PATCH v4 3/3] tcg/i386: enable dynamic TLB sizing

2018-10-12 Thread Emilio G. Cota
As the following experiments show, this a net perf gain,
particularly for memory-heavy workloads. Experiments
are run on an Intel i7-6700K CPU @ 4.00GHz.

1. System boot + shudown, debian aarch64:

- Before (tb-lock-v3):
 Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):

   7469.363393  task-clock (msec) #0.998 CPUs utilized  
  ( +-  0.07% )
31,507,707,190  cycles#4.218 GHz
  ( +-  0.07% )
57,101,577,452  instructions  #1.81  insns per cycle
  ( +-  0.08% )
10,265,531,804  branches  # 1374.352 M/sec  
  ( +-  0.07% )
   173,020,681  branch-misses #1.69% of all branches
  ( +-  0.10% )

   7.483359063 seconds time elapsed 
 ( +-  0.08% )

- After:
 Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):

   7185.036730  task-clock (msec) #0.999 CPUs utilized  
  ( +-  0.11% )
30,303,501,143  cycles#4.218 GHz
  ( +-  0.11% )
54,198,386,487  instructions  #1.79  insns per cycle
  ( +-  0.08% )
 9,726,518,945  branches  # 1353.719 M/sec  
  ( +-  0.08% )
   167,082,307  branch-misses #1.72% of all branches
  ( +-  0.08% )

   7.195597842 seconds time elapsed 
 ( +-  0.11% )

That is, a 3.8% improvement.

2. System boot + shutdown, ubuntu 18.04 x86_64:

- Before (tb-lock-v3):
Performance counter stats for 'taskset -c 0 ../img/x86_64/ubuntu-die.sh 
-nographic' (2 runs):

  49971.036482  task-clock (msec) #0.999 CPUs utilized  
  ( +-  1.62% )
   210,766,077,140  cycles#4.218 GHz
  ( +-  1.63% )
   428,829,830,790  instructions  #2.03  insns per cycle
  ( +-  0.75% )
77,313,384,038  branches  # 1547.164 M/sec  
  ( +-  0.54% )
   835,610,706  branch-misses #1.08% of all branches
  ( +-  2.97% )

  50.003855102 seconds time elapsed 
 ( +-  1.61% )

- After:
 Performance counter stats for 'taskset -c 0 ../img/x86_64/ubuntu-die.sh 
-nographic' (2 runs):

  50118.124477  task-clock (msec) #0.999 CPUs utilized  
  ( +-  4.30% )
   132,396  context-switches  #0.003 M/sec  
  ( +-  1.20% )
 0  cpu-migrations#0.000 K/sec  
  ( +-100.00% )
   167,754  page-faults   #0.003 M/sec  
  ( +-  0.06% )
   211,414,701,601  cycles#4.218 GHz
  ( +-  4.30% )
 stalled-cycles-frontend
 stalled-cycles-backend
   431,618,818,597  instructions  #2.04  insns per cycle
  ( +-  6.40% )
80,197,256,524  branches  # 1600.165 M/sec  
  ( +-  8.59% )
   794,830,352  branch-misses #0.99% of all branches
  ( +-  2.05% )

  50.177077175 seconds time elapsed 
 ( +-  4.23% )

No improvement (within noise range).

3. x86_64 SPEC06int:
  SPEC06int (test set)
 [ Y axis: speedup over master ]
  8 +-+--+++-+++++++-+++--+-+
|   |
|   tlb-lock-v3 |
  7 +-+..$$$...+indirection   +-+
|$ $  +resizing |
|$ $|
  6 +-+..$.$..+-+
|$ $|
|$ $|
  5 +-+..$.$..+-+
|$ $|
|$ $|
  4 +-+..$.$..+-+
|$ $|
|  +++   $ $|
  3 +-+$$+...$.$..+-+
|  $$$ $|
|  $$$ $

[Qemu-devel] [PATCH v4 1/3] cputlb: do not evict empty entries to the vtlb

2018-10-12 Thread Emilio G. Cota
Currently we evict an entry to the victim TLB when it doesn't match
the current address. But it could be that there's no match because
the current entry is empty (i.e. all -1's, for instance via tlb_flush).
Do not evict the entry to the vtlb in that case.

This change will help us keep track of the TLB's use rate, which
we'll use to implement a policy for dynamic TLB sizing.

Reviewed-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Signed-off-by: Emilio G. Cota 
---
 include/exec/cpu-all.h | 9 +
 accel/tcg/cputlb.c | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 117d2fbbca..e21140049b 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -362,6 +362,15 @@ static inline bool tlb_hit(target_ulong tlb_addr, 
target_ulong addr)
 return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK);
 }
 
+/**
+ * tlb_entry_is_empty - return true if the entry is not in use
+ * @te: pointer to CPUTLBEntry
+ */
+static inline bool tlb_entry_is_empty(const CPUTLBEntry *te)
+{
+return te->addr_read == -1 && te->addr_write == -1 && te->addr_code == -1;
+}
+
 void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
 #endif /* !CONFIG_USER_ONLY */
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index a6b716eb79..6ee18308d5 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -678,7 +678,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  * Only evict the old entry to the victim tlb if it's for a
  * different page; otherwise just overwrite the stale data.
  */
-if (!tlb_hit_page_anyprot(te, vaddr_page)) {
+if (!tlb_hit_page_anyprot(te, vaddr_page) && !tlb_entry_is_empty(te)) {
 unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
 CPUTLBEntry *tv = >tlb_v_table[mmu_idx][vidx];
 
-- 
2.17.1




[Qemu-devel] [PATCH v4 2/3] tcg: introduce dynamic TLB sizing

2018-10-12 Thread Emilio G. Cota
Disable for all TCG backends for now.

Signed-off-by: Emilio G. Cota 
---
 include/exec/cpu-defs.h  |  43 +++-
 include/exec/cpu_ldst.h  |  21 ++
 tcg/aarch64/tcg-target.h |   1 +
 tcg/arm/tcg-target.h |   1 +
 tcg/i386/tcg-target.h|   1 +
 tcg/mips/tcg-target.h|   1 +
 tcg/ppc/tcg-target.h |   1 +
 tcg/s390/tcg-target.h|   1 +
 tcg/sparc/tcg-target.h   |   1 +
 tcg/tci/tcg-target.h |   1 +
 accel/tcg/cputlb.c   | 138 +--
 11 files changed, 201 insertions(+), 9 deletions(-)

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 4ff62f32bf..40cd5d4774 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -67,6 +67,19 @@ typedef uint64_t target_ulong;
 #define CPU_TLB_ENTRY_BITS 5
 #endif
 
+#if TCG_TARGET_IMPLEMENTS_DYN_TLB
+#define CPU_TLB_DYN_MIN_BITS 6
+#define CPU_TLB_DYN_DEFAULT_BITS 8
+/*
+ * Assuming TARGET_PAGE_BITS==12, with 2**22 entries we can cover 2**(22+12) ==
+ * 2**34 == 16G of address space. This is roughly what one would expect a
+ * TLB to cover in a modern (as of 2018) x86_64 CPU. For instance, Intel
+ * Skylake's Level-2 STLB has 16 1G entries.
+ */
+#define CPU_TLB_DYN_MAX_BITS 22
+
+#else /* !TCG_TARGET_IMPLEMENTS_DYN_TLB */
+
 /* TCG_TARGET_TLB_DISPLACEMENT_BITS is used in CPU_TLB_BITS to ensure that
  * the TLB is not unnecessarily small, but still small enough for the
  * TLB lookup instruction sequence used by the TCG target.
@@ -98,6 +111,7 @@ typedef uint64_t target_ulong;
  NB_MMU_MODES <= 8 ? 3 : 4))
 
 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
+#endif /* TCG_TARGET_IMPLEMENTS_DYN_TLB */
 
 typedef struct CPUTLBEntry {
 /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
@@ -141,13 +155,36 @@ typedef struct CPUIOTLBEntry {
 MemTxAttrs attrs;
 } CPUIOTLBEntry;
 
-#define CPU_COMMON_TLB \
+#if TCG_TARGET_IMPLEMENTS_DYN_TLB
+
+typedef struct CPUTLBDesc {
+size_t n_used_entries;
+size_t n_flushes_low_rate;
+} CPUTLBDesc;
+
+#define CPU_TLB \
+CPUTLBDesc tlb_desc[NB_MMU_MODES];  \
+/* tlb_mask[i] contains (n_entries - 1) << CPU_TLB_ENTRY_BITS */\
+uintptr_t tlb_mask[NB_MMU_MODES];   \
+CPUTLBEntry *tlb_table[NB_MMU_MODES];
+
+#define CPU_IOTLB   \
+CPUIOTLBEntry *iotlb[NB_MMU_MODES];
+#else
+#define CPU_TLB \
+CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];
+
+#define CPU_IOTLB   \
+CPUIOTLBEntry iotlb[NB_MMU_MODES][CPU_TLB_SIZE];
+#endif /* TCG_TARGET_IMPLEMENTS_DYN_TLB */
+
+#define CPU_COMMON_TLB  \
 /* The meaning of the MMU modes is defined in the target code. */   \
 /* tlb_lock serializes updates to tlb_table and tlb_v_table */  \
 QemuSpin tlb_lock;  \
-CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];  \
+CPU_TLB \
 CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE];   \
-CPUIOTLBEntry iotlb[NB_MMU_MODES][CPU_TLB_SIZE];\
+CPU_IOTLB   \
 CPUIOTLBEntry iotlb_v[NB_MMU_MODES][CPU_VTLB_SIZE]; \
 size_t tlb_flush_count; \
 target_ulong tlb_flush_addr;\
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index e3d8d738aa..91f29c1188 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -126,6 +126,21 @@ extern __thread uintptr_t helper_retaddr;
 /* The memory helpers for tcg-generated code need tcg_target_long etc.  */
 #include "tcg.h"
 
+#if TCG_TARGET_IMPLEMENTS_DYN_TLB
+/* Find the TLB index corresponding to the mmu_idx + address pair.  */
+static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
+  target_ulong addr)
+{
+uintptr_t size_mask = env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS;
+
+return (addr >> TARGET_PAGE_BITS) & size_mask;
+}
+
+static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
+{
+return (env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS) + 1;
+}
+#else
 /* Find the TLB index corresponding to the mmu_idx + address pair.  */
 static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
   target_ulong addr)
@@ -133,6 +148,12 @@ static inline uintptr_t tlb_index(CPUArchState *env, 
uintptr_t mmu_idx,
 return (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 }
 
+static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
+{
+return CPU_TLB_SIZE;
+}
+#endif /* TCG_TARGET_IMPLEMENTS_DYN_TLB */
+
 /* Find 

Re: [Qemu-devel] [PATCH] linux-user: Fix crashes in ioctl(SIOCGIFCONF) when ifc_buf is NULL.

2018-10-12 Thread Laurent Vivier
On 09/10/2018 09:45, Kan Li wrote:
> Summary:
> This is to fix bug https://bugs.launchpad.net/qemu/+bug/1796754.
> It is valid for ifc_buf to be NULL according to
> http://man7.org/linux/man-pages/man7/netdevice.7.html.
> 
> Signed-off-by: Kan Li 
> ---
>  linux-user/syscall.c | 56 
>  1 file changed, 31 insertions(+), 25 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ae3c0dfef7..fbab98d4f7 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -4134,28 +4134,33 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, 
> uint8_t *buf_temp,
>  unlock_user(argptr, arg, 0);
>  
>  host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
> -target_ifc_len = host_ifconf->ifc_len;
>  target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
>  
> -target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
> -nb_ifreq = target_ifc_len / target_ifreq_size;
> -host_ifc_len = nb_ifreq * sizeof(struct ifreq);
> +if (target_ifc_buf != 0) {
> +target_ifc_len = host_ifconf->ifc_len;
>  
> -outbufsz = sizeof(*host_ifconf) + host_ifc_len;
> -if (outbufsz > MAX_STRUCT_SIZE) {
> -/* We can't fit all the extents into the fixed size buffer.
> - * Allocate one that is large enough and use it instead.
> - */
> -host_ifconf = malloc(outbufsz);
> -if (!host_ifconf) {
> -return -TARGET_ENOMEM;
> +target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
> +nb_ifreq = target_ifc_len / target_ifreq_size;
> +host_ifc_len = nb_ifreq * sizeof(struct ifreq);
> +
> +outbufsz = sizeof(*host_ifconf) + host_ifc_len;
> +if (outbufsz > MAX_STRUCT_SIZE) {
> +/* We can't fit all the extents into the fixed size buffer.
> + * Allocate one that is large enough and use it instead.
> + */
> +host_ifconf = malloc(outbufsz);
> +if (!host_ifconf) {
> +return -TARGET_ENOMEM;
> +}
> +memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
> +free_buf = 1;
>  }
> -memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
> -free_buf = 1;
> -}
> -host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
> +host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
>  
> -host_ifconf->ifc_len = host_ifc_len;
> +host_ifconf->ifc_len = host_ifc_len;
> +} else {
> +  host_ifc_buf = NULL;
> +}
>  host_ifconf->ifc_buf = host_ifc_buf;
>  
>  ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
> @@ -4178,15 +4183,16 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, 
> uint8_t *buf_temp,
>  thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
>  unlock_user(argptr, arg, target_size);
>  
> - /* copy ifreq[] to target user */
> -
> -argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
> -for (i = 0; i < nb_ifreq ; i++) {
> -thunk_convert(argptr + i * target_ifreq_size,
> -  host_ifc_buf + i * sizeof(struct ifreq),
> -  ifreq_arg_type, THUNK_TARGET);
> +if (target_ifc_buf != 0) {
> +/* copy ifreq[] to target user */
> +argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 
> 0);
> +for (i = 0; i < nb_ifreq ; i++) {
> +thunk_convert(argptr + i * target_ifreq_size,
> +  host_ifc_buf + i * sizeof(struct ifreq),
> +  ifreq_arg_type, THUNK_TARGET);
> +}
> +unlock_user(argptr, target_ifc_buf, target_ifc_len);
>  }
> -unlock_user(argptr, target_ifc_buf, target_ifc_len);
>  }
>  
>  if (free_buf) {
> 

Applied to my branch linux-user-for-3.1

Thanks,
Laurent



Re: [Qemu-devel] [PATCH] linux-user: Fix crashes in ioctl(SIOCGIFCONF) when ifc_buf is NULL.

2018-10-12 Thread Laurent Vivier
On 09/10/2018 09:45, Kan Li wrote:
> Summary:
> This is to fix bug https://bugs.launchpad.net/qemu/+bug/1796754.
> It is valid for ifc_buf to be NULL according to
> http://man7.org/linux/man-pages/man7/netdevice.7.html.
> 
> Signed-off-by: Kan Li 
> ---
>  linux-user/syscall.c | 56 
>  1 file changed, 31 insertions(+), 25 deletions(-)

Reviewed-by: Laurent Vivier 



Re: [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree

2018-10-12 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
> +{
> +gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
> +return true;
> +}
> +static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
> +{
> +if (a->rd != 0) {
> +TCGv t = tcg_temp_new();
> +gen_get_gpr(t, a->rs1);
> +
> +if (a->shamt >= TARGET_LONG_BITS) {
> +gen_exception_illegal(ctx);
> +return true;
> +}
> +tcg_gen_shli_tl(t, t, a->shamt);
> +
> +gen_set_gpr(a->rd, t);
> +tcg_temp_free(t);
> +} /* NOP otherwise */
> +return true;
> +}

Spacing.  Any reason why trans_slli (and the other shifts) aren't using
gen_arith_imm as well?

> +static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
> +{
> +#if !defined(TARGET_RISCV64)
> +gen_exception_illegal(ctx);
> +return true;
> +#endif
> +gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
> +return true;
> +}

return false, like you did for trans_ld?


r~



Re: [Qemu-devel] [PATCH v5 21/28] target/mips: Add opcodes for nanoMIPS EVA instructions

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 21/28] target/mips: Add opcodes for nanoMIPS EVA 
> instructions
>
> From: Dimitrije Nikolic 
>
> Add opcodes for nanoMIPS EVA instructions: CACHEE, LBE, LBUE, LHE,
LHUE, LLE, LLWPE, LWE, PREFE, SBE, SCE, SCWPE, SHE, SWE.
>
> Signed-off-by: Dimitrije Nikolic 
> Signed-off-by: Aleksandar Markovic 
> ---

Reviewed-by: Aleksandar Markovic 


Re: [Qemu-devel] [PATCH v5 22/28] target/mips: Add CP0 Config2 to DisasContext

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 22/28] target/mips: Add CP0 Config2 to DisasContext
>
> From: Stefan Markovic 
>
> Add field corresponding to CP0 Config2 to DisasContext. This is
needed for availability control via Config2 bits.
>
> Signed-off-by: Stefan Markovic 
> Signed-off-by: Aleksandar Markovic 
> ---

Reviewed-by: Aleksandar Markovic 


Re: [Qemu-devel] [PATCH v2 2/3] audio: use object link instead ofqdev property to pass wm8750 reference

2018-10-12 Thread Philippe Mathieu-Daudé
Hi Mao,

On 12/10/2018 14:30, Philippe Mathieu-Daudé wrote:
> Cc'ing Eduardo and Thomas.
> 
> On 12/10/2018 13:51, maozy wrote:
>> Hi, Philippe
>>
>> On 10/12/18 5:53 PM, Philippe Mathieu-Daudé wrote:
>>> Hi Mao,
>>>
>>> On 12/10/2018 10:30, Mao Zhongyi wrote:
 According to qdev-properties.h, properties of pointer type should
 be avoided, it seems a link type property is a good substitution.

 Cc: Jan Kiszka 
 Cc: Peter Maydell 
 Cc: Gerd Hoffmann 
 To: qemu-...@nongnu.org

 Signed-off-by: Mao Zhongyi 
 ---
   hw/arm/musicpal.c  |  3 ++-
   hw/audio/marvell_88w8618.c | 14 ++
   2 files changed, 8 insertions(+), 9 deletions(-)

 diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
 index 3dafb41b0b..ac266f9253 100644
 --- a/hw/arm/musicpal.c
 +++ b/hw/arm/musicpal.c
 @@ -1695,7 +1695,8 @@ static void musicpal_init(MachineState *machine)
   wm8750_dev = i2c_create_slave(i2c, TYPE_WM8750, MP_WM_ADDR);
   dev = qdev_create(NULL, "mv88w8618_audio");
   s = SYS_BUS_DEVICE(dev);
 -    qdev_prop_set_ptr(dev, TYPE_WM8750, wm8750_dev);
 +    object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev),
 + TYPE_WM8750, NULL);
   qdev_init_nofail(dev);
   sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
   sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
 diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
 index cf6ce6979b..baab4a3d53 100644
 --- a/hw/audio/marvell_88w8618.c
 +++ b/hw/audio/marvell_88w8618.c
 @@ -15,6 +15,7 @@
   #include "hw/i2c/i2c.h"
   #include "hw/audio/wm8750.h"
   #include "audio/audio.h"
 +#include "qapi/error.h"
     #define MP_AUDIO_SIZE   0x1000
   @@ -252,6 +253,11 @@ static void mv88w8618_audio_init(Object *obj)
   memory_region_init_io(>iomem, obj, _audio_ops, s,
     "audio", MP_AUDIO_SIZE);
   sysbus_init_mmio(dev, >iomem);
 +
 +    object_property_add_link(OBJECT(dev), "mv88w8618", TYPE_WM8750,
 + (Object **) >wm,
 + qdev_prop_allow_set_link_before_realize,
 + 0, _abort);
   }
     static void mv88w8618_audio_realize(DeviceState *dev, Error **errp)
 @@ -279,11 +285,6 @@ static const VMStateDescription
 mv88w8618_audio_vmsd = {
   }
   };
   -static Property mv88w8618_audio_properties[] = {
 -    DEFINE_PROP_PTR(TYPE_WM8750, mv88w8618_audio_state, wm),
 -    {/* end of list */},
 -};
 -
   static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
   {
   DeviceClass *dc = DEVICE_CLASS(klass);
 @@ -291,9 +292,6 @@ static void
 mv88w8618_audio_class_init(ObjectClass *klass, void *data)
   dc->realize = mv88w8618_audio_realize;
   dc->reset = mv88w8618_audio_reset;
   dc->vmsd = _audio_vmsd;
 -    dc->props = mv88w8618_audio_properties;
 -    /* Reason: pointer property "wm8750" */
 -    dc->user_creatable = false;
>>>
>>> Having a link property isn't it the same restriction?
>>
>> This task can found in
>> https://wiki.qemu.org/Contribute/BiteSizedTasks#Device_models
>>
>> Convert qdev pointer properties (defined with DEFINE_PROP_PTR) to QOM
>> links. Example: commit 873b4d3.
> 
> I agree with the QOM conversion (the rest of this patch), what I'm
> wondering is if declaring this device now user_creatable is correct. I
> don't think we can set link property from command line, but maybe I'm
> wrong because I never investigate/tried to do it.
> 
> Maybe devices having link property are automatically marked as
> user_creatable = false, then your change would be correct (except you
> should explicit that in the commit message).
> 
> I'll post another mail on the list to ask about that.

On https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02531.html

Peter answered:

  I think whether a device with a link property is
  user creatable might depend on what the property is
  for and whether the device has a useful fallback for
  "link not connected".

So if you look the realize function, there is no check on the linked object:

static void mv88w8618_audio_realize(DeviceState *dev, Error **errp)
{
mv88w8618_audio_state *s = MV88W8618_AUDIO(dev);

wm8750_data_req_set(s->wm, mv88w8618_audio_callback, s);
}

Then the called function dereference the WM8750State:

void wm8750_data_req_set(DeviceState *dev, data_req_cb *data_req,
 void *opaque)
{
WM8750State *s = WM8750(dev);

s->data_req = data_req;
s->opaque = opaque;
}

So this patch is incorrect. You should either keep the
'dc->user_creatable = false' line, or add a check in the realize()
function, as here:

static void bcm2836_realize(DeviceState 

Re: [Qemu-devel] [PATCH v5 25/28] hw/mips: Add Data Scratch Pad RAM

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 25/28] hw/mips: Add Data Scratch Pad RAM
>
>From: Yongbok Kim 
>
> The optional Data Scratch Pad RAM (DSPRAM) block provides a
general scratch pad RAM used for temporary storage of data. The
DSPRAM provides a connection to on-chip memory or memory-mapped
registers, which are accessed in parallel with the L1 data
cache to minimize access latency.
>
> Signed-off-by: Yongbok Kim 
> Signed-off-by: Aleksandar Markovic 
> ---

This patch is incomplete - some files are missing.

Thanks,
Aleksandar


Re: [Qemu-devel] [PATCH v5 08/28] target/mips: Add CPO PWBase register

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 08/28] target/mips: Add CPO PWBase register
>
> From: Yongbok Kim 
>
>Add PWBase register (CP0 Register 5, Select 5).

This and several other patches in this series contain letter "O" instead of 
digit "0" in their title. This should be corrected.

Aleksandar


Re: [Qemu-devel] [PATCH v2] linux-user: Suppress address-of-packed-member warnings in __get/put_user_e

2018-10-12 Thread Laurent Vivier
On 09/10/2018 18:18, Peter Maydell wrote:
> Our __get_user_e() and __put_user_e() macros cause newer versions
> of clang to generate false-positive -Waddress-of-packed-member
> warnings if they are passed the address of a member of a packed
> struct (see https://bugs.llvm.org/show_bug.cgi?id=39113).
> Suppress these using the _Pragma() operator. Unfortunately
> _Pragma() support in gcc is broken in some gcc versions and
> in some usage contexts, so we limit the pragma usage here to clang.
> 
> To put in the pragmas we need to convert the macros from
> expressions to statements, but all the callsites effectively
> treat them as statements already so this is OK.
> 
> Signed-off-by: Peter Maydell 
> ---
> Changes v1->v2: _Pragma() in gcc appears to be a disaster area;
> limit the use of it to clang only, since it's just clang that
> emits the bogus warning in this case. Tested on clang-3.8.0,
> clang-7, gcc 5.4.0 and gcc 8.0.1.
> 
>  linux-user/qemu.h | 70 ++-
>  1 file changed, 51 insertions(+), 19 deletions(-)
> 

Applied to my branch linux-user-for-3.1

Thanks,
Laurent



Re: [Qemu-devel] [PATCH] linux-user/sparc/signal.c: Remove unnecessary comment

2018-10-12 Thread Laurent Vivier
On 09/10/2018 20:40, Peter Maydell wrote:
> Remove a comment suggesting that we need to call tb_flush()
> after writing the SPARC signal frame trampoline insns.
> This isn't necessary in QEMU, because (even if the guest
> architecture requires explicit icache maintenance) we
> ensure that memory writes result in invalidation of
> translated code from that memory.
> 
> Signed-off-by: Peter Maydell 
> ---
> Found (with grep) while looking at what parts of the tree call
> tb_flush()...
> 
>  linux-user/sparc/signal.c | 4 

Applied to my branch linux-user-for-3.1

Thanks,
Laurent



Re: [Qemu-devel] [PATCH v5 04/28] linux-user: Add MIPS-specific prctl() options

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 04/28] linux-user: Add MIPS-specific prctl() options
>
> From: Stefan Markovic 
>
>Add MIPS-specific prctl() options TARGET_PR_SET_FP_MODE and
TARGET_PR_SET_FP_MODE. These values are essentially copied from
linux kernel header include/uapi/linux/prctl.h.
>
>This is done in a way consistent with a similar case of
aarch64-specific prctl() options TARGET_PR_SVE_SET_VL and
TARGET_PR_SVE_GET_VL.
>
> Signed-off-by: Stefan Markovic 
> Signed-off-by: Aleksandar Markovic 
> ---

Reviewed-by: Aleksandar Markovic 



Re: [Qemu-devel] [PATCH v5 05/28] linux-user: Add infrastructure for handling MIPS-specific prctl()

2018-10-12 Thread Aleksandar Markovic
> Subject: [PATCH v5 05/28] linux-user: Add infrastructure for handling 
> MIPS-specific prctl()
>
> From: Stefan Markovic 
>
>Add infrastructure for handling MIPS-specific prctl(). This is,
for now, just an empty placeholder. The real handling will be
implemented in subsequent patches.
>
> Signed-off-by: Stefan Markovic 
> Signed-off-by: Aleksandar Markovic 
> ---
> linux-user/syscall.c | 8 
> 1 file changed, 8 insertions(+)

Reviewed-by: Aleksandar Markovic 



Re: [Qemu-devel] [PATCH] Makefile: Install new vgabios binaries

2018-10-12 Thread Philippe Mathieu-Daudé
On 12/10/2018 18:26, Alex Williamson wrote:
> Difficult to make use of if not installed
> 
> Fixes: cd1bfd5ef336 ("seabios: update bios and vgabios binaries")
> Signed-off-by: Alex Williamson 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
> 
>  Makefile |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Makefile b/Makefile
> index 1144d6e3ba0e..f2947186a4c3 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -802,6 +802,7 @@ bepocz
>  ifdef INSTALL_BLOBS
>  BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
>  vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
> +vgabios-ramfb.bin vgabios-bochs-display.bin \
>  ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin 
> QEMU,cgthree.bin \
>  pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
>  pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
> 
> 



Re: [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store insns to decodetree

2018-10-12 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +}
> +static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)

Watch your spacing.  Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree

2018-10-12 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
> +{
> +CPURISCVState *env = current_cpu->env_ptr;
> +gen_jal(env, ctx, a->rd, a->imm);

I think you should go ahead and put env into ctx, which is probably where it
should have been in the first place for gen_jal et al to examine features.

Reading from current_cpu is definitely suspect.


r~



Re: [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC

2018-10-12 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +#define EX_SH(amount) \
> +static int64_t ex_shift_##amount(int imm) \
> +{ \
> +return imm << amount; \
> +}

The int64_t return doesn't help, because it'll be stored back into a struct
that uses just "int".  If you have a shift that goes outside that, you'd have
to handle it in the trans_* function.  Which is not the case here, at least.

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [RFC 1/5] virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate

2018-10-12 Thread Michael S. Tsirkin
On Fri, Oct 12, 2018 at 02:24:27PM +1100, David Gibson wrote:
> When the balloon is inflated, we discard memory place in it using madvise()
> with MADV_DONTNEED.  And when we deflate it we use MADV_WILLNEED, which
> sounds like it makes sense but is actually unnecessary.
> 
> The misleadingly named MADV_DONTNEED just discards the memory in question,
> it doesn't set any persistent state on it in-kernel; all that's necessary
> to bring the memory back is to touch it.  MADV_WILLNEED in contrast
> specifically says that the memory will be used soon and faults it in.
> 
> Memory that's being given back to the guest by deflating the balloon
> *might* be used soon, but it equally could just sit around in the guest's
> pools until it actually needs it.  And, over the general timescale that
> memory ballooning operates, it seems unlikely that one extra fault for the
> guest will be a vast performance issue.

Thinking about it, it might be for RT guests.

So I suspect if you want to drop MADV_WILLNEED you need a flag
telling qemu that's not the usecase.




> So, simplify the balloon's operation by dropping the madvise() on deflate.
> 
> Signed-off-by: David Gibson 
> ---
>  hw/virtio/virtio-balloon.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index 1728e4f83a..6ec4bcf4e1 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -35,9 +35,8 @@
>  
>  static void balloon_page(void *addr, int deflate)
>  {
> -if (!qemu_balloon_is_inhibited()) {
> -qemu_madvise(addr, BALLOON_PAGE_SIZE,
> -deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
> +if (!qemu_balloon_is_inhibited() && !deflate) {
> +qemu_madvise(addr, BALLOON_PAGE_SIZE, QEMU_MADV_DONTNEED);
>  }
>  }
>  
> -- 
> 2.17.1



Re: [Qemu-devel] [RFC 1/5] virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate

2018-10-12 Thread Eric Blake

On 10/12/18 12:41 PM, Richard Henderson wrote:

On 10/11/18 8:24 PM, David Gibson wrote:

When the balloon is inflated, we discard memory place in it using madvise()
with MADV_DONTNEED.  And when we deflate it we use MADV_WILLNEED, which
sounds like it makes sense but is actually unnecessary.

The misleadingly named MADV_DONTNEED just discards the memory in question,
it doesn't set any persistent state on it in-kernel; all that's necessary
to bring the memory back is to touch it.



Isn't the point of deflate to free up host memory, for use by other guests or
whatever?


If I remember correctly, deflate says to make the balloon smaller (that 
is, the balloon gets out of the way so that the guest can use more 
memory); inflate says to make the balloon bigger (that is, the guest has 
less memory available to use because the inflated balloon is occupying 
that memory instead - where memory occupied by the balloon is really 
memory handed back to the host).




If you do nothing upon deflate, then that doesn't actually happen.  It seems to
me that this is backward and you should use DONTNEED on deflate and then
inflate should do nothing.


Or rather, it sounds like your definition of deflate is opposite the one 
I recall (you are trying to argue that deflate means the guest uses less 
memory and is therefore deflating in size; while I thought deflate meant 
that the balloon shrinks in size making more memory available to the guest).


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



Re: [Qemu-devel] [PATCH v2 8/8] iscsi: Support auto-read-only option

2018-10-12 Thread Eric Blake

On 10/12/18 6:55 AM, Kevin Wolf wrote:

If read-only=off, but auto-read-only=on is given, open the volume
read-write if we have the permissions, but instead of erroring out for
read-only volumes, just degrade to read-only.

Signed-off-by: Kevin Wolf 
---
  block/iscsi.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)



Reviewed-by: Eric Blake 

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



[Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false

2018-10-12 Thread Bastian Koppelmann
return false in trans_* instructions is no longer used as a fallback to
the old decoder. We can therefore now use 'return false' to indicate an illegal
instruction.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 .../riscv/insn_trans/trans_privileged.inc.c   |  6 ++
 target/riscv/insn_trans/trans_rvc.inc.c   | 21 +++
 target/riscv/insn_trans/trans_rvd.inc.c   | 14 ++---
 target/riscv/insn_trans/trans_rvf.inc.c   | 10 -
 target/riscv/insn_trans/trans_rvi.inc.c   | 18 ++--
 target/riscv/translate.c  |  1 +
 6 files changed, 28 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
index 9534adb025..f378c3852e 100644
--- a/target/riscv/insn_trans/trans_privileged.inc.c
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -37,8 +37,7 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a, 
uint32_t insn)
 
 static bool trans_uret(DisasContext *ctx, arg_uret *a, uint32_t insn)
 {
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 
 static bool trans_sret(DisasContext *ctx, arg_sret *a, uint32_t insn)
@@ -61,8 +60,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a, 
uint32_t insn)
 
 static bool trans_hret(DisasContext *ctx, arg_hret *a, uint32_t insn)
 {
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 
 static bool trans_mret(DisasContext *ctx, arg_mret *a, uint32_t insn)
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index b98c18d99e..43e9e6e1ac 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -23,8 +23,7 @@ static bool trans_c_addi4spn(DisasContext *ctx, 
arg_c_addi4spn *a,
 {
 if (a->nzuimm == 0) {
 /* Reserved in ISA */
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 arg_addi arg = { .rd = a->rd, .rs1 = 2, .imm = a->nzuimm };
 return trans_addi(ctx, , insn);
@@ -144,14 +143,12 @@ static bool trans_c_srli(DisasContext *ctx, arg_c_srli 
*a, uint16_t insn)
 {
 if (a->shamt == 0) {
 /* Reserved in ISA */
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 #ifdef TARGET_RISCV32
 /* Ensure, that shamt[5] is zero for RV32 */
 if (a->shamt >= 32) {
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 #endif
 
@@ -163,14 +160,12 @@ static bool trans_c_srai(DisasContext *ctx, arg_c_srai 
*a, uint16_t insn)
 {
 if (a->shamt == 0) {
 /* Reserved in ISA */
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 #ifdef TARGET_RISCV32
 /* Ensure, that shamt[5] is zero for RV32 */
 if (a->shamt >= 32) {
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 #endif
 
@@ -242,15 +237,13 @@ static bool trans_c_slli(DisasContext *ctx, arg_c_slli 
*a, uint16_t insn)
 {
 if (a->shamt == 0) {
 /* Reserved in ISA */
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 
 #ifdef TARGET_RISCV32
 /* Ensure, that shamt[5] is zero for RV32 */
 if (a->shamt >= 32) {
-gen_exception_illegal(ctx);
-return true;
+return false;
 }
 #endif
 
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
index 076d2147c3..8593b20233 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -253,7 +253,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d 
*a, uint32_t insn)
 gen_set_gpr(a->rd, t0);
 tcg_temp_free(t0);
 #else
-gen_exception_illegal(ctx);
+return false;
 #endif
 return true;
 }
@@ -323,7 +323,7 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d 
*a, uint32_t insn)
 gen_set_gpr(a->rd, t0);
 tcg_temp_free(t0);
 #else
-gen_exception_illegal(ctx);
+return false;
 #endif
 return true;
 }
@@ -339,7 +339,7 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, 
arg_fcvt_lu_d *a, uint32_t insn)
 gen_set_gpr(a->rd, t0);
 tcg_temp_free(t0);
 #else
-gen_exception_illegal(ctx);
+return false;
 #endif
 return true;
 }
@@ -351,7 +351,7 @@ static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d 
*a, uint32_t insn)
 
 gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
 #else
-gen_exception_illegal(ctx);
+return false;
 #endif
 return true;
 }
@@ -368,7 +368,7 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l 
*a, uint32_t insn)
 gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
 tcg_temp_free(t0);
 #else
-gen_exception_illegal(ctx);
+return false;
 #endif
 return true;
 }
@@ -385,7 +385,7 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, 
arg_fcvt_d_lu *a, uint32_t insn)
 

[Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvm.inc.c |  55 ++---
 target/riscv/translate.c| 266 +++-
 2 files changed, 151 insertions(+), 170 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
index 2d0fd6a64f..6f7187bb8f 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -21,67 +21,74 @@
 
 static bool trans_mul(DisasContext *ctx, arg_mul *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_mul_tl);
 }
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_muls2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _mulhsu);
 }
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_mulu2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _div);
 }
 static bool trans_divu(DisasContext *ctx, arg_divu *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _divu);
 }
 static bool trans_rem(DisasContext *ctx, arg_rem *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _rem);
 }
 static bool trans_remu(DisasContext *ctx, arg_remu *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _remu);
 }
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_mul_tl);
 }
 static bool trans_divw(DisasContext *ctx, arg_divw *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith_w(ctx, a, _div);
 }
 static bool trans_divuw(DisasContext *ctx, arg_divuw *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith_w(ctx, a, _divu);
 }
 static bool trans_remw(DisasContext *ctx, arg_remw *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith_w(ctx, a, _rem);
 }
 static bool trans_remuw(DisasContext *ctx, arg_remuw *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith_w(ctx, a, _remu);
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 047f64c6f2..5e24ec49a0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -165,156 +165,110 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-int rs2)
+static void gen_div(TCGv ret, TCGv source1, TCGv source2)
 {
-TCGv source1, source2, cond1, cond2, zeroreg, resultopt1;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
+TCGv cond1, cond2, zeroreg, resultopt1;
+/* Handle by altering args to tcg_gen_div to produce req'd results:
+ * For overflow: want source1 in source1 and 1 in source2
+ * For div by zero: want -1 in source1 and 1 in source2 -> -1 result */
+cond1 = tcg_temp_new();
+cond2 = tcg_temp_new();
+zeroreg = tcg_const_tl(0);
+resultopt1 = tcg_temp_new();
+
+tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
+tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)(~0L));
+tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
+((target_ulong)1) << (TARGET_LONG_BITS - 1));
+tcg_gen_and_tl(cond1, cond1, cond2); /* cond1 = overflow */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, 0); /* cond2 = div 0 */
+/* if div by zero, set source1 to -1, 

[Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists

2018-10-12 Thread Bastian Koppelmann
manual decoding in gen_arith() is not necessary with decodetree.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  3 ++-
 target/riscv/insn_trans/trans_rvi.inc.c | 21 ++--
 target/riscv/translate.c| 33 ++---
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 806315b830..549cacfdd5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -40,6 +40,7 @@
 # Argument sets:
 imm rs2 rs1
 _imm imm rs1 rd
+ rd rs1 rs2
  shamt rs1 rd
 aq rl rs2 rs1 rd
 
@@ -48,7 +49,7 @@
 @sfence_vma ... . .   ... . ... %rs2 %rs1
 @sfence_vm  ... . .   ... . ... %rs1
 
-@r   ...   . . ... . ...   %rs2 %rs1 
%rd
+@r   ...   . . ... . ... %rs2 %rs1 
%rd
 @i   . ... . ... _imm imm=%imm_i  %rs1 
%rd
 @b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 76d4baab69..cb0c6263bd 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -323,14 +323,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a, 
uint32_t insn)
 
 static bool trans_add(DisasContext *ctx, arg_add *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a, uint32_t insn)
@@ -353,8 +351,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a, 
uint32_t insn)
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a, uint32_t insn)
@@ -371,14 +368,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a, 
uint32_t insn)
 
 static bool trans_or(DisasContext *ctx, arg_or *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_and_tl);
 }
 
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a, uint32_t insn)
@@ -436,8 +431,7 @@ static bool trans_addw(DisasContext *ctx, arg_addw *a, 
uint32_t insn)
 gen_exception_illegal(ctx);
 return true;
 #endif
-gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_add_tl);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
@@ -446,8 +440,7 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a, 
uint32_t insn)
 gen_exception_illegal(ctx);
 return true;
 #endif
-gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, _gen_sub_tl);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ed1d93af47..92aa4641b0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -175,12 +175,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 gen_get_gpr(source2, rs2);
 
 switch (opc) {
-CASE_OP_32_64(OPC_RISC_ADD):
-tcg_gen_add_tl(source1, source1, source2);
-break;
-CASE_OP_32_64(OPC_RISC_SUB):
-tcg_gen_sub_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SLLW:
 tcg_gen_andi_tl(source2, source2, 0x1F);
@@ -197,9 +191,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 case OPC_RISC_SLTU:
 tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
 break;
-case OPC_RISC_XOR:
-tcg_gen_xor_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SRLW:
 /* clear upper 32 */
@@ -225,12 +216,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
 tcg_gen_sar_tl(source1, source1, source2);
 break;
-case OPC_RISC_OR:
-tcg_gen_or_tl(source1, source1, source2);
-break;
-case OPC_RISC_AND:
-tcg_gen_and_tl(source1, source1, source2);

[Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G()

2018-10-12 Thread Bastian Koppelmann
decodetree handles all instructions now so the fallback is not necessary
anymore.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/translate.c | 23 ---
 1 file changed, 23 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 86ca885c7e..8ef943f6c8 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -412,27 +412,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 #include "decode_insn16.inc.c"
 #include "insn_trans/trans_rvc.inc.c"
 
-static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
-{
-int rs1, rd;
-uint32_t op;
-
-/* We do not do misaligned address check here: the address should never be
- * misaligned at this point. Instructions that set PC must do the check,
- * since epc must be the address of the instruction that caused us to
- * perform the misaligned instruction fetch */
-
-op = MASK_OP_MAJOR(ctx->opcode);
-rs1 = GET_RS1(ctx->opcode);
-rd = GET_RD(ctx->opcode);
-
-switch (op) {
-default:
-gen_exception_illegal(ctx);
-break;
-}
-}
-
 static void decode_opc(CPURISCVState *env, DisasContext *ctx)
 {
 /* check for compressed insn */
@@ -448,8 +427,6 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx)
 } else {
 ctx->pc_succ_insn = ctx->base.pc_next + 4;
 if (!decode_insn32(ctx, ctx->opcode)) {
-/* fallback to old decoder */
-decode_RV32_64G(env, ctx);
 }
 }
 }
-- 
2.19.1




[Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store()

2018-10-12 Thread Bastian Koppelmann
With decodetree we don't need to convert RISC-V opcodes into to MemOps
as gen_store() did.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 31 --
 target/riscv/translate.c| 34 -
 2 files changed, 23 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 873a5e8b53..b09c52a708 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -192,27 +192,42 @@ static bool trans_ld(DisasContext *ctx, arg_ld *a, 
uint32_t insn)
 #endif
 }
 
-static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+static bool trans_store(DisasContext *ctx, arg_sb *a, int memop)
 {
-gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+gen_get_gpr(dat, a->rs2);
+
+if (memop < 0) {
+return false;
+}
+
+tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
+tcg_temp_free(t0);
+tcg_temp_free(dat);
 return true;
 }
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+{
+return trans_store(ctx, a, MO_SB);
+}
 static bool trans_sh(DisasContext *ctx, arg_sh *a, uint32_t insn)
 {
-gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
-return true;
+return trans_store(ctx, a, MO_TESW);
 }
+
 static bool trans_sw(DisasContext *ctx, arg_sw *a, uint32_t insn)
 {
-gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
-return true;
+return trans_store(ctx, a, MO_TESL);
 }
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
-return true;
+return trans_store(ctx, a, MO_TEQ);
 #else
 return false;
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 544e71a46c..feae31cb94 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -54,20 +54,6 @@ typedef struct DisasContext {
 int frm;
 } DisasContext;
 
-/* convert riscv funct3 to qemu memop for load/store */
-static const int tcg_memop_lookup[8] = {
-[0 ... 7] = -1,
-[0] = MO_SB,
-[1] = MO_TESW,
-[2] = MO_TESL,
-[4] = MO_UB,
-[5] = MO_TEUW,
-#ifdef TARGET_RISCV64
-[3] = MO_TEQ,
-[6] = MO_TEUL,
-#endif
-};
-
 #ifdef TARGET_RISCV64
 #define CASE_OP_32_64(X) case X: case glue(X, W)
 #else
@@ -488,26 +474,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
-target_long imm)
-{
-TCGv t0 = tcg_temp_new();
-TCGv dat = tcg_temp_new();
-gen_get_gpr(t0, rs1);
-tcg_gen_addi_tl(t0, t0, imm);
-gen_get_gpr(dat, rs2);
-int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
-
-if (memop < 0) {
-gen_exception_illegal(ctx);
-return;
-}
-
-tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
-tcg_temp_free(t0);
-tcg_temp_free(dat);
-}
-
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
 TCGv_i32 t0;
-- 
2.19.1




[Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system()

2018-10-12 Thread Bastian Koppelmann
with all 16 bit insns moved to decodetree no path is falling back to
gen_system(), so we can remove it.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/translate.c | 32 
 1 file changed, 32 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 5e24ec49a0..86ca885c7e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -305,34 +305,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 tcg_temp_free_i32(t0);
 }
 
-
-static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int csr)
-{
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
-switch (opc) {
-case OPC_RISC_ECALL:
-switch (csr) {
-case 0x0: /* ECALL */
-/* always generates U-level ECALL, fixed in do_interrupt handler */
-generate_exception(ctx, RISCV_EXCP_U_ECALL);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-case 0x1: /* EBREAK */
-generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-default:
-gen_exception_illegal(ctx);
-break;
-}
-break;
-}
-}
-
 #define EX_SH(amount) \
 static int64_t ex_shift_##amount(int imm) \
 { \
@@ -455,10 +427,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 rd = GET_RD(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_SYSTEM:
-gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
-   (ctx->opcode & 0xFFF0) >> 20);
-break;
 default:
 gen_exception_illegal(ctx);
 break;
-- 
2.19.1




Re: [Qemu-devel] [PATCH v2 06/12] net: cadence_gem: Add support for selecting the DMA MemoryRegion

2018-10-12 Thread Alistair Francis
On Wed, Oct 10, 2018 at 7:27 PM Edgar E. Iglesias
 wrote:
>
> From: "Edgar E. Iglesias" 
>
> Add support for selecting the Memory Region that the GEM
> will do DMA to.
>
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/net/cadence_gem.c | 59 ++--
>  include/hw/net/cadence_gem.h |  2 ++
>  2 files changed, 39 insertions(+), 22 deletions(-)
>
> diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
> index 759c1d71e0..a40f136285 100644
> --- a/hw/net/cadence_gem.c
> +++ b/hw/net/cadence_gem.c
> @@ -28,6 +28,7 @@
>  #include "hw/net/cadence_gem.h"
>  #include "qapi/error.h"
>  #include "qemu/log.h"
> +#include "sysemu/dma.h"
>  #include "net/checksum.h"
>
>  #ifdef CADENCE_GEM_ERR_DEBUG
> @@ -835,9 +836,9 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
>  {
>  DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
>  /* read current descriptor */
> -cpu_physical_memory_read(s->rx_desc_addr[q],
> - (uint8_t *)s->rx_desc[q],
> - sizeof(uint32_t) * gem_get_desc_len(s, true));
> +address_space_read(>dma_as, s->rx_desc_addr[q], 
> MEMTXATTRS_UNSPECIFIED,
> +   (uint8_t *)s->rx_desc[q],
> +   sizeof(uint32_t) * gem_get_desc_len(s, true));
>
>  /* Descriptor owned by software ? */
>  if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
> @@ -956,10 +957,10 @@ static ssize_t gem_receive(NetClientState *nc, const 
> uint8_t *buf, size_t size)
>  rx_desc_get_buffer(s->rx_desc[q]));
>
>  /* Copy packet data to emulated DMA buffer */
> -cpu_physical_memory_write(rx_desc_get_buffer(s, s->rx_desc[q]) +
> +address_space_write(>dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) 
> +
>
> rxbuf_offset,
> -  rxbuf_ptr,
> -  MIN(bytes_to_copy, rxbufsize));
> +MEMTXATTRS_UNSPECIFIED, rxbuf_ptr,
> +MIN(bytes_to_copy, rxbufsize));
>  rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
>  bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
>
> @@ -993,9 +994,10 @@ static ssize_t gem_receive(NetClientState *nc, const 
> uint8_t *buf, size_t size)
>  }
>
>  /* Descriptor write-back.  */
> -cpu_physical_memory_write(s->rx_desc_addr[q],
> -  (uint8_t *)s->rx_desc[q],
> -  sizeof(uint32_t) * gem_get_desc_len(s, 
> true));
> +address_space_write(>dma_as, s->rx_desc_addr[q],
> +MEMTXATTRS_UNSPECIFIED,
> +(uint8_t *)s->rx_desc[q],
> +sizeof(uint32_t) * gem_get_desc_len(s, true));
>
>  /* Next descriptor */
>  if (rx_desc_get_wrap(s->rx_desc[q])) {
> @@ -1099,9 +1101,9 @@ static void gem_transmit(CadenceGEMState *s)
>  packet_desc_addr = s->tx_desc_addr[q];
>
>  DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
> -cpu_physical_memory_read(packet_desc_addr,
> - (uint8_t *)desc,
> - sizeof(uint32_t) * gem_get_desc_len(s, 
> false));
> +address_space_read(>dma_as, packet_desc_addr,
> +   MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
> +   sizeof(uint32_t) * gem_get_desc_len(s, false));
>  /* Handle all descriptors owned by hardware */
>  while (tx_desc_get_used(desc) == 0) {
>
> @@ -1133,8 +1135,9 @@ static void gem_transmit(CadenceGEMState *s)
>  /* Gather this fragment of the packet from "dma memory" to our
>   * contig buffer.
>   */
> -cpu_physical_memory_read(tx_desc_get_buffer(s, desc), p,
> - tx_desc_get_length(desc));
> +address_space_read(>dma_as, tx_desc_get_buffer(s, desc),
> +   MEMTXATTRS_UNSPECIFIED,
> +   p, tx_desc_get_length(desc));
>  p += tx_desc_get_length(desc);
>  total_bytes += tx_desc_get_length(desc);
>
> @@ -1145,13 +1148,15 @@ static void gem_transmit(CadenceGEMState *s)
>  /* Modify the 1st descriptor of this packet to be owned by
>   * the processor.
>   */
> -cpu_physical_memory_read(s->tx_desc_addr[q],
> - (uint8_t *)desc_first,
> - sizeof(desc_first));
> +address_space_read(>dma_as, s->tx_desc_addr[q],
> +   MEMTXATTRS_UNSPECIFIED,
> +   (uint8_t *)desc_first,
> +   sizeof(desc_first));
> 

Re: [Qemu-devel] [RFC 1/5] virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate

2018-10-12 Thread Richard Henderson
On 10/11/18 8:24 PM, David Gibson wrote:
> When the balloon is inflated, we discard memory place in it using madvise()
> with MADV_DONTNEED.  And when we deflate it we use MADV_WILLNEED, which
> sounds like it makes sense but is actually unnecessary.
> 
> The misleadingly named MADV_DONTNEED just discards the memory in question,
> it doesn't set any persistent state on it in-kernel; all that's necessary
> to bring the memory back is to touch it.


Isn't the point of deflate to free up host memory, for use by other guests or
whatever?

If you do nothing upon deflate, then that doesn't actually happen.  It seems to
me that this is backward and you should use DONTNEED on deflate and then
inflate should do nothing.


r~



[Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/Makefile.objs  |  9 ++-
 target/riscv/insn16.decode  | 55 +++
 target/riscv/insn_trans/trans_rvc.inc.c | 89 +
 target/riscv/translate.c| 88 +---
 4 files changed, 168 insertions(+), 73 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ea02f9b9ef..ec7326f1c7 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -8,4 +8,11 @@ target/riscv/decode_insn32.inc.c: \
  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
  "GEN", $(TARGET_DIR)$@)
 
-target/riscv/translate.o: target/riscv/decode_insn32.inc.c
+target/riscv/decode_insn16.inc.c: \
+  $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn16 --insnwidth 16 
$<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c \
+   target/riscv/decode_insn16.inc.c
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
new file mode 100644
index 00..558c0c41f0
--- /dev/null
+++ b/target/riscv/insn16.decode
@@ -0,0 +1,55 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see .
+
+# Fields:
+%rd7:5
+%rs1_3 7:3!function=ex_rvc_register
+%rs2_3 2:3!function=ex_rvc_register
+
+# Immediates:
+%nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
+%uimm_cl_d 5:2 10:3   !function=ex_shift_3
+%uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
+
+
+# Argument sets:
+   rs1 rd
+_dw uimm   rs1 rd
+   nzuimm rd
+   rs1 rs2
+_dw uimm   rs1 rs2
+
+
+# Formats 16:
+@ciw   ...    ... .. nzuimm=%nzuimm_ciw   rd=%rs2_3
+@cl_d  ... ... ... .. ... .. _dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
+@cl_w  ... ... ... .. ... .. _dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
+@cl... ... ... .. ... ..   rs1=%rs1_3  rd=%rs2_3
+@cs... ... ... .. ... ..   rs1=%rs1_3  
rs2=%rs2_3
+@cs_d  ... ... ... .. ... .. _dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
+@cs_w  ... ... ... .. ... .. _dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
+
+
+# *** RV64C Standard Extension (Quadrant 0) ***
+c_addi4spn000 ... 00 @ciw
+c_fld 001  ... ... .. ... 00 @cl_d
+c_lw  010  ... ... .. ... 00 @cl_w
+c_flw_ld  011  --- ... -- ... 00 @cl#Note: Must parse uimm manually
+c_fsd 101  ... ... .. ... 00 @cs_d
+c_sw  110  ... ... .. ... 00 @cs_w
+c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must parse uimm manually
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
new file mode 100644
index 00..f8ad2db527
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -0,0 +1,89 @@
+/*
+ * RISC-V translation routines for the RVC Compressed Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a,
+uint16_t insn)
+{
+if (a->nzuimm == 0) {
+/* Reserved 

[Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions

2018-10-12 Thread Bastian Koppelmann
gen_arith_imm() does a lot of decoding manually, which was hard to read in
case of the shift instructions and is not necessary anymore with decodetree.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  3 +-
 target/riscv/insn_trans/trans_rvi.inc.c | 52 +
 target/riscv/translate.c| 99 +
 3 files changed, 60 insertions(+), 94 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7c71f8338b..806315b830 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -39,6 +39,7 @@
 
 # Argument sets:
 imm rs2 rs1
+_imm imm rs1 rd
  shamt rs1 rd
 aq rl rs2 rs1 rd
 
@@ -48,7 +49,7 @@
 @sfence_vm  ... . .   ... . ... %rs1
 
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
-@i   . ... . ... imm=%imm_i %rs1 
%rd
+@i   . ... . ... _imm imm=%imm_i  %rs1 
%rd
 @b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index b09c52a708..76d4baab69 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -235,37 +235,50 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a, 
uint32_t insn)
 
 static bool trans_addi(DisasContext *ctx, arg_addi *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
-return true;
+return trans_arith_imm(ctx, a, _gen_add_tl);
 }
 
 static bool trans_slti(DisasContext *ctx, arg_slti *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
-return true;
+return trans_arith_imm(ctx, a, _gen_xor_tl);
 }
+
 static bool trans_ori(DisasContext *ctx, arg_ori *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
-return true;
+return trans_arith_imm(ctx, a, _gen_or_tl);
 }
+
 static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
-return true;
+return trans_arith_imm(ctx, a, _gen_and_tl);
 }
+
 static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
 {
 if (a->rd != 0) {
@@ -370,13 +383,26 @@ static bool trans_and(DisasContext *ctx, arg_and *a, 
uint32_t insn)
 
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
-return true;
+#ifdef TARGET_RISCV64
+bool res = trans_arith_imm(ctx, a, _gen_add_tl);
+tcg_gen_ext32s_tl(cpu_gpr[a->rd], cpu_gpr[a->rd]);
+return res;
+#else
+return false;
+#endif
 }
 
 static bool trans_slliw(DisasContext *ctx, arg_slliw *a, uint32_t insn)
 {
-gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_shli_tl(source1, source1, a->shamt);
+tcg_gen_ext32s_tl(source1, source1);
+gen_set_gpr(a->rd, source1);
+
+tcg_temp_free(source1);
 return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index feae31cb94..ed1d93af47 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -373,86 +373,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(source2);
 }
 
-static void gen_arith_imm(DisasContext *ctx, uint32_t opc, int rd,
-int rs1, target_long imm)
-{
-TCGv source1 = tcg_temp_new();
-int shift_len = TARGET_LONG_BITS;
-int shift_a;
-
-gen_get_gpr(source1, rs1);
-
-switch (opc) {
-case OPC_RISC_ADDI:
-#if defined(TARGET_RISCV64)
-case OPC_RISC_ADDIW:
-#endif
-tcg_gen_addi_tl(source1, source1, imm);
-break;
-case OPC_RISC_SLTI:
-tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, imm);
-break;
-case OPC_RISC_SLTIU:
-

[Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  13 +++
 target/riscv/insn_trans/trans_rva.inc.c |  99 +
 target/riscv/translate.c| 140 
 3 files changed, 112 insertions(+), 140 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 31fca2f184..b4a86f5402 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -148,3 +148,16 @@ amomin_w   1 . . . . 010 . 010 @atom_st
 amomax_w   10100 . . . . 010 . 010 @atom_st
 amominu_w  11000 . . . . 010 . 010 @atom_st
 amomaxu_w  11100 . . . . 010 . 010 @atom_st
+
+# *** RV64A Standard Extension (in addition to RV32A) ***
+lr_d   00010 . . 0 . 011 . 010 @atom_ld
+sc_d   00011 . . . . 011 . 010 @atom_st
+amoswap_d  1 . . . . 011 . 010 @atom_st
+amoadd_d   0 . . . . 011 . 010 @atom_st
+amoxor_d   00100 . . . . 011 . 010 @atom_st
+amoand_d   01100 . . . . 011 . 010 @atom_st
+amoor_d01000 . . . . 011 . 010 @atom_st
+amomin_d   1 . . . . 011 . 010 @atom_st
+amomax_d   10100 . . . . 011 . 010 @atom_st
+amominu_d  11000 . . . . 011 . 010 @atom_st
+amomaxu_d  11100 . . . . 011 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
index 2cb2bfd9cc..06616982c6 100644
--- a/target/riscv/insn_trans/trans_rva.inc.c
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -173,3 +173,102 @@ static bool trans_amomaxu_w(DisasContext *ctx, 
arg_amomaxu_w *a, uint32_t insn)
 {
 return gen_amo(ctx, a, OPC_RISC_AMOMAXU, (MO_ALIGN | MO_TESL));
 }
+
+static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
+#else
+return false;
+#endif
+}
+
+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOSWAP, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOADD, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOXOR, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOAND, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOOR, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOMIN, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOMAX, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOMINU, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
+
+static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+return gen_amo(ctx, a, OPC_RISC_AMOMAXU, (MO_ALIGN | MO_TEQ));
+#else
+return false;
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 760ed88162..1f6d58cb7e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -710,143 +710,6 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, 
int rs1,
 tcg_temp_free(t0);
 }
 
-static void gen_atomic(DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int rs2)
-{
-TCGv src1, src2, dat;
-TCGLabel *l1, *l2;
-TCGMemOp mop;
-bool aq, rl;
-
-/* Extract the size of the atomic operation.  */
-switch (extract32(opc, 12, 3)) {
-case 2: /* 32-bit */
-mop = MO_ALIGN | MO_TESL;
-break;
-#if defined(TARGET_RISCV64)
-case 3: /* 64-bit */
-mop = MO_ALIGN | MO_TEQ;
-break;
-#endif
-default:
-gen_exception_illegal(ctx);
-return;
-}
-rl = 

[Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load()

2018-10-12 Thread Bastian Koppelmann
With decodetree we don't need to convert RISC-V opcodes into to MemOps
as gen_load() did.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 44 +
 target/riscv/translate.c| 20 ---
 2 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 6097b82df4..873a5e8b53 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -131,46 +131,62 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, 
uint32_t insn)
 return trans_branch(ctx, a, TCG_COND_GEU);
 }
 
-static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+static bool trans_load(DisasContext *ctx, arg_lb *a, int memop)
 {
-gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+if (memop < 0) {
+return false;
+}
+
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
+gen_set_gpr(a->rd, t1);
+tcg_temp_free(t0);
+tcg_temp_free(t1);
 return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+{
+return trans_load(ctx, a, MO_SB);
+}
+
 static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)
 {
-gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_TESW);
 }
+
 static bool trans_lw(DisasContext *ctx, arg_lw *a, uint32_t insn)
 {
-gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_TESL);
 }
+
 static bool trans_lbu(DisasContext *ctx, arg_lbu *a, uint32_t insn)
 {
-gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_UB);
 }
+
 static bool trans_lhu(DisasContext *ctx, arg_lhu *a, uint32_t insn)
 {
-gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_TEUW);
 }
 
 static bool trans_lwu(DisasContext *ctx, arg_lwu *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_TEUL);
 #else
 return false;
 #endif
 }
+
 static bool trans_ld(DisasContext *ctx, arg_ld *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
-return true;
+return trans_load(ctx, a, MO_TEQ);
 #else
 return false;
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b8a9b1c64b..544e71a46c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,26 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-target_long imm)
-{
-TCGv t0 = tcg_temp_new();
-TCGv t1 = tcg_temp_new();
-gen_get_gpr(t0, rs1);
-tcg_gen_addi_tl(t0, t0, imm);
-int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
-
-if (memop < 0) {
-gen_exception_illegal(ctx);
-return;
-}
-
-tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
-gen_set_gpr(rd, t1);
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-}
-
 static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
 target_long imm)
 {
-- 
2.19.1




[Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 of RVXC insns to decodetree

2018-10-12 Thread Bastian Koppelmann
This also removes all functions that now became obsolete.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn16.decode  |  34 +-
 target/riscv/insn_trans/trans_rvc.inc.c | 107 +
 target/riscv/translate.c| 151 +---
 3 files changed, 139 insertions(+), 153 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 29dade0fa1..138290c450 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -20,6 +20,7 @@
 %rd7:5
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
+%rs2_5 2:5
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -30,12 +31,14 @@
 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
 
 %nzuimm_6bit   12:1 2:5
+%uimm_6bit_ld 2:3 12:1 5:2   !function=ex_shift_3
+%uimm_6bit_lw 2:2 12:1 4:3   !function=ex_shift_2
+%uimm_6bit_sd 7:3 10:3   !function=ex_shift_3
+%uimm_6bit_sw 7:2 9:4!function=ex_shift_2
 
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
 
-
-
 # Argument sets:
rs1 rd
 _dw uimm   rs1 rd
@@ -47,11 +50,15 @@
rd  rs2
 _j   imm
 _shift   shamt  rd
-
+_ld  uimm  rd
+_sd  uimm  rs2
 
 _addi16sp_lui  imm_lui imm_addi16sp rd
+_flwsp_ldspuimm_flwsp uimm_ldsp rd
+_fswsp_sdspuimm_fswsp uimm_sdsp rs2
 
 # Formats 16:
+@cr  . .  ..   rs2=%rs2_5  %rd
 @ci... . . .  ..  imm=%imm_ci  %rd
 @ciw   ...    ... .. nzuimm=%nzuimm_ciw   rd=%rs2_3
 @cl_d  ... ... ... .. ... .. _dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
@@ -64,9 +71,19 @@
 @cb... ... ... .. ... ..  imm=%imm_cb  rs1=%rs1_3
 @cj...... .. _jimm=%imm_cj
 
+@c_ld  ... . .  . .. _ld uimm=%uimm_6bit_ld  %rd
+@c_lw  ... . .  . .. _ld uimm=%uimm_6bit_lw  %rd
+@c_sd  ... . .  . .. _sd uimm=%uimm_6bit_sd  rs2=%rs2_5
+@c_sw  ... . .  . .. _sd uimm=%uimm_6bit_sw  rs2=%rs2_5
+
 @c_addi16sp_lui ... .  . . .. _addi16sp_lui %imm_lui %imm_addi16sp 
%rd
+@c_flwsp_ldsp   ... .  . . .. _flwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
+uimm_ldsp=%uimm_6bit_ld %rd
+@c_fswsp_sdsp   ... .  . . .. _fswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
+uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
 
 @c_shift... . .. ... . .. _shift rd=%rs1_3 shamt=%nzuimm_6bit
+@c_shift2   ... . .. ... . .. _shift rd=%rdshamt=%nzuimm_6bit
 
 @c_andi ... . .. ... . ..  imm=%imm_ci rd=%rs1_3
 
@@ -96,3 +113,14 @@ c_addw100 1 11 ... 01 ... 01 @cs_2
 c_j   101 ... 01 @cj
 c_beqz110  ... ...  . 01 @cb
 c_bnez111  ... ...  . 01 @cb
+
+# *** RV64C Standard Extension (Quadrant 2) ***
+c_slli000 .  .  . 10 @c_shift2
+c_fldsp   001 .  .  . 10 @c_ld
+c_lwsp010 .  .  . 10 @c_lw
+c_flwsp_ldsp  011 .  .  . 10 @c_flwsp_ldsp 
#C.LDSP:RV64;C.FLWSP:RV32
+c_jr_mv   100 0  .  . 10 @cr
+c_ebreak_jalr_add 100 1  .  . 10 @cr
+c_fsdsp   101   ..  . 10 @c_sd
+c_swsp110 .  .  . 10 @c_sw
+c_fswsp_sdsp  111 .  .  . 10 @c_fswsp_sdsp 
#C.SDSP:RV64;C.FSWSP:RV32
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index 74cb4dad0a..b98c18d99e 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -237,3 +237,110 @@ static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez 
*a, uint16_t insn)
 arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
 return trans_bne(ctx, , insn);
 }
+
+static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a, uint16_t insn)
+{
+if (a->shamt == 0) {
+/* Reserved in ISA */
+gen_exception_illegal(ctx);
+return true;
+}
+
+#ifdef TARGET_RISCV32
+/* Ensure, that shamt[5] is zero for RV32 */
+if (a->shamt >= 32) {
+gen_exception_illegal(ctx);
+return true;
+}
+#endif
+
+arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+return trans_slli(ctx, , insn);
+}
+
+static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a, uint16_t insn)
+{
+arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_fld(ctx, , insn);
+}
+
+static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a, uint16_t insn)
+{
+arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_lw(ctx, , insn);
+}
+
+static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a,
+uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+/* C.FLWSP */
+arg_flw 

Re: [Qemu-devel] [PATCH v2 7/8] gluster: Support auto-read-only option

2018-10-12 Thread Eric Blake

On 10/12/18 6:55 AM, Kevin Wolf wrote:

If read-only=off, but auto-read-only=on is given, open the file
read-write if we have the permissions, but instead of erroring out for
read-only files, just degrade to read-only.

Signed-off-by: Kevin Wolf 
---
  block/gluster.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/block/gluster.c b/block/gluster.c
index 4fd55a9cc5..68d20c8830 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -849,6 +849,15 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict 
*options,
  qemu_gluster_parse_flags(bdrv_flags, _flags);
  
  s->fd = glfs_open(s->glfs, gconf->path, open_flags);

+if (!s->fd && errno == EACCES) {


EROFS is not possible as it was for posix file?


+/* Try to degrade to read-only, but if it doesn't work, still use the
+ * normal error message. */
+ret = bdrv_apply_auto_read_only(bs, NULL, NULL);


No guarantees on what errno is on failure...


+if (ret == 0) {
+open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
+s->fd = glfs_open(s->glfs, gconf->path, open_flags);
+}
+}
  if (!s->fd) {
  ret = -errno;


...but you are relying on it here.  (Same story as in the posix driver)

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



[Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  35 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 326 
 target/riscv/translate.c|   1 +
 3 files changed, 362 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b4a86f5402..b6807ef8dd 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,6 +17,7 @@
 # this program.  If not, see .
 
 # Fields:
+%rs3   27:5
 %rs2   20:5
 %rs1   15:5
 %rd7:5
@@ -24,6 +25,7 @@
 %sh620:6
 %sh520:5
 %csr20:12
+%rm 12:3
 
 %pred   24:4
 %succ   20:4
@@ -58,6 +60,11 @@
 @atom_ld . aq:1 rl:1 .  . ...  rs2=0 %rs1 
%rd
 @atom_st . aq:1 rl:1 .  . ...  %rs2  %rs1 
%rd
 
+@r4_rm   . ..  . . ... . ... %rs3 %rs2 %rs1 %rm %rd
+@r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
+@r2_rm   ...   . . ... . ... %rs1 %rm %rd
+@r2  ...   . . ... . ... %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -161,3 +168,31 @@ amomin_d   1 . . . . 011 . 010 @atom_st
 amomax_d   10100 . . . . 011 . 010 @atom_st
 amominu_d  11000 . . . . 011 . 010 @atom_st
 amomaxu_d  11100 . . . . 011 . 010 @atom_st
+
+# *** RV32F Standard Extension ***
+flw   . 010 . 111 @i
+fsw...  . . 010 . 0100111 @s
+fmadd_s. 00 . . ... . 111 @r4_rm
+fmsub_s. 00 . . ... . 1000111 @r4_rm
+fnmsub_s   . 00 . . ... . 1001011 @r4_rm
+fnmadd_s   . 00 . . ... . 100 @r4_rm
+fadd_s 000  . . ... . 1010011 @r_rm
+fsub_s 100  . . ... . 1010011 @r_rm
+fmul_s 0001000  . . ... . 1010011 @r_rm
+fdiv_s 0001100  . . ... . 1010011 @r_rm
+fsqrt_s0101100  0 . ... . 1010011 @r2_rm
+fsgnj_s001  . . 000 . 1010011 @r
+fsgnjn_s   001  . . 001 . 1010011 @r
+fsgnjx_s   001  . . 010 . 1010011 @r
+fmin_s 0010100  . . 000 . 1010011 @r
+fmax_s 0010100  . . 001 . 1010011 @r
+fcvt_w_s   110  0 . ... . 1010011 @r2_rm
+fcvt_wu_s  110  1 . ... . 1010011 @r2_rm
+fmv_x_w111  0 . 000 . 1010011 @r2
+feq_s  101  . . 010 . 1010011 @r
+flt_s  101  . . 001 . 1010011 @r
+fle_s  101  . . 000 . 1010011 @r
+fclass_s   111  0 . 001 . 1010011 @r2
+fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
+fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
+fmv_w_x000  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
new file mode 100644
index 00..e24efc76b4
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -0,0 +1,326 @@
+/*
+ * RISC-V translation routines for the RV64F Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define REQUIRE_FPU \
+if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) \
+gen_exception_illegal(ctx)
+
+static bool trans_flw(DisasContext *ctx, arg_flw *a, uint32_t insn)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
+/* RISC-V requires NaN-boxing of narrower width floating point values */
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xULL);
+
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fsw(DisasContext *ctx, arg_fsw *a, uint32_t insn)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+REQUIRE_FPU;
+tcg_gen_addi_tl(t0, t0, 

[Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  28 +++
 target/riscv/insn_trans/trans_rvd.inc.c | 313 
 target/riscv/translate.c|   1 +
 3 files changed, 342 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a629a717dc..1e4ef4f8cc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -202,3 +202,31 @@ fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
 fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
 fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
 fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
+
+# *** RV32D Standard Extension ***
+fld   . 011 . 111 @i
+fsd... .  . 011 . 0100111 @s
+fmadd_d. 01 . . ... . 111 @r4_rm
+fmsub_d. 01 . . ... . 1000111 @r4_rm
+fnmsub_d   . 01 . . ... . 1001011 @r4_rm
+fnmadd_d   . 01 . . ... . 100 @r4_rm
+fadd_d 001  . . ... . 1010011 @r_rm
+fsub_d 101  . . ... . 1010011 @r_rm
+fmul_d 0001001  . . ... . 1010011 @r_rm
+fdiv_d 0001101  . . ... . 1010011 @r_rm
+fsqrt_d0101101  0 . ... . 1010011 @r2_rm
+fsgnj_d0010001  . . 000 . 1010011 @r
+fsgnjn_d   0010001  . . 001 . 1010011 @r
+fsgnjx_d   0010001  . . 010 . 1010011 @r
+fmin_d 0010101  . . 000 . 1010011 @r
+fmax_d 0010101  . . 001 . 1010011 @r
+fcvt_s_d   010  1 . ... . 1010011 @r2_rm
+fcvt_d_s   011  0 . ... . 1010011 @r2_rm
+feq_d  1010001  . . 010 . 1010011 @r
+flt_d  1010001  . . 001 . 1010011 @r
+fle_d  1010001  . . 000 . 1010011 @r
+fclass_d   1110001  0 . 001 . 1010011 @r2
+fcvt_w_d   111  0 . ... . 1010011 @r2_rm
+fcvt_wu_d  111  1 . ... . 1010011 @r2_rm
+fcvt_d_w   1101001  0 . ... . 1010011 @r2_rm
+fcvt_d_wu  1101001  1 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
new file mode 100644
index 00..7120afa9be
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -0,0 +1,313 @@
+/*
+ * RISC-V translation routines for the RV64D Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_fld(DisasContext *ctx, arg_fld *a, uint32_t insn)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fsd(DisasContext *ctx, arg_fsd *a, uint32_t insn)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a, uint32_t insn)
+{
+gen_set_rm(ctx, a->rm);
+gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+return true;
+}
+
+static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a, uint32_t insn)
+{
+gen_set_rm(ctx, a->rm);
+gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+return true;
+}
+
+static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a, uint32_t insn)
+{
+gen_set_rm(ctx, a->rm);
+gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+return true;
+}
+
+static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a, uint32_t insn)
+{
+gen_set_rm(ctx, a->rm);
+gen_helper_fnmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+

[Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  6 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 70 +
 2 files changed, 76 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b6807ef8dd..a629a717dc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -196,3 +196,9 @@ fclass_s   111  0 . 001 . 1010011 @r2
 fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
 fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
 fmv_w_x000  0 . 000 . 1010011 @r2
+
+# *** RV64F Standard Extension (in addition to RV32F) ***
+fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
+fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
+fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
+fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
index e24efc76b4..d33a0113c2 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -324,3 +324,73 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x 
*a, uint32_t insn)
 
 return true;
 }
+
+static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+
+return true;
+}
+
+static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+
+return true;
+}
+
+static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
-- 
2.19.1




[Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +
 target/riscv/translate.c| 59 ++
 2 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index cb0c6263bd..b84a2e018b 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -333,19 +333,39 @@ static bool trans_sub(DisasContext *ctx, arg_sub *a, 
uint32_t insn)
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
-return true;
+
+return trans_shift(ctx, a, _gen_shl_tl);
 }
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_setcond_tl(TCG_COND_LT, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
@@ -354,16 +374,15 @@ static bool trans_xor(DisasContext *ctx, arg_xor *a, 
uint32_t insn)
 return trans_arith(ctx, a, _gen_xor_tl);
 }
 
+
 static bool trans_srl(DisasContext *ctx, arg_srl *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
-return true;
+return trans_shift(ctx, a, _gen_shr_tl);
 }
 
 static bool trans_sra(DisasContext *ctx, arg_sra *a, uint32_t insn)
 {
-gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
-return true;
+return trans_shift(ctx, a, _gen_sar_tl);
 }
 
 static bool trans_or(DisasContext *ctx, arg_or *a, uint32_t insn)
@@ -449,7 +468,18 @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a, 
uint32_t insn)
 gen_exception_illegal(ctx);
 return true;
 #endif
-gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shl_tl(source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
@@ -459,7 +489,20 @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a, 
uint32_t insn)
 gen_exception_illegal(ctx);
 return true;
 #endif
-gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/* clear upper 32 */
+tcg_gen_ext32u_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shr_tl(source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
@@ -469,7 +512,21 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a, 
uint32_t insn)
 gen_exception_illegal(ctx);
 return true;
 #endif
-gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/* first, trick to get it to act like working on 32 bits (get rid of
+   upper 32, sign extend to fill space) */
+tcg_gen_ext32s_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_sar_tl(source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92aa4641b0..047f64c6f2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -175,47 +175,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 gen_get_gpr(source2, rs2);
 
 switch (opc) {
-#if defined(TARGET_RISCV64)
-case OPC_RISC_SLLW:
-tcg_gen_andi_tl(source2, source2, 0x1F);
-tcg_gen_shl_tl(source1, source1, source2);
-break;
-#endif
-case OPC_RISC_SLL:
-tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-tcg_gen_shl_tl(source1, source1, source2);
-break;
-case OPC_RISC_SLT:
-tcg_gen_setcond_tl(TCG_COND_LT, source1, source1, source2);
-break;
-

[Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |   8 +
 target/riscv/insn_trans/trans_rvd.inc.c |  94 +
 target/riscv/translate.c| 484 +---
 3 files changed, 103 insertions(+), 483 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1e4ef4f8cc..5df550169b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -230,3 +230,11 @@ fcvt_w_d   111  0 . ... . 1010011 @r2_rm
 fcvt_wu_d  111  1 . ... . 1010011 @r2_rm
 fcvt_d_w   1101001  0 . ... . 1010011 @r2_rm
 fcvt_d_wu  1101001  1 . ... . 1010011 @r2_rm
+
+# *** RV64D Standard Extension (in addition to RV32D) ***
+fcvt_l_d   111  00010 . ... . 1010011 @r2_rm
+fcvt_lu_d  111  00011 . ... . 1010011 @r2_rm
+fmv_x_d1110001  0 . 000 . 1010011 @r2
+fcvt_d_l   1101001  00010 . ... . 1010011 @r2_rm
+fcvt_d_lu  1101001  00011 . ... . 1010011 @r2_rm
+fmv_d_x001  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
index 7120afa9be..076d2147c3 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -311,3 +311,97 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, 
arg_fcvt_d_wu *a, uint32_t insn)
 
 return true;
 }
+
+static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
+
+static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+REQUIRE_FPU;
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
+tcg_temp_free(t0);
+#else
+gen_exception_illegal(ctx);
+#endif
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e19398ce10..85cabb70fb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -179,44 +179,6 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
-uint32_t rs2, int rm, uint64_t min)
-{
-switch (rm) {
-case 0: /* fsgnj */
-if (rs1 == rs2) { /* FMOV */
-tcg_gen_mov_i64(cpu_fpr[rd], cpu_fpr[rs1]);
-} else {
-tcg_gen_deposit_i64(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-}
-break;
-case 1: /* fsgnjn */
-if (rs1 == rs2) { /* FNEG */
-tcg_gen_xori_i64(cpu_fpr[rd], cpu_fpr[rs1], min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_not_i64(t0, cpu_fpr[rs2]);
-tcg_gen_deposit_i64(cpu_fpr[rd], t0, cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-tcg_temp_free_i64(t0);
-}
-break;
-case 2: /* fsgnjx */
-if (rs1 == rs2) { /* FABS */
-tcg_gen_andi_i64(cpu_fpr[rd], cpu_fpr[rs1], ~min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_andi_i64(t0, cpu_fpr[rs2], min);
-tcg_gen_xor_i64(cpu_fpr[rd], cpu_fpr[rs1], t0);
-

[Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  | 17 +
 target/riscv/insn_trans/trans_rvm.inc.c | 87 +
 target/riscv/translate.c| 10 +--
 3 files changed, 105 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index dbb177395d..15dd6234a4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -114,3 +114,20 @@ subw 010 .  . 000 . 0111011 @r
 sllw 000 .  . 001 . 0111011 @r
 srlw 000 .  . 101 . 0111011 @r
 sraw 010 .  . 101 . 0111011 @r
+
+# *** RV32M Standard Extension ***
+mul  001 .  . 000 . 0110011 @r
+mulh 001 .  . 001 . 0110011 @r
+mulhsu   001 .  . 010 . 0110011 @r
+mulhu001 .  . 011 . 0110011 @r
+div  001 .  . 100 . 0110011 @r
+divu 001 .  . 101 . 0110011 @r
+rem  001 .  . 110 . 0110011 @r
+remu 001 .  . 111 . 0110011 @r
+
+# *** RV64M Standard Extension (in addition to RV32M) ***
+mulw 001 .  . 000 . 0111011 @r
+divw 001 .  . 100 . 0111011 @r
+divuw001 .  . 101 . 0111011 @r
+remw 001 .  . 110 . 0111011 @r
+remuw001 .  . 111 . 0111011 @r
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
new file mode 100644
index 00..2d0fd6a64f
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -0,0 +1,87 @@
+/*
+ * RISC-V translation routines for the RV64M Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+
+static bool trans_mul(DisasContext *ctx, arg_mul *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_div(DisasContext *ctx, arg_div *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_divu(DisasContext *ctx, arg_divu *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_rem(DisasContext *ctx, arg_rem *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_remu(DisasContext *ctx, arg_remu *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_mulw(DisasContext *ctx, arg_mulw *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_divw(DisasContext *ctx, arg_divw *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_divuw(DisasContext *ctx, arg_divuw *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_remw(DisasContext *ctx, arg_remw *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
+return true;
+}
+static bool trans_remuw(DisasContext *ctx, arg_remuw *a, uint32_t insn)
+{
+gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7438205492..7c1ecfaf1b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1638,6 +1638,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "decode_insn32.inc.c"
 /* Include insn module translation function */
 

[Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC

2018-10-12 Thread Bastian Koppelmann
for now only LUI & AUIPC are decoded and translated. If decodetree fails, we
falls back to the old decoder.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/Makefile.objs  | 10 +++
 target/riscv/insn32.decode  | 30 +
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +
 target/riscv/translate.c| 24 -
 4 files changed, 92 insertions(+), 7 deletions(-)
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index abd0a7cde3..ea02f9b9ef 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1,11 @@
 obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+
+target/riscv/decode_insn32.inc.c: \
+  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
new file mode 100644
index 00..44d4e922b6
--- /dev/null
+++ b/target/riscv/insn32.decode
@@ -0,0 +1,30 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see .
+
+# Fields:
+%rd7:5
+
+# immediates:
+%imm_u12:s20 !function=ex_shift_12
+
+# Formats 32:
+@u     . ... imm=%imm_u  
%rd
+
+# *** RV32I Base Instruction Set ***
+lui     . 0110111 @u
+auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
new file mode 100644
index 00..aee0d1637d
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -0,0 +1,35 @@
+/*
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_lui(DisasContext *ctx, arg_lui *a, uint32_t insn)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm);
+}
+return true;
+}
+
+static bool trans_auipc(DisasContext *ctx, arg_auipc *a, uint32_t insn)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next);
+}
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 18d7b6d147..2ee886c6b7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1666,6 +1666,19 @@ static void decode_RV32_64C(CPURISCVState *env, 
DisasContext *ctx)
 }
 }
 
+#define EX_SH(amount) \
+static int64_t ex_shift_##amount(int imm) \
+{ \
+return imm << amount; \
+}
+EX_SH(12)
+
+bool decode_insn32(DisasContext *ctx, uint32_t insn);
+/* Include the auto-generated decoder for 32 bit insn */
+#include "decode_insn32.inc.c"
+/* Include insn module translation function */
+#include "insn_trans/trans_rvi.inc.c"
+
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
 int rs1;
@@ -1686,12 +1699,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-

[Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode|  13 ++
 .../riscv/insn_trans/trans_privileged.inc.c   | 111 ++
 target/riscv/translate.c  |  49 +---
 3 files changed, 125 insertions(+), 48 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5df550169b..7c71f8338b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -44,6 +44,8 @@
 
 # Formats 32:
 @noargs  
+@sfence_vma ... . .   ... . ... %rs2 %rs1
+@sfence_vm  ... . .   ... . ... %rs1
 
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
@@ -65,6 +67,17 @@
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... %rs1 %rd
 
+# *** Privileged Instructions ***
+ecall   0 000 0 1110011 @noargs
+ebreak 0001 0 000 0 1110011 @noargs
+uret   00000010 0 000 0 1110011 @noargs
+sret   000100000010 0 000 0 1110011 @noargs
+hret   00100010 0 000 0 1110011 @noargs
+mret   001100000010 0 000 0 1110011 @noargs
+wfi000100000101 0 000 0 1110011 @noargs
+sfence_vma 0001001. . 000 0 1110011 @sfence_vma
+sfence_vm  000100000100 . 000 0 1110011 @sfence_vm
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
new file mode 100644
index 00..9534adb025
--- /dev/null
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -0,0 +1,111 @@
+/*
+ * RISC-V translation routines for the RISC-V privileged instructions.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_ecall(DisasContext *ctx, arg_ecall *a, uint32_t insn)
+{
+/* always generates U-level ECALL, fixed in do_interrupt handler */
+generate_exception(ctx, RISCV_EXCP_U_ECALL);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a, uint32_t insn)
+{
+generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_uret(DisasContext *ctx, arg_uret *a, uint32_t insn)
+{
+gen_exception_illegal(ctx);
+return true;
+}
+
+static bool trans_sret(DisasContext *ctx, arg_sret *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+CPURISCVState *env = current_cpu->env_ptr;
+if (riscv_has_ext(env, RVS)) {
+gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+} else {
+gen_exception_illegal(ctx);
+}
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_hret(DisasContext *ctx, arg_hret *a, uint32_t insn)
+{
+gen_exception_illegal(ctx);
+return true;
+}
+
+static bool trans_mret(DisasContext *ctx, arg_mret *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_wfi(DisasContext *ctx, arg_wfi *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_helper_wfi(cpu_env);
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a,
+ uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+

[Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch()

2018-10-12 Thread Bastian Koppelmann
The latter utilizes argument-sets of decodetree such that no manual
decoding is necessary as in gen_branch().

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 56 +
 target/riscv/translate.c| 47 -
 2 files changed, 38 insertions(+), 65 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 2668beb990..6097b82df4 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -73,42 +73,62 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a, 
uint32_t insn)
 return true;
 }
 
-static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+static bool trans_branch(DisasContext *ctx, arg_branch *a, TCGCond cond)
 {
+TCGLabel *l = gen_new_label();
+TCGv source1, source2;
+source1 = tcg_temp_new();
+source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_brcond_tl(cond, source1, source2, l);
+gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+gen_set_label(l); /* branch taken */
+
 CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+/* misaligned */
+gen_exception_inst_addr_mis(ctx);
+} else {
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(source1);
+tcg_temp_free(source2);
+
 return true;
 }
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+{
+return trans_branch(ctx, a, TCG_COND_EQ);
+}
+
 static bool trans_bne(DisasContext *ctx, arg_bne *a, uint32_t insn)
 {
-CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
-return true;
+return trans_branch(ctx, a, TCG_COND_NE);
 }
+
 static bool trans_blt(DisasContext *ctx, arg_blt *a, uint32_t insn)
 {
-CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
-return true;
+return trans_branch(ctx, a, TCG_COND_LT);
 }
+
 static bool trans_bge(DisasContext *ctx, arg_bge *a, uint32_t insn)
 {
-CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
-return true;
+return trans_branch(ctx, a, TCG_COND_GE);
 }
+
 static bool trans_bltu(DisasContext *ctx, arg_bltu *a, uint32_t insn)
 {
-CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
-return true;
+return trans_branch(ctx, a, TCG_COND_LTU);
 }
+
 static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
 {
-
-CPURISCVState *env = current_cpu->env_ptr;
-gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
-return true;
+return trans_branch(ctx, a, TCG_COND_GEU);
 }
 
 static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a0da694aa3..b8a9b1c64b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,53 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-   int rs1, int rs2, target_long bimm)
-{
-TCGLabel *l = gen_new_label();
-TCGv source1, source2;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
-
-switch (opc) {
-case OPC_RISC_BEQ:
-tcg_gen_brcond_tl(TCG_COND_EQ, source1, source2, l);
-break;
-case OPC_RISC_BNE:
-tcg_gen_brcond_tl(TCG_COND_NE, source1, source2, l);
-break;
-case OPC_RISC_BLT:
-tcg_gen_brcond_tl(TCG_COND_LT, source1, source2, l);
-break;
-case OPC_RISC_BGE:
-tcg_gen_brcond_tl(TCG_COND_GE, source1, source2, l);
-break;
-case OPC_RISC_BLTU:
-tcg_gen_brcond_tl(TCG_COND_LTU, source1, source2, l);
-break;
-case OPC_RISC_BGEU:
-tcg_gen_brcond_tl(TCG_COND_GEU, source1, source2, l);
-break;
-default:
-gen_exception_illegal(ctx);
-return;
-}
-tcg_temp_free(source1);
-tcg_temp_free(source2);
-
-gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
-gen_set_label(l); /* branch taken */
-if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
-/* misaligned */
-gen_exception_inst_addr_mis(ctx);
-} else {
-gen_goto_tb(ctx, 0, ctx->base.pc_next + bimm);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-}
-
 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
 target_long imm)
 {
-- 
2.19.1




[Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  | 19 +
 target/riscv/insn_trans/trans_rvi.inc.c | 52 +
 target/riscv/translate.c| 19 +
 3 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6..b49913416d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,14 +17,33 @@
 # this program.  If not, see .
 
 # Fields:
+%rs2   20:5
+%rs1   15:5
 %rd7:5
 
 # immediates:
+%imm_i20:s12
+%imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
+%imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
 
+# Argument sets:
+imm rs2 rs1
+
 # Formats 32:
+@i   . ... . ... imm=%imm_i %rs1 
%rd
+@b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
+@j     . ... imm=%imm_j  
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
+jal     . 110 @j
+jalr  . 000 . 1100111 @i
+beq  ... .. 000 . 1100011 @b
+bne  ... .. 001 . 1100011 @b
+blt  ... .. 100 . 1100011 @b
+bge  ... .. 101 . 1100011 @b
+bltu ... .. 110 . 1100011 @b
+bgeu ... .. 111 . 1100011 @b
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index aee0d1637d..83345d71d7 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,55 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a, 
uint32_t insn)
 }
 return true;
 }
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_jal(env, ctx, a->rd, a->imm);
+return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_jalr(env, ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_bne(DisasContext *ctx, arg_bne *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_blt(DisasContext *ctx, arg_blt *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_bge(DisasContext *ctx, arg_bge *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a, uint32_t insn)
+{
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
+{
+
+CPURISCVState *env = current_cpu->env_ptr;
+gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ee886c6b7..8181ad7419 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1671,6 +1671,7 @@ static void decode_RV32_64C(CPURISCVState *env, 
DisasContext *ctx)
 { \
 return imm << amount; \
 }
+EX_SH(1)
 EX_SH(12)
 
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1699,24 +1700,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_AUIPC:
-if (rd == 0) {
-break; /* NOP */
-}
-tcg_gen_movi_tl(cpu_gpr[rd], (sextract64(ctx->opcode, 12, 20) << 12) +
-   ctx->base.pc_next);
-break;
-case OPC_RISC_JAL:
-imm = GET_JAL_IMM(ctx->opcode);
-gen_jal(env, ctx, rd, imm);
-break;
-case OPC_RISC_JALR:
-gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_BRANCH:
-gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
-   GET_B_IMM(ctx->opcode));
-break;
 case OPC_RISC_LOAD:
 gen_load(ctx, 

[Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree

2018-10-12 Thread Bastian Koppelmann
we cannot remove the call to gen_arith() in decode_RV32_64G() since it
is used to translate multiply instructions.

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  36 
 target/riscv/insn_trans/trans_rvi.inc.c | 221 
 target/riscv/translate.c|   9 -
 3 files changed, 257 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index badd1d9216..cb7622e223 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,9 @@
 %rs1   15:5
 %rd7:5
 
+%sh620:6
+%sh520:5
+
 # immediates:
 %imm_i20:s12
 %imm_s25:s7 7:5
@@ -30,14 +33,19 @@
 
 # Argument sets:
 imm rs2 rs1
+ shamt rs1 rd
 
 # Formats 32:
+@r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
+@sh6 ..  .. .  ... . ...   shamt=%sh6  %rs1 
%rd
+@sh5 ...  . .  ... . ...   shamt=%sh5  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -57,8 +65,36 @@ lhu   . 101 . 011 @i
 sb   ...  .   . 000 . 0100011 @s
 sh   ...  .   . 001 . 0100011 @s
 sw   ...  .   . 010 . 0100011 @s
+addi  . 000 . 0010011 @i
+slti  . 010 . 0010011 @i
+sltiu . 011 . 0010011 @i
+xori  . 100 . 0010011 @i
+ori   . 110 . 0010011 @i
+andi  . 111 . 0010011 @i
+slli 00 ... 001 . 0010011 @sh6
+srli 00 ... 101 . 0010011 @sh6
+srai 01 ... 101 . 0010011 @sh6
+add  000 .. 000 . 0110011 @r
+sub  010 .. 000 . 0110011 @r
+sll  000 .. 001 . 0110011 @r
+slt  000 .. 010 . 0110011 @r
+sltu 000 .. 011 . 0110011 @r
+xor  000 .. 100 . 0110011 @r
+srl  000 .. 101 . 0110011 @r
+sra  010 .. 101 . 0110011 @r
+or   000 .. 110 . 0110011 @r
+and  000 .. 111 . 0110011 @r
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu     . 110 . 011 @i
 ld      . 011 . 011 @i
 sd   ... .  . 011 . 0100011 @s
+addiw   . 000 . 0011011 @i
+slliw000 .  . 001 . 0011011 @sh5
+srliw000 .  . 101 . 0011011 @sh5
+sraiw010 .  . 101 . 0011011 @sh5
+addw 000 .  . 000 . 0111011 @r
+subw 010 .  . 000 . 0111011 @r
+sllw 000 .  . 001 . 0111011 @r
+srlw 000 .  . 101 . 0111011 @r
+sraw 010 .  . 101 . 0111011 @r
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 5803518fdc..2b017cf4a4 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -156,3 +156,224 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a, 
uint32_t insn)
 return false;
 #endif
 }
+
+static bool trans_addi(DisasContext *ctx, arg_addi *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_slti(DisasContext *ctx, arg_slti *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_xori(DisasContext *ctx, arg_xori *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_ori(DisasContext *ctx, arg_ori *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
+{
+gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
+{
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+

[Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr()

2018-10-12 Thread Bastian Koppelmann
trans_jalr() is the only caller, so move the code into
trans_jalr().

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 27 +-
 target/riscv/translate.c| 38 -
 2 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index f5abec9b55..2668beb990 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -43,8 +43,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a, 
uint32_t insn)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
 {
+/* no chaining with JALR */
+TCGLabel *misaligned = NULL;
+TCGv t0 = tcg_temp_new();
 CPURISCVState *env = current_cpu->env_ptr;
-gen_jalr(env, ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+
+gen_get_gpr(cpu_pc, a->rs1);
+tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+
+if (!riscv_has_ext(env, RVC)) {
+misaligned = gen_new_label();
+tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+}
+
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
+}
+tcg_gen_lookup_and_goto_ptr();
+
+if (misaligned) {
+gen_set_label(misaligned);
+gen_exception_inst_addr_mis(ctx);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(t0);
 return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6b4a0430fd..a0da694aa3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,44 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
- int rd, int rs1, target_long imm)
-{
-/* no chaining with JALR */
-TCGLabel *misaligned = NULL;
-TCGv t0 = tcg_temp_new();
-
-switch (opc) {
-case OPC_RISC_JALR:
-gen_get_gpr(cpu_pc, rs1);
-tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
-tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
-
-if (!riscv_has_ext(env, RVC)) {
-misaligned = gen_new_label();
-tcg_gen_andi_tl(t0, cpu_pc, 0x2);
-tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
-}
-
-if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-}
-tcg_gen_lookup_and_goto_ptr();
-
-if (misaligned) {
-gen_set_label(misaligned);
-gen_exception_inst_addr_mis(ctx);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-
-default:
-gen_exception_illegal(ctx);
-break;
-}
-tcg_temp_free(t0);
-}
-
 static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
int rs1, int rs2, target_long bimm)
 {
-- 
2.19.1




[Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  8 
 target/riscv/insn_trans/trans_rvi.inc.c | 20 
 target/riscv/translate.c| 14 --
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index cb7622e223..695577b19b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -24,6 +24,9 @@
 %sh620:6
 %sh520:5
 
+%pred   24:4
+%succ   20:4
+
 # immediates:
 %imm_i20:s12
 %imm_s25:s7 7:5
@@ -36,6 +39,8 @@
  shamt rs1 rd
 
 # Formats 32:
+@noargs  
+
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
@@ -45,6 +50,7 @@
 
 @sh6 ..  .. .  ... . ...   shamt=%sh6  %rs1 
%rd
 @sh5 ...  . .  ... . ...   shamt=%sh5  %rs1 
%rd
+@fence      .  ... . ... %pred %succ
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
@@ -84,6 +90,8 @@ srl  000 .. 101 . 0110011 @r
 sra  010 .. 101 . 0110011 @r
 or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
+fence     0 000 0 000 @fence
+fence_i   0 001 0 000 @noargs
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu     . 110 . 011 @i
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 2b017cf4a4..f532ca48e8 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -377,3 +377,23 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a, 
uint32_t insn)
 gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
 return true;
 }
+
+static bool trans_fence(DisasContext *ctx, arg_fence *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+/* FENCE is a full memory barrier. */
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+#endif
+return true;
+}
+static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+/* FENCE_I is a no-op in QEMU,
+ * however we need to end the translation block */
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+tcg_gen_exit_tb(NULL, 0);
+ctx->base.is_jmp = DISAS_NORETURN;
+#endif
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 96169c4935..08c3b73c1a 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1739,20 +1739,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
  GET_RM(ctx->opcode));
 break;
-case OPC_RISC_FENCE:
-#ifndef CONFIG_USER_ONLY
-if (ctx->opcode & 0x1000) {
-/* FENCE_I is a no-op in QEMU,
- * however we need to end the translation block */
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-tcg_gen_exit_tb(NULL, 0);
-ctx->base.is_jmp = DISAS_NORETURN;
-} else {
-/* FENCE is a full memory barrier. */
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
-}
-#endif
-break;
 case OPC_RISC_SYSTEM:
 gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF0) >> 20);
-- 
2.19.1




[Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree

2018-10-12 Thread Bastian Koppelmann
Hi,

this patchset converts the RISC-V decoder to decodetree in three major steps:

1) Convert 32-bit instructions to decodetree [Patch 1-14]:
Many of the gen_* functions are called by the decode functions for 16-bit
and 32-bit functions. If we move translation code from the gen_*
functions to the generated trans_* functions of decode-tree, we get a lot of
duplication. Therefore, we mostly generate calls to the old gen_* function
which are properly replaced after step 2).

Each of the trans_ functions are grouped into files corresponding to their
ISA extension, e.g. addi which is in RV32I is translated in the file
'trans_rvi.inc.c'.

2) Convert 16-bit instructions to decodetree [Patch 15-17]:
All 16 bit instructions have a direct mapping to a 32 bit instruction. Thus,
we convert the arguments in the 16 bit trans_ function to the arguments of
the corresponding 32 bit instruction and call the 32 bit trans_ function.

3) Remove old manual decoding in gen_* function [Patch 17-28]:
this move all manual translation code into the trans_* instructions of
decode tree, such that we can remove the old decode_* functions.

the full tree can be found here:
https://github.com/bkoppelmann/qemu/tree/riscv-dt

Cheers,
Bastian

Bastian Koppelmann (28):
  targer/riscv: Activate decodetree and implemnt LUI & AUIPC
  target/riscv: Convert RVXI branch insns to decodetree
  target/riscv: Convert RVXI load/store insns to decodetree
  target/riscv: Convert RVXI arithmetic insns to decodetree
  target/riscv: Convert RVXI fence insns to decodetree
  target/riscv: Convert RVXI csr insns to decodetree
  target/riscv: Convert RVXM insns to decodetree
  target/riscv: Convert RV32A insns to decodetree
  target/riscv: Convert RV64A insns to decodetree
  target/riscv: Convert RV32F insns to decodetree
  target/riscv: Convert RV64F insns to decodetree
  target/riscv: Convert RV32D insns to decodetree
  target/riscv: Convert RV64D insns to decodetree
  target/riscv: Convert RV priv insns to decodetree
  target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  target/riscv: Remove gen_jalr()
  target/riscv: Replace gen_branch() with trans_branch()
  target/riscv: Replace gen_load() with trans_load()
  target/riscv: Replace gen_store() with trans_store()
  target/riscv: Move gen_arith_imm() decoding into trans_* functions
  target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  target/riscv: Remove shift and slt insn manual decoding
  target/riscv: Remove manual decoding of RV32/64M insn
  target/riscv: Remove gen_system()
  target/riscv: Remove decode_RV32_64G()
  target/riscv: Replace gen_exception_illegal with return false

 target/riscv/Makefile.objs|   17 +
 target/riscv/insn16.decode|  126 ++
 target/riscv/insn32.decode|  255 +++
 .../riscv/insn_trans/trans_privileged.inc.c   |  109 +
 target/riscv/insn_trans/trans_rva.inc.c   |  274 +++
 target/riscv/insn_trans/trans_rvc.inc.c   |  339 
 target/riscv/insn_trans/trans_rvd.inc.c   |  407 
 target/riscv/insn_trans/trans_rvf.inc.c   |  396 
 target/riscv/insn_trans/trans_rvi.inc.c   |  624 ++
 target/riscv/insn_trans/trans_rvm.inc.c   |   94 +
 target/riscv/translate.c  | 1745 ++---
 11 files changed, 2827 insertions(+), 1559 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

--
2.19.1




[Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +
 target/riscv/translate.c| 43 +-
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 695577b19b..dbb177395d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 %sh620:6
 %sh520:5
+%csr20:12
 
 %pred   24:4
 %succ   20:4
@@ -51,6 +52,7 @@
 @sh6 ..  .. .  ... . ...   shamt=%sh6  %rs1 
%rd
 @sh5 ...  . .  ... . ...   shamt=%sh5  %rs1 
%rd
 @fence      .  ... . ... %pred %succ
+@csr    .  ... . ...   %csr %rs1 
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
@@ -92,6 +94,12 @@ or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
 fence     0 000 0 000 @fence
 fence_i   0 001 0 000 @noargs
+csrrw . 001 . 1110011 @csr
+csrrs . 010 . 1110011 @csr
+csrrc . 011 . 1110011 @csr
+csrrwi    . 101 . 1110011 @csr
+csrrsi    . 110 . 1110011 @csr
+csrrci    . 111 . 1110011 @csr
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu     . 110 . 011 @i
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index f532ca48e8..f5abec9b55 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -397,3 +397,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i 
*a, uint32_t insn)
 #endif
 return true;
 }
+
+#define RISCV_OP_CSR_PRE do {\
+source1 = tcg_temp_new(); \
+csr_store = tcg_temp_new(); \
+dest = tcg_temp_new(); \
+rs1_pass = tcg_temp_new(); \
+gen_get_gpr(source1, a->rs1); \
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
+tcg_gen_movi_tl(rs1_pass, a->rs1); \
+tcg_gen_movi_tl(csr_store, a->csr); \
+gen_io_start();\
+} while (0)
+
+#define RISCV_OP_CSR_POST do {\
+gen_io_end(); \
+gen_set_gpr(a->rd, dest); \
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
+tcg_gen_exit_tb(NULL, 0); \
+ctx->base.is_jmp = DISAS_NORETURN; \
+tcg_temp_free(source1); \
+tcg_temp_free(csr_store); \
+tcg_temp_free(dest); \
+tcg_temp_free(rs1_pass); \
+} while (0)
+
+
+static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, source1, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a, uint32_t insn)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 08c3b73c1a..7438205492 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1276,16 +1276,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t 
opc, int rd,
 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
   int rd, int rs1, int csr)
 {
-TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
+TCGv source1, dest;
 source1 = tcg_temp_new();
-csr_store = tcg_temp_new();
 dest = tcg_temp_new();
-rs1_pass = tcg_temp_new();
-imm_rs1 = tcg_temp_new();
 gen_get_gpr(source1, rs1);
 tcg_gen_movi_tl(cpu_pc, 

[Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  17 +++
 target/riscv/insn_trans/trans_rva.inc.c | 175 
 target/riscv/translate.c|   1 +
 3 files changed, 193 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 15dd6234a4..31fca2f184 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -38,6 +38,7 @@
 # Argument sets:
 imm rs2 rs1
  shamt rs1 rd
+aq rl rs2 rs1 rd
 
 # Formats 32:
 @noargs  
@@ -54,6 +55,9 @@
 @fence      .  ... . ... %pred %succ
 @csr    .  ... . ...   %csr %rs1 
%rd
 
+@atom_ld . aq:1 rl:1 .  . ...  rs2=0 %rs1 
%rd
+@atom_st . aq:1 rl:1 .  . ...  %rs2  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -131,3 +135,16 @@ divw 001 .  . 100 . 0111011 @r
 divuw001 .  . 101 . 0111011 @r
 remw 001 .  . 110 . 0111011 @r
 remuw001 .  . 111 . 0111011 @r
+
+# *** RV32A Standard Extension ***
+lr_w   00010 . . 0 . 010 . 010 @atom_ld
+sc_w   00011 . . . . 010 . 010 @atom_st
+amoswap_w  1 . . . . 010 . 010 @atom_st
+amoadd_w   0 . . . . 010 . 010 @atom_st
+amoxor_w   00100 . . . . 010 . 010 @atom_st
+amoand_w   01100 . . . . 010 . 010 @atom_st
+amoor_w01000 . . . . 010 . 010 @atom_st
+amomin_w   1 . . . . 010 . 010 @atom_st
+amomax_w   10100 . . . . 010 . 010 @atom_st
+amominu_w  11000 . . . . 010 . 010 @atom_st
+amomaxu_w  11100 . . . . 010 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
new file mode 100644
index 00..2cb2bfd9cc
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -0,0 +1,175 @@
+/*
+ * RISC-V translation routines for the RV64A Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+/* Put addr in load_res, data in load_val.  */
+gen_get_gpr(src1, a->rs1);
+if (a->rl) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+}
+tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
+if (a->aq) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+}
+tcg_gen_mov_tl(load_res, src1);
+gen_set_gpr(a->rd, load_val);
+
+tcg_temp_free(src1);
+return true;
+}
+
+static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+TCGLabel *l2 = gen_new_label();
+
+gen_get_gpr(src1, a->rs1);
+tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
+
+gen_get_gpr(src2, a->rs2);
+/* Note that the TCG atomic primitives are SC,
+   so we can ignore AQ/RL along this path.  */
+tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+  ctx->mem_idx, mop);
+tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
+gen_set_gpr(a->rd, dat);
+tcg_gen_br(l2);
+
+gen_set_label(l1);
+/* Address comparion failure.  However, we still need to
+   provide the memory barrier implied by AQ/RL.  */
+tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
+tcg_gen_movi_tl(dat, 1);
+gen_set_gpr(a->rd, dat);
+
+gen_set_label(l2);
+tcg_temp_free(dat);
+tcg_temp_free(src1);
+tcg_temp_free(src2);
+return true;
+}
+
+static bool gen_amo(DisasContext *ctx, arg_atomic *a, uint32_t opc,
+TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = 

[Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  | 15 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 71 +
 target/riscv/translate.c|  7 ---
 3 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b49913416d..badd1d9216 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 # immediates:
 %imm_i20:s12
+%imm_s25:s7 7:5
 %imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
 %imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
@@ -33,6 +34,7 @@
 # Formats 32:
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
+@s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
@@ -47,3 +49,16 @@ blt  ... .. 100 . 1100011 @b
 bge  ... .. 101 . 1100011 @b
 bltu ... .. 110 . 1100011 @b
 bgeu ... .. 111 . 1100011 @b
+lb    . 000 . 011 @i
+lh    . 001 . 011 @i
+lw    . 010 . 011 @i
+lbu   . 100 . 011 @i
+lhu   . 101 . 011 @i
+sb   ...  .   . 000 . 0100011 @s
+sh   ...  .   . 001 . 0100011 @s
+sw   ...  .   . 010 . 0100011 @s
+
+# *** RV64I Base Instruction Set (in addition to RV32I) ***
+lwu     . 110 . 011 @i
+ld      . 011 . 011 @i
+sd   ... .  . 011 . 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 83345d71d7..5803518fdc 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -85,3 +85,74 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, 
uint32_t insn)
 gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
 return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+{
+gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)
+{
+gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_lw(DisasContext *ctx, arg_lw *a, uint32_t insn)
+{
+gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_lbu(DisasContext *ctx, arg_lbu *a, uint32_t insn)
+{
+gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_lhu(DisasContext *ctx, arg_lhu *a, uint32_t insn)
+{
+gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
+return true;
+#else
+return false;
+#endif
+}
+static bool trans_ld(DisasContext *ctx, arg_ld *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+{
+gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_sh(DisasContext *ctx, arg_sh *a, uint32_t insn)
+{
+gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
+return true;
+}
+static bool trans_sw(DisasContext *ctx, arg_sw *a, uint32_t insn)
+{
+gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
+return true;
+#else
+return false;
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8181ad7419..517a2cda17 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1700,13 +1700,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_LOAD:
-gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_STORE:
-gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
-  GET_STORE_IMM(ctx->opcode));
-break;
 case OPC_RISC_ARITH_IMM:
 #if defined(TARGET_RISCV64)
 case OPC_RISC_ARITH_IMM_W:
-- 
2.19.1




Re: [Qemu-devel] [PATCH v2 6/8] curl: Support auto-read-only option

2018-10-12 Thread Eric Blake

On 10/12/18 6:55 AM, Kevin Wolf wrote:

If read-only=off, but auto-read-only=on is given, just degrade to
read-only.

Signed-off-by: Kevin Wolf 
---
  block/curl.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)


Reviewed-by: Eric Blake 

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



Re: [Qemu-devel] [RFC 0/5] Improve balloon handling of pagesizes other than 4kiB

2018-10-12 Thread Michael S. Tsirkin
On Fri, Oct 12, 2018 at 02:24:26PM +1100, David Gibson wrote:
> The virtio-balloon devices was never really thought out for cases
> other than 4kiB pagesize on both guest and host.  It works in some
> cases, but in others can be ineffectual or even cause guest memory
> corruption.
> 
> This series makes a handful of preliminary cleanups, then makes a
> change to safely, though not perfectly, handle cases with non 4kiB
> pagesizes.

BTW do you want to add an interface to specify the page size?
I can see either host or guest or both supporting that.

Reviewed-by: Michael S. Tsirkin 


> David Gibson (5):
>   virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate
>   virtio-balloon: Corrections to address verification
>   virtio-balloon: Rework ballon_page() interface
>   virtio-balloon: Use ram_block_discard_range() instead of raw madvise()
>   virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size
> 
>  hw/virtio/virtio-balloon.c | 100 -
>  include/hw/virtio/virtio-balloon.h |   3 +
>  2 files changed, 87 insertions(+), 16 deletions(-)
> 
> -- 
> 2.17.1



Re: [Qemu-devel] [PATCH v2 5/8] file-posix: Support auto-read-only option

2018-10-12 Thread Eric Blake

On 10/12/18 6:55 AM, Kevin Wolf wrote:

If read-only=off, but auto-read-only=on is given, open the file
read-write if we have the permissions, but instead of erroring out for
read-only files, just degrade to read-only.

Signed-off-by: Kevin Wolf 
---
  block/file-posix.c | 13 +
  1 file changed, 13 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index 2da3a76355..eead3f2df3 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -527,6 +527,19 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
  
  s->fd = -1;

  fd = qemu_open(filename, s->open_flags, 0644);
+
+if (fd < 0 && (errno == EACCES || errno == EROFS)) {
+/* Try to degrade to read-only, but if it doesn't work, still use the
+ * normal error message. */
+ret = bdrv_apply_auto_read_only(bs, NULL, NULL);


No guarantees what errno is after this call...


+if (ret == 0) {
+bdrv_flags &= ~BDRV_O_RDWR;
+raw_parse_flags(bdrv_flags, >open_flags);
+assert(!(s->open_flags & O_CREAT));
+fd = qemu_open(filename, s->open_flags);
+}
+}
+
  if (fd < 0) {
  ret = -errno;
  error_setg_errno(errp, errno, "Could not open '%s'", filename);


...even though you still rely on it here.

Possible solution:

fd = qemu_open();
if (fd < 0) {
ret = -errno;
if ((errno == EACCES || errno == EROFS) &&
!bdrv_apply_auto_read_only(bs, NULL, NULL)) {
bdrv_flags ...
fd = qemu_open();
ret = fd < 0 ? -errno : 0;
}
}
if (fd < 0) {
error_setg_errno(errp, -ret, "Could not open '%s'

Another possible solution: change the contract of 
bdrv_apply_auto_read_only() to leave errno unchanged (a bit odd, if the 
return value is different than the incoming errno value).


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



[Qemu-devel] [PATCH v4 2/3] Acceptance tests: add make rule for running them

2018-10-12 Thread Cleber Rosa
The acceptance (aka functional, aka Avocado-based) tests are
Python files located in "tests/acceptance" that need to be run
with the Avocado libs and test runner.

Let's provide a convenient way for QEMU developers to run them,
by making use of the tests-venv with the required setup.

Also, while the Avocado test runner will take care of creating a
location to save test results to, it was understood that it's better
if the results are kept within the build tree.

Signed-off-by: Cleber Rosa 
---
 docs/devel/testing.rst  | 35 ++-
 tests/Makefile.include  | 21 +++--
 tests/venv-requirements.txt |  1 +
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 727c4019b5..b992a2961d 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -545,10 +545,31 @@ Tests based on ``avocado_qemu.Test`` can easily:
- 
http://avocado-framework.readthedocs.io/en/latest/api/test/avocado.html#avocado.Test
- 
http://avocado-framework.readthedocs.io/en/latest/api/utils/avocado.utils.html
 
-Installation
-
+Running tests
+-
 
-To install Avocado and its dependencies, run:
+You can run the acceptance tests simply by executing:
+
+.. code::
+
+  make check-acceptance
+
+This involves the automatic creation of Python virtual environment
+within the build tree (at ``tests/venv``) which will have all the
+right dependencies, and will save tests results also within the
+build tree (at ``tests/results``).
+
+Note: the build environment must be using a Python 3 stack, and have
+the ``venv`` and ``pip`` packages installed.  If necessary, make sure
+``configure`` is called with ``--python=`` and that those modules are
+available.  On Debian and Ubuntu based systems, depending on the
+specific version, they may be on packages named ``python3-venv`` and
+``python3-pip``.
+
+Manual Installation
+---
+
+To manually install Avocado and its dependencies, run:
 
 .. code::
 
@@ -689,11 +710,15 @@ The exact QEMU binary to be used on QEMUMachine.
 Uninstalling Avocado
 
 
-If you've followed the installation instructions above, you can easily
-uninstall Avocado.  Start by listing the packages you have installed::
+If you've followed the manual installation instructions above, you can
+easily uninstall Avocado.  Start by listing the packages you have
+installed::
 
   pip list --user
 
 And remove any package you want with::
 
   pip uninstall 
+
+If you've used ``make check-acceptance``, the Python virtual environment where
+Avocado is installed will be cleaned up as part of ``make check-clean``.
diff --git a/tests/Makefile.include b/tests/Makefile.include
index b66180efa1..75547fc947 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -11,6 +11,7 @@ check-help:
@echo " $(MAKE) check-qapi-schemaRun QAPI schema tests"
@echo " $(MAKE) check-block  Run block tests"
@echo " $(MAKE) check-tcgRun TCG tests"
+   @echo " $(MAKE) check-acceptance Run all acceptance (functional) 
tests"
@echo " $(MAKE) check-report.htmlGenerates an HTML test report"
@echo " $(MAKE) check-venv   Creates a Python venv for tests"
@echo " $(MAKE) check-clean  Clean the tests"
@@ -1020,10 +1021,15 @@ check-decodetree:
 
 # Python venv for running tests
 
-.PHONY: check-venv
+.PHONY: check-venv check-acceptance
 
 TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
 TESTS_VENV_REQ=$(SRC_PATH)/tests/venv-requirements.txt
+TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
+# Controls the output generated by Avocado when running tests.
+# Any number of command separated loggers are accepted.  For more
+# information please refer to "avocado --help".
+AVOCADO_SHOW=none
 
 $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
$(call quiet-command, \
@@ -1034,8 +1040,19 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
 PIP, $(TESTS_VENV_REQ))
$(call quiet-command, touch $@)
 
+$(TESTS_RESULTS_DIR):
+   $(call quiet-command, mkdir -p $@, \
+MKDIR, $@)
+
 check-venv: $(TESTS_VENV_DIR)
 
+check-acceptance: check-venv $(TESTS_RESULTS_DIR)
+   $(call quiet-command, \
+$(TESTS_VENV_DIR)/bin/python -m avocado \
+--show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
+--failfast=on $(SRC_PATH)/tests/acceptance, \
+"AVOCADO", "tests/acceptance")
+
 # Consolidated targets
 
 .PHONY: check-qapi-schema check-qtest check-unit check check-clean
@@ -1049,7 +1066,7 @@ check-clean:
rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), 
$(check-qtest-$(target)-y)) $(check-qtest-generic-y))
rm -f tests/test-qapi-gen-timestamp
-   rm -rf $(TESTS_VENV_DIR)
+   rm -rf $(TESTS_VENV_DIR) $(TESTS_RESULTS_DIR)
 
 clean: check-clean
 
diff --git 

[Qemu-devel] [PATCH v4 0/3] Bootstrap Python venv and acceptance/functional tests

2018-10-12 Thread Cleber Rosa
TL;DR
=

Allow acceptance tests to be run with `make check-acceptance`.

Details
===

This introduces a Python virtual environment that will be setup within
the QEMU build directory, that will contain the exact environment that
tests may require.

There's one current caveat: it requires Python 3, as it's based on the
venv module.  This was based on some discussions and perception about
standardizing on Python 3, but can easily be made to accommodate Python
2 as well.

Example of bootstrap and test execution on Travis-CI:

https://travis-ci.org/qemu/qemu/jobs/439331028#L2508

   ...
  VENV/home/travis/build/qemu/qemu/tests/venv
  MKDIR   /home/travis/build/qemu/qemu/tests/results
  PIP /home/travis/build/qemu/qemu/tests/venv-requirements.txt
  AVOCADO tests/acceptance
JOB ID : 920e4fcf55a1782f1ae77bee64b20ccdc2ed
JOB LOG: 
/home/travis/build/qemu/qemu/tests/results/job-2018-10-09T21.42-920e4fc/job.log
 (1/6) 
/home/travis/build/qemu/qemu/tests/acceptance/boot_linux_console.py:BootLinuxConsole.test:
  PASS (3.57 s)
 (2/6) 
/home/travis/build/qemu/qemu/tests/acceptance/version.py:Version.test_qmp_human_info_version:
  PASS (0.04 s)
 (3/6) 
/home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_no_vnc:  PASS 
(0.04 s)
 (4/6) 
/home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_no_vnc_change_password:
  PASS (0.04 s)
 (5/6) 
/home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_vnc_change_password_requires_a_password:
  PASS (0.04 s)
 (6/6) 
/home/travis/build/qemu/qemu/tests/acceptance/vnc.py:Vnc.test_vnc_change_password:
  PASS (0.04 s)
RESULTS: PASS 6 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
JOB TIME   : 3.90 s
   ...

Changes from v3:


 * Fixed typo in commit message (s/requiment/requirement/).  (Eric)

Changes from v2:


 * Make the $(TESTS_VENV_DIR) target depend on the
   venv-requirements.txt file, and touch $(TESTS_VENV_DIR) after venv
   runs.  With this, updates on the file are reflected on the
   venv. (Philippe)

 * Run pip with "python -m pip".  It may have been installed reusing
   the system wide packages, and then the script may not be available
   on the venv. (Philippe)

 * Dropped Python version on Travis, and using the version supplied
   by the distro (3.4). (Philippe)

 * Added "python3.4-venv" package requirement on Travis. (Philippe)

 * Added variable (AVOCADO_SHOW) with logging streams to be shown
   while running the acceptance tests.  By default it's set to none,
   the equivalent of the quiet mode used on previous versions.
   (Philippe)

 * On Travis, set the AVOCADO_SHOW variable to "app", so that the
   individual test results can be easily seen.  (Philippe)

Ideas discussed, but not implemented:

  * Run pip with "$(PYTHON) -m pip -q install ..." because it points
to the system wide Python installation. (Philippe)

  * Drop the "--system-site-packages" flag.  Waiting on another round
of tests to determine if they are really the cause of some package
installation problems.

Changes from v1:


 * TESTS_VENV_REQ (the path of "venv-requirements.txt") now points to
   the source path ($SRC_PATH instead of $BUILD_DIR)

 * Create the venv with "--system-site-packages", which allows the
   reuse of packages (and no additional downloads) in case there's a
   package installed system wide providing the same package and
   version.

 * Run Avocado with "python -m avocado".  It may have been installed
   reusing the system wide packages, and then the script may not
   be available on the venv.

 * Improved documentation describing the Python 3, venv and pip
   requirements.

 * Updated avocado-framework requirement to latest released version
   (65.0)

 * (New commit) Added support for running the acceptance tests on
   Travis.

Ideas discussed, but not implemented:

 * Install external packages such as python3-pip on Debian based
   systems, deemed too invasive on developer's systems.

 * Allow the use of Python 2, and consequently the "virtualenv"
   module.

Cleber Rosa (3):
  Bootstrap Python venv for tests
  Acceptance tests: add make rule for running them
  Travis support for the acceptance tests

 .travis.yml |  5 +
 docs/devel/testing.rst  | 35 ++-
 tests/Makefile.include  | 37 +
 tests/venv-requirements.txt |  4 
 4 files changed, 76 insertions(+), 5 deletions(-)
 create mode 100644 tests/venv-requirements.txt

-- 
2.17.1




[Qemu-devel] [PATCH v4 1/3] Bootstrap Python venv for tests

2018-10-12 Thread Cleber Rosa
A number of QEMU tests are written in Python, and may benefit
from an untainted Python venv.

By using make rules, tests that depend on specific Python libs
can set that rule as a requirement, along with rules that require
the presence or installation of specific libraries.

The tests/venv-requirements.txt is supposed to contain the
Python requirements that should be added to the venv created
by check-venv.

Signed-off-by: Cleber Rosa 
---
 tests/Makefile.include  | 20 
 tests/venv-requirements.txt |  3 +++
 2 files changed, 23 insertions(+)
 create mode 100644 tests/venv-requirements.txt

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 5eadfd52f9..b66180efa1 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -12,6 +12,7 @@ check-help:
@echo " $(MAKE) check-block  Run block tests"
@echo " $(MAKE) check-tcgRun TCG tests"
@echo " $(MAKE) check-report.htmlGenerates an HTML test report"
+   @echo " $(MAKE) check-venv   Creates a Python venv for tests"
@echo " $(MAKE) check-clean  Clean the tests"
@echo
@echo "Please note that HTML reports do not regenerate if the unit 
tests"
@@ -1017,6 +1018,24 @@ check-decodetree:
   ./check.sh "$(PYTHON)" "$(SRC_PATH)/scripts/decodetree.py", \
   TEST, decodetree.py)
 
+# Python venv for running tests
+
+.PHONY: check-venv
+
+TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
+TESTS_VENV_REQ=$(SRC_PATH)/tests/venv-requirements.txt
+
+$(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
+   $(call quiet-command, \
+$(PYTHON) -m venv --system-site-packages $@, \
+VENV, $@)
+   $(call quiet-command, \
+$(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
$(TESTS_VENV_REQ), \
+PIP, $(TESTS_VENV_REQ))
+   $(call quiet-command, touch $@)
+
+check-venv: $(TESTS_VENV_DIR)
+
 # Consolidated targets
 
 .PHONY: check-qapi-schema check-qtest check-unit check check-clean
@@ -1030,6 +1049,7 @@ check-clean:
rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), 
$(check-qtest-$(target)-y)) $(check-qtest-generic-y))
rm -f tests/test-qapi-gen-timestamp
+   rm -rf $(TESTS_VENV_DIR)
 
 clean: check-clean
 
diff --git a/tests/venv-requirements.txt b/tests/venv-requirements.txt
new file mode 100644
index 00..d39f9d1576
--- /dev/null
+++ b/tests/venv-requirements.txt
@@ -0,0 +1,3 @@
+# Add Python module requirements, one per line, to be installed
+# in the tests/venv Python virtual environment. For more info,
+# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
-- 
2.17.1




[Qemu-devel] [PATCH v4 3/3] Travis support for the acceptance tests

2018-10-12 Thread Cleber Rosa
This enables the execution of the acceptance tests on Travis.

Because the Travis environment is based on Ubuntu Trusty, it requires
the python3-pip and python3.4-venv packages.

Signed-off-by: Cleber Rosa 
---
 .travis.yml | 5 +
 1 file changed, 5 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 95be6ec59f..f55f799c52 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,6 +36,8 @@ addons:
   - liburcu-dev
   - libusb-1.0-0-dev
   - libvte-2.90-dev
+  - python3-pip
+  - python3.4-venv
   - sparse
   - uuid-dev
   - gcovr
@@ -117,6 +119,9 @@ matrix:
 - env: CONFIG="--target-list=x86_64-softmmu"
   python:
 - "3.6"
+# Acceptance (Functional) tests
+- env: CONFIG="--python=/usr/bin/python3 --target-list=x86_64-softmmu"
+   TEST_CMD="make AVOCADO_SHOW=app check-acceptance"
 # Using newer GCC with sanitizers
 - addons:
 apt:
-- 
2.17.1




[Qemu-devel] [PATCH v5 19/28] target/mips: Improve DSP R2/R3-related naming

2018-10-12 Thread Aleksandar Markovic
From: Stefan Markovic 

Do following replacements:

ASE_DSPR2 -> ASE_DSP_R2
ASE_DSPR3 -> ASE_DSP_R3
check_dspr2() -> check_dsp_r2()
check_dspr3() -> check_dsp_r3()

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Stefan Markovic 
Signed-off-by: Aleksandar Markovic 
---
 target/mips/internal.h   |   4 +-
 target/mips/mips-defs.h  |   4 +-
 target/mips/translate.c  | 180 +++
 target/mips/translate_init.inc.c |   8 +-
 4 files changed, 98 insertions(+), 98 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index e367d7e..6cf00d8 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -358,12 +358,12 @@ static inline void compute_hflags(CPUMIPSState *env)
 (env->CP0_Config5 & (1 << CP0C5_SBRI))) {
 env->hflags |= MIPS_HFLAG_SBRI;
 }
-if (env->insn_flags & ASE_DSPR3) {
+if (env->insn_flags & ASE_DSP_R3) {
 if (env->CP0_Status & (1 << CP0St_MX)) {
 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
MIPS_HFLAG_DSPR3;
 }
-} else if (env->insn_flags & ASE_DSPR2) {
+} else if (env->insn_flags & ASE_DSP_R2) {
 /* Enables access MIPS DSP resources, now our cpu is DSP ASER2,
so enable to access DSPR2 resources. */
 if (env->CP0_Status & (1 << CP0St_MX)) {
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index b27b7ae..5b985b8 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -46,8 +46,8 @@
 #define   ASE_MIPS3D0x0002
 #define   ASE_MDMX  0x0004
 #define   ASE_DSP   0x0008
-#define   ASE_DSPR2 0x0010
-#define   ASE_DSPR3 0x0200
+#define   ASE_DSP_R20x0010
+#define   ASE_DSP_R30x0200
 #define   ASE_MT0x0020
 #define   ASE_SMARTMIPS 0x0040
 #define   ASE_MICROMIPS 0x0080
diff --git a/target/mips/translate.c b/target/mips/translate.c
index c3ad65c..1d31051 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1858,7 +1858,7 @@ static inline void check_dsp(DisasContext *ctx)
 }
 }
 
-static inline void check_dspr2(DisasContext *ctx)
+static inline void check_dsp_r2(DisasContext *ctx)
 {
 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
 if (ctx->insn_flags & ASE_DSP) {
@@ -1869,7 +1869,7 @@ static inline void check_dspr2(DisasContext *ctx)
 }
 }
 
-static inline void check_dspr3(DisasContext *ctx)
+static inline void check_dsp_r3(DisasContext *ctx)
 {
 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR3))) {
 if (ctx->insn_flags & ASE_DSP) {
@@ -17642,7 +17642,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, 
uint32_t opc,
 case NM_POOL32AXF_2_0_7:
 switch (extract32(ctx->opcode, 9, 3)) {
 case NM_DPA_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
 break;
 case NM_DPAQ_S_W_PH:
@@ -17650,7 +17650,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, 
uint32_t opc,
 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
 break;
 case NM_DPS_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
 break;
 case NM_DPSQ_S_W_PH:
@@ -17665,7 +17665,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, 
uint32_t opc,
 case NM_POOL32AXF_2_8_15:
 switch (extract32(ctx->opcode, 9, 3)) {
 case NM_DPAX_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
 break;
 case NM_DPAQ_SA_L_W:
@@ -17673,7 +17673,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, 
uint32_t opc,
 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
 break;
 case NM_DPSX_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
 break;
 case NM_DPSQ_SA_L_W:
@@ -17692,7 +17692,7 @@ static void gen_pool32axf_2_multiply(DisasContext *ctx, 
uint32_t opc,
 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
 break;
 case NM_DPAQX_S_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
 break;
 case NM_DPSU_H_QBL:
@@ -17700,11 +17700,11 @@ static void gen_pool32axf_2_multiply(DisasContext 
*ctx, uint32_t opc,
 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
 break;
 case NM_DPSQX_S_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
 break;
 case NM_MULSA_W_PH:
-check_dspr2(ctx);
+check_dsp_r2(ctx);
 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
 

Re: [Qemu-devel] [PATCH v2 3/8] block: Require auto-read-only for existing fallbacks

2018-10-12 Thread Eric Blake

On 10/12/18 6:55 AM, Kevin Wolf wrote:

Some block drivers have traditionally changed their node to read-only
mode without asking the user. This behaviour has been marked deprecated
since 2.11, expecting users to provide an explicit read-only=on option.

Now that we have auto-read-only=on, enable these drivers to make use of
the option.

This is the only use of bdrv_set_read_only(), so we can make it a bit
more specific and turn it into a bdrv_apply_auto_read_only() that is
more convenient for drivers to use.

Signed-off-by: Kevin Wolf 
---



+++ b/block.c
@@ -266,27 +266,36 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool 
read_only,
  return 0;
  }
  
-/* TODO Remove (deprecated since 2.11)

- * Block drivers are not supposed to automatically change bs->read_only.
- * Instead, they should just check whether they can provide what the user
- * explicitly requested and error out if read-write is requested, but they can
- * only provide read-only access. */
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
+/*
+ * Called by a driver that can only provide a read-only image.
+ *
+ * Returns 0 if the node is already read-only or it could switch the node to
+ * read-only because BDRV_O_AUTO_RDONLY is set.
+ *
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set.
+ * If @errmsg is not NULL, it is used as the error message for the Error
+ * object.


I like it.

Worth documenting the -EINVAL (copy-on-read prevents setting read-only) 
failure as well?  (The -EPERM failure of bdrv_can_set_read_only() is not 
reachable, since this new function never clears readonly).



+ */
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
+  Error **errp)
  {
  int ret = 0;
  
-ret = bdrv_can_set_read_only(bs, read_only, false, errp);

+if (!(bs->open_flags & BDRV_O_RDWR)) {
+return 0;
+}
+if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
+error_setg(errp, "%s", errmsg ?: "Image is read-only");
+return -EACCES;
+}
+
+ret = bdrv_can_set_read_only(bs, true, false, errp);
  if (ret < 0) {
  return ret;
  }


Makes sense.


+++ b/block/vvfat.c
@@ -1262,16 +1262,10 @@ static int vvfat_open(BlockDriverState *bs, QDict 
*options, int flags,
 "Unable to set VVFAT to 'rw' when drive is read-only");
  goto fail;
  }
-} else  if (!bdrv_is_read_only(bs)) {
-error_report("Opening non-rw vvfat images without an explicit "
- "read-only=on option is deprecated. Future versions "
- "will refuse to open the image instead of "
- "automatically marking the image read-only.");
-/* read only is the default for safety */
-ret = bdrv_set_read_only(bs, true, _err);
+} else {
+ret = bdrv_apply_auto_read_only(bs, NULL, errp);
  if (ret < 0) {
-error_propagate(errp, local_err);
-goto fail;
+return ret;


Don't you still need the goto fail, to avoid leaking opts?

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



[Qemu-devel] [PATCH v5 24/28] hw/mips: Update ITU to utilise SAARI/SAAR registers

2018-10-12 Thread Aleksandar Markovic
From: Yongbok Kim 

Update the ITU to utilise SAARI/SAAR registers and add new ITU
Control Register (ICR0).

Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
---
 hw/mips/cps.c  |  8 ++
 hw/misc/mips_itu.c | 72 +-
 include/hw/misc/mips_itu.h |  7 +
 target/mips/cpu.h  |  5 
 target/mips/op_helper.c| 14 +
 5 files changed, 99 insertions(+), 7 deletions(-)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 4285d19..dd68795 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -69,6 +69,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 Error *err = NULL;
 target_ulong gcr_base;
 bool itu_present = false;
+bool saar_present = false;
 
 for (i = 0; i < s->num_vp; i++) {
 cpu = MIPS_CPU(cpu_create(s->cpu_type));
@@ -82,12 +83,14 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 itu_present = true;
 /* Attach ITC Tag to the VP */
 env->itc_tag = mips_itu_get_tag_region(>itu);
+env->itu = >itu;
 }
 qemu_register_reset(main_cpu_reset, cpu);
 }
 
 cpu = MIPS_CPU(first_cpu);
 env = >env;
+saar_present = (bool) env->saarp;
 
 /* Inter-Thread Communication Unit */
 if (itu_present) {
@@ -96,6 +99,11 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
 object_property_set_int(OBJECT(>itu), 16, "num-fifo", );
 object_property_set_int(OBJECT(>itu), 16, "num-semaphores", );
+object_property_set_bool(OBJECT(>itu), saar_present, "saar-present",
+ );
+if (saar_present) {
+qdev_prop_set_ptr(DEVICE(>itu), "saar", (void *) 
>CP0_SAAR);
+}
 object_property_set_bool(OBJECT(>itu), true, "realized", );
 if (err != NULL) {
 error_propagate(errp, err);
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 43bbec4..746e0c2 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -55,9 +55,17 @@ typedef enum ITCView {
 ITCVIEW_EF_SYNC = 2,
 ITCVIEW_EF_TRY  = 3,
 ITCVIEW_PV_SYNC = 4,
-ITCVIEW_PV_TRY  = 5
+ITCVIEW_PV_TRY  = 5,
+ITCVIEW_PV_ICR  = 15
 } ITCView;
 
+#define ITC_ICR0_CELL_NUM   16
+#define ITC_ICR0_BLK_GRAIN  8
+#define ITC_ICR0_BLK_GRAIN_MASK  0x7
+#define ITC_ICR0_ERR_AXI2
+#define ITC_ICR0_ERR_PARITY 1
+#define ITC_ICR0_ERR_EXEC   0
+
 MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu)
 {
 return >tag_io;
@@ -76,7 +84,7 @@ static uint64_t itc_tag_read(void *opaque, hwaddr addr, 
unsigned size)
 return tag->ITCAddressMap[index];
 }
 
-static void itc_reconfigure(MIPSITUState *tag)
+void itc_reconfigure(MIPSITUState *tag)
 {
 uint64_t *am = >ITCAddressMap[0];
 MemoryRegion *mr = >storage_io;
@@ -84,6 +92,12 @@ static void itc_reconfigure(MIPSITUState *tag)
 uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
 bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
 
+if (tag->saar_present) {
+address = ((*(uint64_t *) tag->saar) & 0xE000ULL) << 4;
+size = 1 << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
+is_enabled = *(uint64_t *) tag->saar & 1;
+}
+
 memory_region_transaction_begin();
 if (!(size & (size - 1))) {
 memory_region_set_size(mr, size);
@@ -142,7 +156,12 @@ static inline ITCView get_itc_view(hwaddr addr)
 static inline int get_cell_stride_shift(const MIPSITUState *s)
 {
 /* Minimum interval (for EntryGain = 0) is 128 B */
-return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
+if (s->saar_present) {
+return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
+ITC_ICR0_BLK_GRAIN_MASK);
+} else {
+return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
+}
 }
 
 static inline ITCStorageCell *get_cell(MIPSITUState *s,
@@ -356,6 +375,12 @@ static void view_pv_try_write(ITCStorageCell *c)
 view_pv_common_write(c);
 }
 
+static void raise_exception(int excp)
+{
+current_cpu->exception_index = excp;
+cpu_loop_exit(current_cpu);
+}
+
 static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
 {
 MIPSITUState *s = (MIPSITUState *)opaque;
@@ -363,6 +388,14 @@ static uint64_t itc_storage_read(void *opaque, hwaddr 
addr, unsigned size)
 ITCView view = get_itc_view(addr);
 uint64_t ret = -1;
 
+switch (size) {
+case 1:
+case 2:
+s->icr0 |= 1 << ITC_ICR0_ERR_AXI;
+raise_exception(EXCP_DBE);
+return 0;
+}
+
 switch (view) {
 case ITCVIEW_BYPASS:
 ret = view_bypass_read(cell);
@@ -382,6 +415,9 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, 
unsigned size)
 case ITCVIEW_PV_TRY:
 ret = view_pv_try_read(cell);
 break;
+case ITCVIEW_PV_ICR:
+ret = s->icr0;
+break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   

[Qemu-devel] [PATCH v5 25/28] hw/mips: Add Data Scratch Pad RAM

2018-10-12 Thread Aleksandar Markovic
From: Yongbok Kim 

The optional Data Scratch Pad RAM (DSPRAM) block provides a
general scratch pad RAM used for temporary storage of data. The
DSPRAM provides a connection to on-chip memory or memory-mapped
registers, which are accessed in parallel with the L1 data
cache to minimize access latency.

Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
---
 default-configs/mips-softmmu-common.mak |  1 +
 hw/mips/cps.c   |  3 ++-
 hw/mips/mips_malta.c| 31 +++
 hw/misc/Makefile.objs   |  1 +
 include/hw/mips/cps.h   |  2 ++
 target/mips/cpu.h   |  5 +
 target/mips/internal.h  |  1 +
 target/mips/op_helper.c | 10 ++
 target/mips/translate.c |  7 +++
 9 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/default-configs/mips-softmmu-common.mak 
b/default-configs/mips-softmmu-common.mak
index fae2347..45f2cbf 100644
--- a/default-configs/mips-softmmu-common.mak
+++ b/default-configs/mips-softmmu-common.mak
@@ -36,3 +36,4 @@ CONFIG_EMPTY_SLOT=y
 CONFIG_MIPS_CPS=y
 CONFIG_MIPS_ITU=y
 CONFIG_I2C=y
+CONFIG_MIPS_DSPRAM=y
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index dd68795..93d3bea 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -102,7 +102,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 object_property_set_bool(OBJECT(>itu), saar_present, "saar-present",
  );
 if (saar_present) {
-qdev_prop_set_ptr(DEVICE(>itu), "saar", (void *) 
>CP0_SAAR);
+qdev_prop_set_ptr(DEVICE(>itu), "saar",
+  (void *) >CP0_SAAR[0]);
 }
 object_property_set_bool(OBJECT(>itu), true, "realized", );
 if (err != NULL) {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 29b90ba..1b1bbd8 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1169,6 +1169,36 @@ static void create_cps(MaltaState *s, const char 
*cpu_type,
 *cbus_irq = NULL;
 }
 
+static void create_dspram(void)
+{
+MIPSCPU *cpu = MIPS_CPU(first_cpu);
+CPUMIPSState *env = >env;
+bool dspram_present = (bool) env->dspramp;
+Error *err = NULL;
+
+env->dspram = g_new0(MIPSDSPRAMState, 1);
+
+/* DSPRAM */
+if (dspram_present) {
+if (!(bool) env->saarp) {
+error_report("%s: DSPRAM requires SAAR registers", __func__);
+exit(1);
+}
+object_initialize(env->dspram, sizeof(MIPSDSPRAMState),
+  TYPE_MIPS_DSPRAM);
+qdev_set_parent_bus(DEVICE(env->dspram), sysbus_get_default());
+qdev_prop_set_ptr(DEVICE(env->dspram), "saar",
+  (void *) >CP0_SAAR[1]);
+object_property_set_bool(OBJECT(env->dspram), true, "realized", );
+if (err != NULL) {
+error_report("%s: DSPRAM initialisation failed", __func__);
+exit(1);
+}
+memory_region_add_subregion(get_system_memory(), 0,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(env->dspram), 0));
+}
+}
+
 static void mips_create_cpu(MaltaState *s, const char *cpu_type,
 qemu_irq *cbus_irq, qemu_irq *i8259_irq)
 {
@@ -1177,6 +1207,7 @@ static void mips_create_cpu(MaltaState *s, const char 
*cpu_type,
 } else {
 create_cpu_without_cps(cpu_type, cbus_irq, i8259_irq);
 }
+create_dspram();
 }
 
 static
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 6d50b03..37a1b41 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -60,6 +60,7 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
 obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
 obj-$(CONFIG_MIPS_ITU) += mips_itu.o
+obj-$(CONFIG_MIPS_DSPRAM) += mips_dspram.o
 obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o
 obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
 
diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index aab1af9..a637036 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -25,6 +25,7 @@
 #include "hw/intc/mips_gic.h"
 #include "hw/misc/mips_cpc.h"
 #include "hw/misc/mips_itu.h"
+#include "hw/misc/mips_dspram.h"
 
 #define TYPE_MIPS_CPS "mips-cps"
 #define MIPS_CPS(obj) OBJECT_CHECK(MIPSCPSState, (obj), TYPE_MIPS_CPS)
@@ -41,6 +42,7 @@ typedef struct MIPSCPSState {
 MIPSGICState gic;
 MIPSCPCState cpc;
 MIPSITUState itu;
+MIPSDSPRAMState dspram;
 } MIPSCPSState;
 
 qemu_irq get_cps_irq(MIPSCPSState *cps, int pin_number);
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 9c57878..a2aca3f 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -644,6 +644,7 @@ struct CPUMIPSState {
 uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
 int insn_flags; /* Supported instruction set */
 int saarp;
+int dspramp;
 
 /* Fields up to this point are cleared 

[Qemu-devel] [PATCH v5 23/28] target/mips: Implement emulation of nanoMIPS EVA instructions

2018-10-12 Thread Aleksandar Markovic
From: Dimitrije Nikolic 

Implement emulation of nanoMIPS EVA instructions. They are all
part of P.LS.E0 instruction pool, or one of its subpools.

Signed-off-by: Dimitrije Nikolic 
Signed-off-by: Aleksandar Markovic 
---
 target/mips/translate.c | 128 
 1 file changed, 128 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9e4aae5..7ef8ef0 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1992,6 +1992,35 @@ static inline void check_nms(DisasContext *ctx)
 }
 }
 
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
+ * Config2 TL, and Config5 L2C are unset.
+ */
+static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
+{
+if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
+!(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
+!(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
+!(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
+!(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
+!(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
+{
+generate_exception_end(ctx, EXCP_RI);
+}
+}
+
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 EVA bit is NOT set.
+ */
+static inline void check_eva(DisasContext *ctx)
+{
+if (!unlikely(ctx->CP0_Config5 & (1 << CP0C5_EVA))) {
+generate_exception_end(ctx, EXCP_RI);
+}
+}
+
 
 /* Define small wrappers for gen_load_fpr* so that we have a uniform
calling interface for 32 and 64-bit FPRs.  No sense in changing
@@ -20217,6 +20246,105 @@ static int decode_nanomips_32_48_opc(CPUMIPSState 
*env, DisasContext *ctx)
 break;
 }
 break;
+case NM_P_LS_E0:
+switch (extract32(ctx->opcode, 11, 4)) {
+case NM_LBE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LBE, rt, rs, s);
+break;
+case NM_SBE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SBE, rt, rs, s);
+break;
+case NM_LBUE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LBUE, rt, rs, s);
+break;
+case NM_P_PREFE:
+if (rt == 31) {
+/* case NM_SYNCIE */
+check_eva(ctx);
+check_cp0_enabled(ctx);
+/* Break the TB to be able to sync copied instructions
+   immediately */
+ctx->base.is_jmp = DISAS_STOP;
+} else {
+/* case NM_PREFE */
+check_eva(ctx);
+check_cp0_enabled(ctx);
+/* Treat as NOP. */
+}
+break;
+case NM_LHE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LHE, rt, rs, s);
+break;
+case NM_SHE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SHE, rt, rs, s);
+break;
+case NM_LHUE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LHUE, rt, rs, s);
+break;
+case NM_CACHEE:
+check_nms_dl_il_sl_tl_l2c(ctx);
+gen_cache_operation(ctx, rt, rs, s);
+break;
+case NM_LWE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LWE, rt, rs, s);
+break;
+case NM_SWE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SWE, rt, rs, s);
+break;
+case NM_P_LLE:
+switch (extract32(ctx->opcode, 2, 2)) {
+case NM_LLE:
+check_xnp(ctx);
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LLE, rt, rs, s);
+break;
+case NM_LLWPE:
+check_xnp(ctx);
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+default:
+generate_exception_end(ctx, EXCP_RI);
+break;
+}

[Qemu-devel] [PATCH v5 27/28] target/mips: Add MSA ASE to MIPS64R2-generic CPU

2018-10-12 Thread Aleksandar Markovic
From: Yongbok Kim 

Add MSA ASE to MIPS64R2-generic CPU.

Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
---
 target/mips/translate_init.inc.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index 4c62c50..38c847f 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -620,7 +620,10 @@ const mips_def_t mips_defs[] =
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_MSAP),
+.CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M),
+.CP0_Config4_rw_bitmask = 0,
+.CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn),
 .CP0_LLAddr_rw_bitmask = 0,
 .CP0_LLAddr_shift = 0,
 .SYNCI_Step = 32,
@@ -634,7 +637,7 @@ const mips_def_t mips_defs[] =
 .CP1_fcr31_rw_bitmask = 0xFF83,
 .SEGBITS = 42,
 .PABITS = 36,
-.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
+.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D | ASE_MSA,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
-- 
2.7.4




  1   2   3   >