Re: [PATCH v3 11/11] qapi: Restrict code generated for user-mode

2020-09-30 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> A lot of QAPI generated code is never used by user-mode.
>
> Split out qapi_system_modules and qapi_system_or_tools_modules
> from the qapi_all_modules array. We now have 3 groups:
> - always used
> - use by system-mode or tools (usually by the block layer)
> - only used by system-mode
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> Resetting due to Meson update:
> Reviewed-by: Richard Henderson 
> ---
>  qapi/meson.build | 51 ++--
>  1 file changed, 36 insertions(+), 15 deletions(-)
>
> diff --git a/qapi/meson.build b/qapi/meson.build
> index 7c4a89a882..ba9677ba97 100644
> --- a/qapi/meson.build
> +++ b/qapi/meson.build
> @@ -14,39 +14,60 @@ util_ss.add(files(
>  ))
>  
>  qapi_all_modules = [
> +  'common',
> +  'introspect',
> +  'misc',
> +]
> +
> +qapi_system_modules = [
>'acpi',
>'audio',
> +  'dump',
> +  'machine-target',
> +  'machine',
> +  'migration',
> +  'misc-target',
> +  'net',
> +  'pci',
> +  'qdev',
> +  'rdma',
> +  'rocker',
> +  'tpm',
> +  'trace',
> +]
> +
> +# system or tools
> +qapi_block_modules = [
>'authz',
>'block-core',
>'block',
>'char',
> -  'common',
>'control',
>'crypto',
> -  'dump',
>'error',
> -  'introspect',
>'job',
> -  'machine',
> -  'machine-target',
> -  'migration',
> -  'misc',
> -  'misc-target',
> -  'net',
>'pragma',
> -  'qdev',
> -  'pci',
>'qom',
> -  'rdma',
> -  'rocker',
>'run-state',
>'sockets',
> -  'tpm',
> -  'trace',
>'transaction',
>'ui',
>  ]

Most of these aren't "block modules".  Name the thing
qapi_system_or_tools_modules?

> +if have_system
> +  qapi_all_modules += qapi_system_modules
> +elif have_user
> +  # Temporary kludge because X86CPUFeatureWordInfo is not
> +  # restricted to system-mode. This should be removed (along
> +  # with target/i386/feature-stub.c) once target/i386/cpu.c
> +  # has been cleaned.
> +  qapi_all_modules += ['machine-target']
> +endif
> +
> +if have_block

Aha, precedence for using "block" as an abbreviation of "system or
tools".  I find that confusing.

> +  qapi_all_modules += qapi_block_modules
> +endif
> +
>  qapi_storage_daemon_modules = [
>'block-core',
>'char',




Re: [PATCH v3 01/11] qapi: Restrict query-uuid command to block code

2020-09-30 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> In commit f68c01470b we restricted the query-uuid command to
> machine code, but it is incorrect, as it is also used by the
> tools.  Therefore move this command again, but to block.json,
> which is shared by machine code and tools.
>
> Fixes: f68c01470b ("qapi: Restrict query-uuid command to machine code")
>
> Signed-off-by: Philippe Mathieu-Daudé 

UUIDs are not really a block-specific thing.

QMP query-uuid and HMP info uuid are about the VM, like query-name.
That's why they used to be next to query-name in misc.json.

There's one additional use in block/iscsi.c's get_initiator_name().  I
figure that's what pulls it into tools via qemu-img.

Which other QAPI modules are shared by all the executables that use it?

What about reverting the commit?  How bad would that be for user mode?




[PATCH] MAINTAINERS: Ignore bios-tables-test in the qtest section

2020-09-30 Thread Thomas Huth
I'm very often getting CC: on rather large patch series that
modify the ACPI stuff of either ARM or x86, just because the
bios-table-test is often slightly involved here. I can't say
much about ACPI, and the bios-table-test is already covered
by the ACPI section in MAINTAINERS, so I'd rather prefer to
not getting automatically CC-ed on such patch series anymore.
If people want my opinion about qtest-related changes, they
can still put me on CC manually.

Signed-off-by: Thomas Huth 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e1e8ae277d..d476fbf627 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2474,7 +2474,7 @@ S: Maintained
 F: softmmu/qtest.c
 F: accel/qtest.c
 F: tests/qtest/
-X: tests/qtest/bios-tables-test-allowed-diff.h
+X: tests/qtest/bios-tables-test*
 
 Device Fuzzing
 M: Alexander Bulekov 
-- 
2.18.2




Re: [PATCH 5/9] hw/block/nvme: support for admin-only command set

2020-09-30 Thread Klaus Jensen
On Sep 30 15:04, Keith Busch wrote:
> Signed-off-by: Keith Busch 
> ---

Reviewed-by: Klaus Jensen 

>  hw/block/nvme.c  | 1 +
>  include/block/nvme.h | 3 ++-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 6c582e6874..ec7363ea40 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -2755,6 +2755,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> *pci_dev)
>  NVME_CAP_SET_CQR(n->bar.cap, 1);
>  NVME_CAP_SET_TO(n->bar.cap, 0xf);
>  NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
> +NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_ADMIN_ONLY);
>  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
>  
>  n->bar.vs = NVME_SPEC_VER;
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index bc20a2ba5e..521533fd2a 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -83,7 +83,8 @@ enum NvmeCapMask {
>  << CAP_PMR_SHIFT)
>  
>  enum NvmeCapCss {
> -NVME_CAP_CSS_NVM = 1 << 0,
> +NVME_CAP_CSS_NVM= 1 << 0,
> +NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
>  };
>  
>  enum NvmeCcShift {
> -- 
> 2.24.1
> 
> 

-- 
One of us - No more doubt, silence or taboo about mental illness.


signature.asc
Description: PGP signature


Re: [PATCH 4/9] hw/block/nvme: validate command set selected

2020-09-30 Thread Klaus Jensen
On Sep 30 15:04, Keith Busch wrote:
> Fail to start the controller if the user requests a command set that the
> controller does not support.
> 
> Signed-off-by: Keith Busch 

Reviewed-by: Klaus Jensen 

> ---
>  hw/block/nvme.c   | 6 +-
>  hw/block/trace-events | 1 +
>  include/block/nvme.h  | 4 
>  3 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 41389b2b09..6c582e6874 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -2049,6 +2049,10 @@ static int nvme_start_ctrl(NvmeCtrl *n)
>  trace_pci_nvme_err_startfail_acq_misaligned(n->bar.acq);
>  return -1;
>  }
> +if (unlikely(!(NVME_CAP_CSS(n->bar.cap) & (1 << 
> NVME_CC_CSS(n->bar.cc) {
> +trace_pci_nvme_err_startfail_css(NVME_CC_CSS(n->bar.cc));
> +return -1;
> +}
>  if (unlikely(NVME_CC_MPS(n->bar.cc) <
>   NVME_CAP_MPSMIN(n->bar.cap))) {
>  trace_pci_nvme_err_startfail_page_too_small(
> @@ -2750,7 +2754,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> *pci_dev)
>  NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
>  NVME_CAP_SET_CQR(n->bar.cap, 1);
>  NVME_CAP_SET_TO(n->bar.cap, 0xf);
> -NVME_CAP_SET_CSS(n->bar.cap, 1);
> +NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
>  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
>  
>  n->bar.vs = NVME_SPEC_VER;
> diff --git a/hw/block/trace-events b/hw/block/trace-events
> index 446cca08e9..7720e1b4d9 100644
> --- a/hw/block/trace-events
> +++ b/hw/block/trace-events
> @@ -133,6 +133,7 @@ pci_nvme_err_startfail_cqent_too_small(uint8_t log2ps, 
> uint8_t maxlog2ps) "nvme_
>  pci_nvme_err_startfail_cqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) 
> "nvme_start_ctrl failed because the completion queue entry size is too large: 
> log2size=%u, max=%u"
>  pci_nvme_err_startfail_sqent_too_small(uint8_t log2ps, uint8_t maxlog2ps) 
> "nvme_start_ctrl failed because the submission queue entry size is too small: 
> log2size=%u, min=%u"
>  pci_nvme_err_startfail_sqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) 
> "nvme_start_ctrl failed because the submission queue entry size is too large: 
> log2size=%u, max=%u"
> +pci_nvme_err_startfail_css(uint8_t css) "nvme_start_ctrl failed because 
> invalid command set selected:%u"
>  pci_nvme_err_startfail_asqent_sz_zero(void) "nvme_start_ctrl failed because 
> the admin submission queue size is zero"
>  pci_nvme_err_startfail_acqent_sz_zero(void) "nvme_start_ctrl failed because 
> the admin completion queue size is zero"
>  pci_nvme_err_startfail(void) "setting controller enable bit failed"
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index 868cf53f0b..bc20a2ba5e 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -82,6 +82,10 @@ enum NvmeCapMask {
>  #define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
>  << CAP_PMR_SHIFT)
>  
> +enum NvmeCapCss {
> +NVME_CAP_CSS_NVM = 1 << 0,
> +};
> +
>  enum NvmeCcShift {
>  CC_EN_SHIFT = 0,
>  CC_CSS_SHIFT= 4,
> -- 
> 2.24.1
> 
> 

-- 
One of us - No more doubt, silence or taboo about mental illness.


signature.asc
Description: PGP signature


Re: [PATCH 3/9] hw/block/nvme: support per-namespace smart log

2020-09-30 Thread Klaus Jensen
On Sep 30 15:04, Keith Busch wrote:
> Let the user specify a specific namespace if they want to get access
> stats for a specific namespace.
> 

I don't think this makes sense for v1.3+.

NVM Express v1.3d, Section 5.14.1.2: "There is no namespace specific
information defined in the SMART / Health log page in this revision of
the specification.  therefore the controller log page and namespace
specific log page contain identical information".

I have no idea why the TWG decided this, but that's the way it is ;)

> Signed-off-by: Keith Busch 
> ---
>  hw/block/nvme.c  | 66 +++-
>  include/block/nvme.h |  1 +
>  2 files changed, 41 insertions(+), 26 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 8d2b5be567..41389b2b09 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -1164,48 +1164,62 @@ static uint16_t nvme_create_sq(NvmeCtrl *n, 
> NvmeRequest *req)
>  return NVME_SUCCESS;
>  }
>  
> +struct nvme_stats {
> +uint64_t units_read;
> +uint64_t units_written;
> +uint64_t read_commands;
> +uint64_t write_commands;
> +};
> +
> +static void nvme_set_blk_stats(NvmeNamespace *ns, struct nvme_stats *stats)
> +{
> +BlockAcctStats *s = blk_get_stats(ns->blkconf.blk);
> +
> +stats->units_read += s->nr_bytes[BLOCK_ACCT_READ] >> BDRV_SECTOR_BITS;
> +stats->units_written += s->nr_bytes[BLOCK_ACCT_WRITE] >> 
> BDRV_SECTOR_BITS;
> +stats->read_commands += s->nr_ops[BLOCK_ACCT_READ];
> +stats->write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
> +}
> +
>  static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
>  uint64_t off, NvmeRequest *req)
>  {
>  uint32_t nsid = le32_to_cpu(req->cmd.nsid);
> -
> +struct nvme_stats stats = { 0 };
> +NvmeSmartLog smart = { 0 };
>  uint32_t trans_len;
> +NvmeNamespace *ns;
>  time_t current_ms;
> -uint64_t units_read = 0, units_written = 0;
> -uint64_t read_commands = 0, write_commands = 0;
> -NvmeSmartLog smart;
> -
> -if (nsid && nsid != 0x) {
> -return NVME_INVALID_FIELD | NVME_DNR;
> -}
>  
>  if (off >= sizeof(smart)) {
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
>  
> -for (int i = 1; i <= n->num_namespaces; i++) {
> -NvmeNamespace *ns = nvme_ns(n, i);
> -if (!ns) {
> -continue;
> -}
> -
> -BlockAcctStats *s = blk_get_stats(ns->blkconf.blk);
> +if (nsid != 0x) {
> +ns = nvme_ns(n, nsid);
> +if (!ns)
> +return NVME_INVALID_NSID | NVME_DNR;
> +nvme_set_blk_stats(ns, );
> +} else {
> +int i;
>  
> -units_read += s->nr_bytes[BLOCK_ACCT_READ] >> BDRV_SECTOR_BITS;
> -units_written += s->nr_bytes[BLOCK_ACCT_WRITE] >> BDRV_SECTOR_BITS;
> -read_commands += s->nr_ops[BLOCK_ACCT_READ];
> -write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
> +for (i = 1; i <= n->num_namespaces; i++) {
> +ns = nvme_ns(n, i);
> +if (!ns) {
> +continue;
> +}
> +nvme_set_blk_stats(ns, );
> +}
>  }
>  
>  trans_len = MIN(sizeof(smart) - off, buf_len);
>  
> -memset(, 0x0, sizeof(smart));
> -
> -smart.data_units_read[0] = cpu_to_le64(DIV_ROUND_UP(units_read, 1000));
> -smart.data_units_written[0] = cpu_to_le64(DIV_ROUND_UP(units_written,
> +smart.data_units_read[0] = cpu_to_le64(DIV_ROUND_UP(stats.units_read,
> +1000));
> +smart.data_units_written[0] = 
> cpu_to_le64(DIV_ROUND_UP(stats.units_written,
> 1000));
> -smart.host_read_commands[0] = cpu_to_le64(read_commands);
> -smart.host_write_commands[0] = cpu_to_le64(write_commands);
> +smart.host_read_commands[0] = cpu_to_le64(stats.read_commands);
> +smart.host_write_commands[0] = cpu_to_le64(stats.write_commands);
>  
>  smart.temperature = cpu_to_le16(n->temperature);
>  
> @@ -2708,7 +2722,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> *pci_dev)
>  id->acl = 3;
>  id->aerl = n->params.aerl;
>  id->frmw = (NVME_NUM_FW_SLOTS << 1) | NVME_FRMW_SLOT1_RO;
> -id->lpa = NVME_LPA_EXTENDED;
> +id->lpa = NVME_LPA_NS_SMART | NVME_LPA_EXTENDED;
>  
>  /* recommended default value (~70 C) */
>  id->wctemp = cpu_to_le16(NVME_TEMPERATURE_WARNING);
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index 58647bcdad..868cf53f0b 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -849,6 +849,7 @@ enum NvmeIdCtrlFrmw {
>  };
>  
>  enum NvmeIdCtrlLpa {
> +NVME_LPA_NS_SMART = 1 << 0,
>  NVME_LPA_EXTENDED = 1 << 2,
>  };
>  
> -- 
> 2.24.1
> 
> 

-- 
One of us - No more doubt, silence or taboo about mental illness.


signature.asc
Description: PGP signature


Re: [PATCH 1/9] hw/block/nvme: remove pointless rw indirection

2020-09-30 Thread Klaus Jensen
On Sep 30 15:04, Keith Busch wrote:
> The code switches on the opcode to invoke a function specific to that
> opcode. There's no point in consolidating back to a common function that
> just switches on that same opcode without any actual common code.
> Restore the opcode specific behavior without going back through another
> level of switches.
> 
> Signed-off-by: Keith Busch 

Reviewed-by: Klaus Jensen 

Point taken. I could've sweared I had a better reason for this.

> ---
>  hw/block/nvme.c | 91 -
>  1 file changed, 29 insertions(+), 62 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index da8344f196..db52ea0db9 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -927,68 +927,12 @@ static void nvme_rw_cb(void *opaque, int ret)
>  nvme_enqueue_req_completion(nvme_cq(req), req);
>  }
>  
> -static uint16_t nvme_do_aio(BlockBackend *blk, int64_t offset, size_t len,
> -NvmeRequest *req)
> -{
> -BlockAcctCookie *acct = >acct;
> -BlockAcctStats *stats = blk_get_stats(blk);
> -
> -bool is_write = false;
> -
> -trace_pci_nvme_do_aio(nvme_cid(req), req->cmd.opcode,
> -  nvme_io_opc_str(req->cmd.opcode), blk_name(blk),
> -  offset, len);
> -
> -switch (req->cmd.opcode) {
> -case NVME_CMD_FLUSH:
> -block_acct_start(stats, acct, 0, BLOCK_ACCT_FLUSH);
> -req->aiocb = blk_aio_flush(blk, nvme_rw_cb, req);
> -break;
> -
> -case NVME_CMD_WRITE_ZEROES:
> -block_acct_start(stats, acct, len, BLOCK_ACCT_WRITE);
> -req->aiocb = blk_aio_pwrite_zeroes(blk, offset, len,
> -   BDRV_REQ_MAY_UNMAP, nvme_rw_cb,
> -   req);
> -break;
> -
> -case NVME_CMD_WRITE:
> -is_write = true;
> -
> -/* fallthrough */
> -
> -case NVME_CMD_READ:
> -block_acct_start(stats, acct, len,
> - is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
> -
> -if (req->qsg.sg) {
> -if (is_write) {
> -req->aiocb = dma_blk_write(blk, >qsg, offset,
> -   BDRV_SECTOR_SIZE, nvme_rw_cb, 
> req);
> -} else {
> -req->aiocb = dma_blk_read(blk, >qsg, offset,
> -  BDRV_SECTOR_SIZE, nvme_rw_cb, req);
> -}
> -} else {
> -if (is_write) {
> -req->aiocb = blk_aio_pwritev(blk, offset, >iov, 0,
> - nvme_rw_cb, req);
> -} else {
> -req->aiocb = blk_aio_preadv(blk, offset, >iov, 0,
> -nvme_rw_cb, req);
> -}
> -}
> -
> -break;
> -}
> -
> -return NVME_NO_COMPLETE;
> -}
> -
>  static uint16_t nvme_flush(NvmeCtrl *n, NvmeRequest *req)
>  {
> -NvmeNamespace *ns = req->ns;
> -return nvme_do_aio(ns->blkconf.blk, 0, 0, req);
> +block_acct_start(blk_get_stats(n->conf.blk), >acct, 0,
> + BLOCK_ACCT_FLUSH);
> +req->aiocb = blk_aio_flush(n->conf.blk, nvme_rw_cb, req);
> +return NVME_NO_COMPLETE;
>  }
>  
>  static uint16_t nvme_write_zeroes(NvmeCtrl *n, NvmeRequest *req)
> @@ -1009,7 +953,11 @@ static uint16_t nvme_write_zeroes(NvmeCtrl *n, 
> NvmeRequest *req)
>  return status;
>  }
>  
> -return nvme_do_aio(ns->blkconf.blk, offset, count, req);
> +block_acct_start(blk_get_stats(n->conf.blk), >acct, 0,
> + BLOCK_ACCT_WRITE);
> +req->aiocb = blk_aio_pwrite_zeroes(n->conf.blk, offset, count,
> +   BDRV_REQ_MAY_UNMAP, nvme_rw_cb, req);
> +return NVME_NO_COMPLETE;
>  }
>  
>  static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
> @@ -1023,6 +971,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
>  uint64_t data_offset = nvme_l2b(ns, slba);
>  enum BlockAcctType acct = req->cmd.opcode == NVME_CMD_WRITE ?
>  BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
> +BlockBackend *blk = ns->blkconf.blk;
>  uint16_t status;
>  
>  trace_pci_nvme_rw(nvme_cid(req), nvme_io_opc_str(rw->opcode),
> @@ -1045,7 +994,25 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
>  goto invalid;
>  }
>  
> -return nvme_do_aio(ns->blkconf.blk, data_offset, data_size, req);
> +block_acct_start(blk_get_stats(blk), >acct, data_size, acct);
> +if (req->qsg.sg) {
> +if (acct == BLOCK_ACCT_WRITE) {
> +req->aiocb = dma_blk_write(blk, >qsg, data_offset,
> +   BDRV_SECTOR_SIZE, nvme_rw_cb, req);
> +} else {
> +req->aiocb = dma_blk_read(blk, >qsg, data_offset,
> +  BDRV_SECTOR_SIZE, nvme_rw_cb, req);
> +}
> +} else {
> +if (acct == 

Re: [PATCH 2/9] hw/block/nvme: fix log page offset check

2020-09-30 Thread Klaus Jensen
On Sep 30 15:04, Keith Busch wrote:
> Return error if the requested offset starts after the size of the log
> being returned. Also, move the check for earlier in the function so
> we're not doing unnecessary calculations.
> 
> Signed-off-by: Keith Busch 

Reviewed-by: Klaus Jensen 

> ---
>  hw/block/nvme.c | 22 ++
>  1 file changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index db52ea0db9..8d2b5be567 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -1179,6 +1179,10 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t 
> rae, uint32_t buf_len,
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
>  
> +if (off >= sizeof(smart)) {
> +return NVME_INVALID_FIELD | NVME_DNR;
> +}
> +
>  for (int i = 1; i <= n->num_namespaces; i++) {
>  NvmeNamespace *ns = nvme_ns(n, i);
>  if (!ns) {
> @@ -1193,10 +1197,6 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t 
> rae, uint32_t buf_len,
>  write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
>  }
>  
> -if (off > sizeof(smart)) {
> -return NVME_INVALID_FIELD | NVME_DNR;
> -}
> -
>  trans_len = MIN(sizeof(smart) - off, buf_len);
>  
>  memset(, 0x0, sizeof(smart));
> @@ -1234,12 +1234,11 @@ static uint16_t nvme_fw_log_info(NvmeCtrl *n, 
> uint32_t buf_len, uint64_t off,
>  .afi = 0x1,
>  };
>  
> -strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
> -
> -if (off > sizeof(fw_log)) {
> +if (off >= sizeof(fw_log)) {
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
>  
> +strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
>  trans_len = MIN(sizeof(fw_log) - off, buf_len);
>  
>  return nvme_dma(n, (uint8_t *) _log + off, trans_len,
> @@ -1252,16 +1251,15 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t 
> rae, uint32_t buf_len,
>  uint32_t trans_len;
>  NvmeErrorLog errlog;
>  
> -if (!rae) {
> -nvme_clear_events(n, NVME_AER_TYPE_ERROR);
> +if (off >= sizeof(errlog)) {
> +return NVME_INVALID_FIELD | NVME_DNR;
>  }
>  
> -if (off > sizeof(errlog)) {
> -return NVME_INVALID_FIELD | NVME_DNR;
> +if (!rae) {
> +nvme_clear_events(n, NVME_AER_TYPE_ERROR);
>  }
>  
>  memset(, 0x0, sizeof(errlog));
> -
>  trans_len = MIN(sizeof(errlog) - off, buf_len);
>  
>  return nvme_dma(n, (uint8_t *), trans_len,
> -- 
> 2.24.1
> 
> 

-- 
One of us - No more doubt, silence or taboo about mental illness.


signature.asc
Description: PGP signature


[PATCH v1 1/1] sheepdog driver patch: fixs the problem of qemu process become crashed when the sheepdog gateway break the IO and then recover

2020-09-30 Thread mingwei
this patch fixs the problem of qemu process become crashed when the sheepdog 
gateway break the IO for a few seconds and then recover.

problem reproduce:
1.start a fio process in qemu to produce IOs to sheepdog gateway, whatever IO 
type you like.
2.kill the sheepdog gateway.
3.wait for a few seconds.
4.restart the sheepdog gateway.
5.qemu process crashed with segfault error 6.

problem cause:
the last io coroutine will be destroyed after reconnect to sheepdog gateway, 
but the coroutine still be scheduled and the s->co_recv is still the last io 
coroutine pointer which had been destroyed, so when this coroutine go to 
coroutine context switch, it will make qemu process crashed.

problem fix:
just make s->co_recv = NULL when the last io coroutine reconnect to sheepdog 
gateway.

Signed-off-by: mingwei 
---
 block/sheepdog.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 2f5c0eb376..3a00f0c1e1 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -727,6 +727,7 @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
NULL, NULL, NULL);
 close(s->fd);
 s->fd = -1;
+s->co_recv = NULL;
 
 /* Wait for outstanding write requests to be completed. */
 while (s->co_send != NULL) {
-- 
2.25.1





Re: [PATCH] configure: actually disable 'git_update' mode with --disable-git-update

2020-09-30 Thread Dan Streetman
On Tue, Sep 22, 2020 at 12:34 PM Daniel P. Berrangé  wrote:
>
> On Wed, Jul 29, 2020 at 03:58:29PM -0400, Dan Streetman wrote:
> > The --disable-git-update configure param sets git_update=no, but
> > some later checks only look for the .git dir. This changes the
> > --enable-git-update to set git_update=yes but also fail if it
> > does not find a .git dir. Then all the later checks for the .git
> > dir can just be changed to a check for $git_update = "yes".
> >
> > Also update the Makefile to skip the 'git_update' checks if it has
> > been disabled.
> >
> > This is needed because downstream packagers, e.g. Debian, Ubuntu, etc,
> > also keep the source code in git, but do not want to enable the
> > 'git_update' mode; with the current code, that's not possible even
> > if the downstream package specifies --disable-git-update.
>
> Lets recap the original intended behaviour
>
>  1. User building from master qemu.git or a fork
>  a) git_update=yes (default)
>  - Always sync submodules to required commit
>
>  b) git_update=no  (--disable-git-update)
>  - Never sync submodules, user is responsible for sync
>  - Validate submodules are at correct commit and fail if not.
>
>  2. User building from tarball
>  - Never do anything git related at all
>
>
> Your change is removing the validation from  1.b).

Would you accept adding a --disable-git-submodules-check so downstream
packagers can keep the source in git, but avoid the submodule
validation?
Or do you have another suggestion for handling this?

Michael, Christian, do you have any suggestions or preference for how
this should be handled in Debian and Ubuntu?

> This is not desirable
> in general, because if a user has done a git pull and failed to sync the
> submodules, they are liable to get obscure, hard to diagnose errors later
> in the build process. This puts a burden on the user and maintainers who
> have to waste time diagnosing such problems.

Yep, this problem causes the same obscure, hard to diagnose errors
later in the build with downstream packages, but only if the .git dir
is present, because the build process is subtly changed in that case.

>
>
>
> > Signed-off-by: Dan Streetman 
> > ---
> > Note this is a rebased resend of a previous email to qemu-trivial:
> > https://lists.nongnu.org/archive/html/qemu-trivial/2020-07/msg00180.html
>
> NB, I'm removing qemu-trivial, because I don't think this patch
> qualifies as trivial.
>
>
> >
> >  Makefile  | 15 +--
> >  configure | 21 +
> >  2 files changed, 22 insertions(+), 14 deletions(-)
> >
> > diff --git a/Makefile b/Makefile
> > index c2120d8d48..42550ae086 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -25,6 +25,8 @@ git-submodule-update:
> >
> >  .PHONY: git-submodule-update
> >
> > +# If --disable-git-update specified, skip these git checks
> > +ifneq (no,$(GIT_UPDATE))
> >  git_module_status := $(shell \
> >cd '$(SRC_PATH)' && \
> >GIT="$(GIT)" ./scripts/git-submodule.sh status $(GIT_SUBMODULES); \
> > @@ -32,7 +34,12 @@ git_module_status := $(shell \
> >  )
> >
> >  ifeq (1,$(git_module_status))
> > -ifeq (no,$(GIT_UPDATE))
> > +ifeq (yes,$(GIT_UPDATE))
> > +git-submodule-update:
> > + $(call quiet-command, \
> > +  (cd $(SRC_PATH) && GIT="$(GIT)" ./scripts/git-submodule.sh 
> > update $(GIT_SUBMODULES)), \
> > +  "GIT","$(GIT_SUBMODULES)")
> > +else
> >  git-submodule-update:
> >   $(call quiet-command, \
> >  echo && \
> > @@ -41,11 +48,7 @@ git-submodule-update:
> >  echo "from the source directory checkout $(SRC_PATH)" && \
> >  echo && \
> >  exit 1)
> > -else
> > -git-submodule-update:
> > - $(call quiet-command, \
> > -  (cd $(SRC_PATH) && GIT="$(GIT)" ./scripts/git-submodule.sh 
> > update $(GIT_SUBMODULES)), \
> > -  "GIT","$(GIT_SUBMODULES)")
> > +endif
> >  endif
> >  endif
> >
> > diff --git a/configure b/configure
> > index 2acc4d1465..e7a241e971 100755
> > --- a/configure
> > +++ b/configure
> > @@ -318,7 +318,7 @@ then
> >  git_submodules="$git_submodules tests/fp/berkeley-testfloat-3"
> >  git_submodules="$git_submodules tests/fp/berkeley-softfloat-3"
> >  else
> > -git_update=no
> > +git_update=""
> >  git_submodules=""
> >
> >  if ! test -f "$source_path/ui/keycodemapdb/README"
> > @@ -1598,7 +1598,12 @@ for opt do
> >;;
> >--with-git=*) git="$optarg"
> >;;
> > -  --enable-git-update) git_update=yes
> > +  --enable-git-update)
> > +  git_update=yes
> > +  if test ! -e "$source_path/.git"; then
> > +  echo "ERROR: cannot --enable-git-update without .git"
> > +  exit 1
> > +  fi
> >;;
> >--disable-git-update) git_update=no
> >;;
> > @@ -2011,7 +2016,7 @@ fi
> >  # Consult white-list to determine whether to enable werror
> >  # by default.  Only enable by default for git builds
> >  if test -z "$werror" ; then
> > -if test -e 

Re: [PATCH] hw/arm/aspeed: Map the UART5 device unconditionally

2020-09-30 Thread Andrew Jeffery



On Wed, 30 Sep 2020, at 19:37, Cédric Le Goater wrote:
> On 9/30/20 7:29 AM, Andrew Jeffery wrote:
> > 
> > 
> > On Fri, 18 Sep 2020, at 02:33, Cédric Le Goater wrote:
> >> On 9/17/20 6:57 PM, Philippe Mathieu-Daudé wrote:
> >>> On 9/16/20 7:51 AM, Cédric Le Goater wrote:
>  On 9/15/20 7:23 PM, Philippe Mathieu-Daudé wrote:
> > ping?
> 
>  It's reviewed : 
> 
>    
>  http://patchwork.ozlabs.org/project/qemu-devel/patch/20200905212415.760452-1-f4...@amsat.org/
> 
> >>>
> >>> Yes I know :) This is part of my routine to check if a
> >>> patch hasn't been confirmed to be queued 1 week after the
> >>> last review, to ping the maintainer (because some
> >>> automatically flush patches older than 1month in their
> >>> mailbox).
> >>
> >> ooh. That's brutal.
> >>
>  I will send a PR when I have more patches.
> >>>
> >>> Ah OK. I didn't know you would keep merging the Aspeed
> >>> patches. Since this was a single patch, I thought it would
> >>> go via the usual qemu-arm queue from Peter.
> >>
> >> sure. It could also. Fine with me. I have only three for the
> >> moment. 
> >>
> >>> No rush, I just wanted to be sure the patch was not lost.
> >>> Also, once a patch is queued, I understand it is the
> >>> maintainer responsibility to keep rebasing the patch
> >>> queued.
> >>
> >> yes. I know. I have been taking care of Andrew's ADC patches 
> >> since 2017 ... cough cough :)
> > 
> > Agh!
> 
> Does that mean "I will work on it !" ? :)

I'll see what I can do, I've recently started to rearrange my task queue.

Andrew



Re: [PATCH] target/riscv: raise exception to HS-mode at get_physical_address

2020-09-30 Thread Alistair Francis
On Sun, Sep 27, 2020 at 12:54 AM Jiangyifei  wrote:
>
>
>
> > -Original Message-
> > From: Alistair Francis [mailto:alistai...@gmail.com]
> > Sent: Saturday, September 26, 2020 6:24 AM
> > To: Jiangyifei 
> > Cc: qemu-devel@nongnu.org Developers ; open
> > list:RISC-V ; Zhanghailiang
> > ; Sagar Karandikar
> > ; Bastian Koppelmann
> > ; Zhangxiaofeng (F)
> > ; Alistair Francis
> > ; yinyipeng ; Palmer
> > Dabbelt ; Wubin (H) ;
> > dengkai (A) 
> > Subject: Re: [PATCH] target/riscv: raise exception to HS-mode at
> > get_physical_address
> >
> > On Mon, Aug 24, 2020 at 1:43 AM Yifei Jiang  wrote:
> > >
> > > VS-stage translation at get_physical_address needs to translate pte
> > > address by G-stage translation. But the G-stage translation error can
> > > not be distinguished from VS-stage translation error in
> > > riscv_cpu_tlb_fill. On migration, destination needs to rebuild pte,
> > > and this G-stage translation error must be handled by HS-mode. So
> > > introduce TRANSLATE_STAGE2_FAIL so that riscv_cpu_tlb_fill could
> > > distinguish and raise it to HS-mode.
> > >
> > > Signed-off-by: Yifei Jiang 
> > > Signed-off-by: Yipeng Yin 
> >
> > Thanks for the patch!
> >
> > Sorry for the delay here.
> >
> > > ---
> > >  target/riscv/cpu.h|  1 +
> > >  target/riscv/cpu_helper.c | 12 ++--
> > >  2 files changed, 11 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index
> > > a804a5d0ba..8b3b368d6a 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -85,6 +85,7 @@ enum {
> > >  #define TRANSLATE_FAIL 1
> > >  #define TRANSLATE_SUCCESS 0
> > >  #define MMU_USER_IDX 3
> > > +#define TRANSLATE_G_STAGE_FAIL 4
> > >
> > >  #define MAX_RISCV_PMPS (16)
> > >
> > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > > index fd1d373b6f..1635b09c41 100644
> > > --- a/target/riscv/cpu_helper.c
> > > +++ b/target/riscv/cpu_helper.c
> > > @@ -440,7 +440,10 @@ restart:
> > >   mmu_idx,
> > false,
> > > true);
> > >
> > >  if (vbase_ret != TRANSLATE_SUCCESS) {
> > > -return vbase_ret;
> > > +env->guest_phys_fault_addr = (base |
> > > +  (addr &
> > > +
> > (TARGET_PAGE_SIZE -
> > > + 1))) >> 2;
> >
> > Can we set guest_phys_fault_addr in riscv_cpu_tlb_fill() instead?
>
> Hi Alistair,
>
> It's not easy to do that. The key is that the wrong address(the `base` 
> variable) is not visible to riscv_cpu_tlb_fill().
> Because the wrong address may be from any level of PTE which can't be easily 
> obtained by riscv_cpu_tlb_fill().
> The alternative is to add an out parameter in get_physical_address(). But it 
> is not either elegant.
> What is your advice?

You are right. Good call.

In which case this looks like the right way to do this. Can you add a
small comment in riscv_cpu_tlb_fill() to indicate that
guest_phys_fault_addr has already been set when handling the error?
The TLB filling code is pretty complex so the more documentation the
better.

Alistair

>
> Best Regards,
> Yifei
>
> >
> > > +return TRANSLATE_G_STAGE_FAIL;
> > >  }
> > >
> > >  pte_addr = vbase + idx * ptesize; @@ -728,12 +731,17 @@
> > > bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> > >  ret = get_physical_address(env, , , address,
> > access_type,
> > > mmu_idx, true, true);
> > >
> > > +if (ret == TRANSLATE_G_STAGE_FAIL) {
> > > +first_stage_error = false;
> > > +access_type = MMU_DATA_LOAD;
> > > +}
> > > +
> > >  qemu_log_mask(CPU_LOG_MMU,
> > >"%s 1st-stage address=%" VADDR_PRIx "
> > ret %d physical "
> > >TARGET_FMT_plx " prot %d\n",
> > >__func__, address, ret, pa, prot);
> > >
> > > -if (ret != TRANSLATE_FAIL) {
> > > +if (ret != TRANSLATE_FAIL && ret != TRANSLATE_G_STAGE_FAIL) {
> >
> > Otherwise this patch looks correct.
> >
> > Alistair
> >
> > >  /* Second stage lookup */
> > >  im_address = pa;
> > >
> > > --
> > > 2.19.1
> > >
> > >
> > >



RE: [PATCH 5/9] hw/block/nvme: support for admin-only command set

2020-09-30 Thread Dmitry Fomichev
> -Original Message-
> From: Keith Busch 
> Sent: Wednesday, September 30, 2020 6:04 PM
> To: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Klaus Jensen
> 
> Cc: Niklas Cassel ; Dmitry Fomichev
> ; Kevin Wolf ; Philippe
> Mathieu-Daudé ; Keith Busch 
> Subject: [PATCH 5/9] hw/block/nvme: support for admin-only command set
> 
> Signed-off-by: Keith Busch 
> ---
>  hw/block/nvme.c  | 1 +
>  include/block/nvme.h | 3 ++-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 6c582e6874..ec7363ea40 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -2755,6 +2755,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice
> *pci_dev)
>  NVME_CAP_SET_CQR(n->bar.cap, 1);
>  NVME_CAP_SET_TO(n->bar.cap, 0xf);
>  NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
> +NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_ADMIN_ONLY);

This could be

- NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
+NVME_CAP_SET_CSS(n->bar.cap, (NVME_CAP_CSS_NVM  | 
NVME_CAP_CSS_ADMIN_ONLY));

Unfortunately, parentheses are needed above because NVME_CAP_SET_CSS macro and
other similar macros use "val" instead of (val). A possible cleanup topic...

>  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
> 
>  n->bar.vs = NVME_SPEC_VER;
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index bc20a2ba5e..521533fd2a 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -83,7 +83,8 @@ enum NvmeCapMask {
>  << CAP_PMR_SHIFT)
> 
>  enum NvmeCapCss {
> -NVME_CAP_CSS_NVM = 1 << 0,
> +NVME_CAP_CSS_NVM= 1 << 0,
> +NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
>  };
> 
>  enum NvmeCcShift {
> --
> 2.24.1




Re: [PATCH] ssi: Display chip select polarity in monitor 'info qtree'

2020-09-30 Thread Alistair Francis
On Sun, Sep 27, 2020 at 2:20 AM Philippe Mathieu-Daudé  wrote:
>
> It is sometime useful to verify a device chip select polarity
> on a SPI bus. Since we have this information available, display
> it in the 'info qtree' monitor output:
>
>   $ qemu-system-arm -M lm3s6965evb -monitor stdio -S
>   (qemu) info qtree
>   [...]
>   dev: pl022, id ""
> gpio-out "sysbus-irq" 1
> mmio 40008000/1000
> bus: ssi
>   type SSI
>   dev: ssd0323, id ""
> gpio-in "" 1
> gpio-in "ssi-gpio-cs" 1
> chip select polarity: high   <---
>   dev: ssi-sd, id ""
> gpio-in "ssi-gpio-cs" 1
> chip select polarity: low<---
> bus: sd-bus
>   type sd-bus
>   dev: sd-card, id ""
> spec_version = 2 (0x2)
> drive = "sd0"
> spi = true
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/ssi/ssi.c | 22 ++
>  1 file changed, 22 insertions(+)
>
> diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
> index 4278d0e4440..4c9f8d66d23 100644
> --- a/hw/ssi/ssi.c
> +++ b/hw/ssi/ssi.c
> @@ -17,6 +17,7 @@
>  #include "migration/vmstate.h"
>  #include "qemu/module.h"
>  #include "qapi/error.h"
> +#include "monitor/monitor.h"
>  #include "qom/object.h"
>
>  struct SSIBus {
> @@ -26,10 +27,31 @@ struct SSIBus {
>  #define TYPE_SSI_BUS "SSI"
>  OBJECT_DECLARE_SIMPLE_TYPE(SSIBus, SSI_BUS)
>
> +static void ssi_print_dev(Monitor *mon, DeviceState *dev, int indent)
> +{
> +static const char *const polarity_s[] = {
> +[SSI_CS_NONE] = "unknown",
> +[SSI_CS_LOW]  = "low",
> +[SSI_CS_HIGH] = "high"
> +};
> +SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(dev);
> +
> +monitor_printf(mon, "%*schip select polarity: %s\n",
> +   indent, "", polarity_s[ssc->cs_polarity]);
> +}
> +
> +static void ssi_bus_class_init(ObjectClass *klass, void *data)
> +{
> +BusClass *k = BUS_CLASS(klass);
> +
> +k->print_dev = ssi_print_dev;
> +}
> +
>  static const TypeInfo ssi_bus_info = {
>  .name = TYPE_SSI_BUS,
>  .parent = TYPE_BUS,
>  .instance_size = sizeof(SSIBus),
> +.class_init = ssi_bus_class_init,
>  };
>
>  static void ssi_cs_default(void *opaque, int n, int level)
> --
> 2.26.2
>
>



Re: [PATCH 01/10] qdev: add "check if address free" callback for buses

2020-09-30 Thread Paolo Bonzini
On 30/09/20 16:27, Maxim Levitsky wrote:
> My patch that switches the direction in scsi_device_find, is supposed to be 
> completely equavalent, 
> based on the following train of thought:
> 
> If scsi_device_find finds an exact match it returns only it, as before.
> 
> Otherwise scsi_device_find were to scan from end of the list to the start, 
> and every time,
> it finds a device with same channel/id it would update the target_dev
> and return it when it reaches the end of the list. 
> 
> If I am not mistaken this means that it would return _first_ device in the 
> list that matches the channel/id.
> This is exactly what new version of scsi_device_find does.

Oh!  I missed that subtlety.  Thanks, that makes sense.

Paolo




RE: [PATCH 8/9] hw/block/nvme: add trace event for requests with non-zero status code

2020-09-30 Thread Dmitry Fomichev
> -Original Message-
> From: Keith Busch 
> Sent: Wednesday, September 30, 2020 6:04 PM
> To: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Klaus Jensen
> 
> Cc: Niklas Cassel ; Dmitry Fomichev
> ; Kevin Wolf ; Philippe
> Mathieu-Daudé ; Keith Busch 
> Subject: [PATCH 8/9] hw/block/nvme: add trace event for requests with
> non-zero status code
> 
> From: Klaus Jensen 
> 
> If a command results in a non-zero status code, trace it.
> 
> Signed-off-by: Klaus Jensen 
> Signed-off-by: Keith Busch 
> ---
>  hw/block/nvme.c   | 6 ++
>  hw/block/trace-events | 1 +
>  2 files changed, 7 insertions(+)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index dc971c9653..16804d0278 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -777,6 +777,12 @@ static void
> nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req)
>  assert(cq->cqid == req->sq->cqid);
>  trace_pci_nvme_enqueue_req_completion(nvme_cid(req), cq->cqid,
>req->status);
> +
> +if (req->status) {
> +trace_pci_nvme_err_req_status(nvme_cid(req), nvme_nsid(req->ns),
> +  req->status, req->cmd.opcode);
> +}
> +

Very useful.
Reviewed-by: Dmitry Fomichev 

>  QTAILQ_REMOVE(>sq->out_req_list, req, entry);
>  QTAILQ_INSERT_TAIL(>req_list, req, entry);
>  timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> 500);
> diff --git a/hw/block/trace-events b/hw/block/trace-events
> index 180c43d258..ff3ca4bbf6 100644
> --- a/hw/block/trace-events
> +++ b/hw/block/trace-events
> @@ -89,6 +89,7 @@ pci_nvme_mmio_shutdown_cleared(void) "shutdown
> bit cleared"
> 
>  # nvme traces for error conditions
>  pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
> +pci_nvme_err_req_status(uint16_t cid, uint32_t nsid, uint16_t status,
> uint8_t opc) "cid %"PRIu16" nsid %"PRIu32" status 0x%"PRIx16" opc
> 0x%"PRIx8""
>  pci_nvme_err_addr_read(uint64_t addr) "addr 0x%"PRIx64""
>  pci_nvme_err_addr_write(uint64_t addr) "addr 0x%"PRIx64""
>  pci_nvme_err_cfs(void) "controller fatal status"
> --
> 2.24.1




RE: [PATCH 2/9] hw/block/nvme: fix log page offset check

2020-09-30 Thread Dmitry Fomichev
> -Original Message-
> From: Keith Busch 
> Sent: Wednesday, September 30, 2020 6:04 PM
> To: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Klaus Jensen
> 
> Cc: Niklas Cassel ; Dmitry Fomichev
> ; Kevin Wolf ; Philippe
> Mathieu-Daudé ; Keith Busch 
> Subject: [PATCH 2/9] hw/block/nvme: fix log page offset check
> 
> Return error if the requested offset starts after the size of the log
> being returned. Also, move the check for earlier in the function so
> we're not doing unnecessary calculations.
> 
> Signed-off-by: Keith Busch 

Reviewed- by: Dmitry Fomichev 

> ---
>  hw/block/nvme.c | 22 ++
>  1 file changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index db52ea0db9..8d2b5be567 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -1179,6 +1179,10 @@ static uint16_t nvme_smart_info(NvmeCtrl *n,
> uint8_t rae, uint32_t buf_len,
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
> 
> +if (off >= sizeof(smart)) {
> +return NVME_INVALID_FIELD | NVME_DNR;
> +}
> +
>  for (int i = 1; i <= n->num_namespaces; i++) {
>  NvmeNamespace *ns = nvme_ns(n, i);
>  if (!ns) {
> @@ -1193,10 +1197,6 @@ static uint16_t nvme_smart_info(NvmeCtrl *n,
> uint8_t rae, uint32_t buf_len,
>  write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
>  }
> 
> -if (off > sizeof(smart)) {
> -return NVME_INVALID_FIELD | NVME_DNR;
> -}
> -
>  trans_len = MIN(sizeof(smart) - off, buf_len);
> 
>  memset(, 0x0, sizeof(smart));
> @@ -1234,12 +1234,11 @@ static uint16_t nvme_fw_log_info(NvmeCtrl *n,
> uint32_t buf_len, uint64_t off,
>  .afi = 0x1,
>  };
> 
> -strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
> -
> -if (off > sizeof(fw_log)) {
> +if (off >= sizeof(fw_log)) {
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
> 
> +strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
>  trans_len = MIN(sizeof(fw_log) - off, buf_len);
> 
>  return nvme_dma(n, (uint8_t *) _log + off, trans_len,
> @@ -1252,16 +1251,15 @@ static uint16_t nvme_error_info(NvmeCtrl *n,
> uint8_t rae, uint32_t buf_len,
>  uint32_t trans_len;
>  NvmeErrorLog errlog;
> 
> -if (!rae) {
> -nvme_clear_events(n, NVME_AER_TYPE_ERROR);
> +if (off >= sizeof(errlog)) {
> +return NVME_INVALID_FIELD | NVME_DNR;
>  }
> 
> -if (off > sizeof(errlog)) {
> -return NVME_INVALID_FIELD | NVME_DNR;
> +if (!rae) {
> +nvme_clear_events(n, NVME_AER_TYPE_ERROR);
>  }
> 
>  memset(, 0x0, sizeof(errlog));
> -
>  trans_len = MIN(sizeof(errlog) - off, buf_len);
> 
>  return nvme_dma(n, (uint8_t *), trans_len,
> --
> 2.24.1




RE: [PATCH 6/9] hw/block/nvme: reject io commands if only admin command set selected

2020-09-30 Thread Dmitry Fomichev
> -Original Message-
> From: Keith Busch 
> Sent: Wednesday, September 30, 2020 6:04 PM
> To: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Klaus Jensen
> 
> Cc: Niklas Cassel ; Dmitry Fomichev
> ; Kevin Wolf ; Philippe
> Mathieu-Daudé ; Keith Busch 
> Subject: [PATCH 6/9] hw/block/nvme: reject io commands if only admin
> command set selected
> 
> From: Klaus Jensen 
> 
> If the host sets CC.CSS to 111b, all commands submitted to I/O queues
> should be completed with status Invalid Command Opcode.
> 
> Note that this is technically a v1.4 feature, but it does not hurt to
> implement before we finally bump the reported version implemented.
> 
> Signed-off-by: Klaus Jensen 
> Signed-off-by: Keith Busch 

Reviewed-by: Dmitry Fomichev 

> ---
>  hw/block/nvme.c  | 4 
>  include/block/nvme.h | 5 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index ec7363ea40..80730e1c03 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -1026,6 +1026,10 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n,
> NvmeRequest *req)
>  trace_pci_nvme_io_cmd(nvme_cid(req), nsid, nvme_sqid(req),
>req->cmd.opcode, nvme_io_opc_str(req->cmd.opcode));
> 
> +if (NVME_CC_CSS(n->bar.cc) == NVME_CC_CSS_ADMIN_ONLY) {
> +return NVME_INVALID_OPCODE | NVME_DNR;
> +}
> +
>  if (!nvme_nsid_valid(n, nsid)) {
>  return NVME_INVALID_NSID | NVME_DNR;
>  }
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index 521533fd2a..6de2d5aa75 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -115,6 +115,11 @@ enum NvmeCcMask {
>  #define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) &
> CC_IOSQES_MASK)
>  #define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) &
> CC_IOCQES_MASK)
> 
> +enum NvmeCcCss {
> +NVME_CC_CSS_NVM= 0x0,
> +NVME_CC_CSS_ADMIN_ONLY = 0x7,
> +};
> +
>  enum NvmeCstsShift {
>  CSTS_RDY_SHIFT  = 0,
>  CSTS_CFS_SHIFT  = 1,
> --
> 2.24.1




[PATCH 9/9] hw/block/nvme: report actual LBA data shift in LBAF

2020-09-30 Thread Keith Busch
From: Dmitry Fomichev 

Calculate the data shift value to report based on the set value of
logical_block_size device property.

In the process, use a local variable to calculate the LBA format
index instead of the hardcoded value 0. This makes the code more
readable and it will make it easier to add support for multiple LBA
formats in the future.

Signed-off-by: Dmitry Fomichev 
Reviewed-by: Klaus Jensen 
Signed-off-by: Keith Busch 
---
 hw/block/nvme-ns.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
index 2ba0263dda..a85e5fdb42 100644
--- a/hw/block/nvme-ns.c
+++ b/hw/block/nvme-ns.c
@@ -47,6 +47,8 @@ static void nvme_ns_init(NvmeNamespace *ns)
 
 static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
 {
+int lba_index;
+
 if (!blkconf_blocksizes(>blkconf, errp)) {
 return -1;
 }
@@ -67,6 +69,9 @@ static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, 
Error **errp)
 n->features.vwc = 0x1;
 }
 
+lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
+ns->id_ns.lbaf[lba_index].ds = 31 - clz32(ns->blkconf.logical_block_size);
+
 return 0;
 }
 
-- 
2.24.1




[PATCH 7/9] hw/block/nvme: add nsid to get/setfeat trace events

2020-09-30 Thread Keith Busch
From: Klaus Jensen 

Include the namespace id in the pci_nvme_{get,set}feat trace events.

Signed-off-by: Klaus Jensen 
Signed-off-by: Keith Busch 
---
 hw/block/nvme.c   | 4 ++--
 hw/block/trace-events | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 80730e1c03..dc971c9653 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1643,7 +1643,7 @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeRequest 
*req)
 [NVME_ARBITRATION] = NVME_ARB_AB_NOLIMIT,
 };
 
-trace_pci_nvme_getfeat(nvme_cid(req), fid, sel, dw11);
+trace_pci_nvme_getfeat(nvme_cid(req), nsid, fid, sel, dw11);
 
 if (!nvme_feature_support[fid]) {
 return NVME_INVALID_FIELD | NVME_DNR;
@@ -1781,7 +1781,7 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeRequest 
*req)
 uint8_t fid = NVME_GETSETFEAT_FID(dw10);
 uint8_t save = NVME_SETFEAT_SAVE(dw10);
 
-trace_pci_nvme_setfeat(nvme_cid(req), fid, save, dw11);
+trace_pci_nvme_setfeat(nvme_cid(req), nsid, fid, save, dw11);
 
 if (save) {
 return NVME_FID_NOT_SAVEABLE | NVME_DNR;
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 7720e1b4d9..180c43d258 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -53,8 +53,8 @@ pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32""
 pci_nvme_identify_nslist(uint32_t ns) "nsid %"PRIu32""
 pci_nvme_identify_ns_descr_list(uint32_t ns) "nsid %"PRIu32""
 pci_nvme_get_log(uint16_t cid, uint8_t lid, uint8_t lsp, uint8_t rae, uint32_t 
len, uint64_t off) "cid %"PRIu16" lid 0x%"PRIx8" lsp 0x%"PRIx8" rae 0x%"PRIx8" 
len %"PRIu32" off %"PRIu64""
-pci_nvme_getfeat(uint16_t cid, uint8_t fid, uint8_t sel, uint32_t cdw11) "cid 
%"PRIu16" fid 0x%"PRIx8" sel 0x%"PRIx8" cdw11 0x%"PRIx32""
-pci_nvme_setfeat(uint16_t cid, uint8_t fid, uint8_t save, uint32_t cdw11) "cid 
%"PRIu16" fid 0x%"PRIx8" save 0x%"PRIx8" cdw11 0x%"PRIx32""
+pci_nvme_getfeat(uint16_t cid, uint32_t nsid, uint8_t fid, uint8_t sel, 
uint32_t cdw11) "cid %"PRIu16" nsid 0x%"PRIx32" fid 0x%"PRIx8" sel 0x%"PRIx8" 
cdw11 0x%"PRIx32""
+pci_nvme_setfeat(uint16_t cid, uint32_t nsid, uint8_t fid, uint8_t save, 
uint32_t cdw11) "cid %"PRIu16" nsid 0x%"PRIx32" fid 0x%"PRIx8" save 0x%"PRIx8" 
cdw11 0x%"PRIx32""
 pci_nvme_getfeat_vwcache(const char* result) "get feature volatile write 
cache, result=%s"
 pci_nvme_getfeat_numq(int result) "get feature number of queues, result=%d"
 pci_nvme_setfeat_numq(int reqcq, int reqsq, int gotcq, int gotsq) "requested 
cq_count=%d sq_count=%d, responding with cq_count=%d sq_count=%d"
-- 
2.24.1




[PATCH 3/9] hw/block/nvme: support per-namespace smart log

2020-09-30 Thread Keith Busch
Let the user specify a specific namespace if they want to get access
stats for a specific namespace.

Signed-off-by: Keith Busch 
---
 hw/block/nvme.c  | 66 +++-
 include/block/nvme.h |  1 +
 2 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 8d2b5be567..41389b2b09 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1164,48 +1164,62 @@ static uint16_t nvme_create_sq(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_SUCCESS;
 }
 
+struct nvme_stats {
+uint64_t units_read;
+uint64_t units_written;
+uint64_t read_commands;
+uint64_t write_commands;
+};
+
+static void nvme_set_blk_stats(NvmeNamespace *ns, struct nvme_stats *stats)
+{
+BlockAcctStats *s = blk_get_stats(ns->blkconf.blk);
+
+stats->units_read += s->nr_bytes[BLOCK_ACCT_READ] >> BDRV_SECTOR_BITS;
+stats->units_written += s->nr_bytes[BLOCK_ACCT_WRITE] >> BDRV_SECTOR_BITS;
+stats->read_commands += s->nr_ops[BLOCK_ACCT_READ];
+stats->write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
+}
+
 static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
 uint64_t off, NvmeRequest *req)
 {
 uint32_t nsid = le32_to_cpu(req->cmd.nsid);
-
+struct nvme_stats stats = { 0 };
+NvmeSmartLog smart = { 0 };
 uint32_t trans_len;
+NvmeNamespace *ns;
 time_t current_ms;
-uint64_t units_read = 0, units_written = 0;
-uint64_t read_commands = 0, write_commands = 0;
-NvmeSmartLog smart;
-
-if (nsid && nsid != 0x) {
-return NVME_INVALID_FIELD | NVME_DNR;
-}
 
 if (off >= sizeof(smart)) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-for (int i = 1; i <= n->num_namespaces; i++) {
-NvmeNamespace *ns = nvme_ns(n, i);
-if (!ns) {
-continue;
-}
-
-BlockAcctStats *s = blk_get_stats(ns->blkconf.blk);
+if (nsid != 0x) {
+ns = nvme_ns(n, nsid);
+if (!ns)
+return NVME_INVALID_NSID | NVME_DNR;
+nvme_set_blk_stats(ns, );
+} else {
+int i;
 
-units_read += s->nr_bytes[BLOCK_ACCT_READ] >> BDRV_SECTOR_BITS;
-units_written += s->nr_bytes[BLOCK_ACCT_WRITE] >> BDRV_SECTOR_BITS;
-read_commands += s->nr_ops[BLOCK_ACCT_READ];
-write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
+for (i = 1; i <= n->num_namespaces; i++) {
+ns = nvme_ns(n, i);
+if (!ns) {
+continue;
+}
+nvme_set_blk_stats(ns, );
+}
 }
 
 trans_len = MIN(sizeof(smart) - off, buf_len);
 
-memset(, 0x0, sizeof(smart));
-
-smart.data_units_read[0] = cpu_to_le64(DIV_ROUND_UP(units_read, 1000));
-smart.data_units_written[0] = cpu_to_le64(DIV_ROUND_UP(units_written,
+smart.data_units_read[0] = cpu_to_le64(DIV_ROUND_UP(stats.units_read,
+1000));
+smart.data_units_written[0] = cpu_to_le64(DIV_ROUND_UP(stats.units_written,
1000));
-smart.host_read_commands[0] = cpu_to_le64(read_commands);
-smart.host_write_commands[0] = cpu_to_le64(write_commands);
+smart.host_read_commands[0] = cpu_to_le64(stats.read_commands);
+smart.host_write_commands[0] = cpu_to_le64(stats.write_commands);
 
 smart.temperature = cpu_to_le16(n->temperature);
 
@@ -2708,7 +2722,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
*pci_dev)
 id->acl = 3;
 id->aerl = n->params.aerl;
 id->frmw = (NVME_NUM_FW_SLOTS << 1) | NVME_FRMW_SLOT1_RO;
-id->lpa = NVME_LPA_EXTENDED;
+id->lpa = NVME_LPA_NS_SMART | NVME_LPA_EXTENDED;
 
 /* recommended default value (~70 C) */
 id->wctemp = cpu_to_le16(NVME_TEMPERATURE_WARNING);
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 58647bcdad..868cf53f0b 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -849,6 +849,7 @@ enum NvmeIdCtrlFrmw {
 };
 
 enum NvmeIdCtrlLpa {
+NVME_LPA_NS_SMART = 1 << 0,
 NVME_LPA_EXTENDED = 1 << 2,
 };
 
-- 
2.24.1




[PATCH 6/9] hw/block/nvme: reject io commands if only admin command set selected

2020-09-30 Thread Keith Busch
From: Klaus Jensen 

If the host sets CC.CSS to 111b, all commands submitted to I/O queues
should be completed with status Invalid Command Opcode.

Note that this is technically a v1.4 feature, but it does not hurt to
implement before we finally bump the reported version implemented.

Signed-off-by: Klaus Jensen 
Signed-off-by: Keith Busch 
---
 hw/block/nvme.c  | 4 
 include/block/nvme.h | 5 +
 2 files changed, 9 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index ec7363ea40..80730e1c03 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1026,6 +1026,10 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
*req)
 trace_pci_nvme_io_cmd(nvme_cid(req), nsid, nvme_sqid(req),
   req->cmd.opcode, nvme_io_opc_str(req->cmd.opcode));
 
+if (NVME_CC_CSS(n->bar.cc) == NVME_CC_CSS_ADMIN_ONLY) {
+return NVME_INVALID_OPCODE | NVME_DNR;
+}
+
 if (!nvme_nsid_valid(n, nsid)) {
 return NVME_INVALID_NSID | NVME_DNR;
 }
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 521533fd2a..6de2d5aa75 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -115,6 +115,11 @@ enum NvmeCcMask {
 #define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK)
 #define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK)
 
+enum NvmeCcCss {
+NVME_CC_CSS_NVM= 0x0,
+NVME_CC_CSS_ADMIN_ONLY = 0x7,
+};
+
 enum NvmeCstsShift {
 CSTS_RDY_SHIFT  = 0,
 CSTS_CFS_SHIFT  = 1,
-- 
2.24.1




[PATCH 8/9] hw/block/nvme: add trace event for requests with non-zero status code

2020-09-30 Thread Keith Busch
From: Klaus Jensen 

If a command results in a non-zero status code, trace it.

Signed-off-by: Klaus Jensen 
Signed-off-by: Keith Busch 
---
 hw/block/nvme.c   | 6 ++
 hw/block/trace-events | 1 +
 2 files changed, 7 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index dc971c9653..16804d0278 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -777,6 +777,12 @@ static void nvme_enqueue_req_completion(NvmeCQueue *cq, 
NvmeRequest *req)
 assert(cq->cqid == req->sq->cqid);
 trace_pci_nvme_enqueue_req_completion(nvme_cid(req), cq->cqid,
   req->status);
+
+if (req->status) {
+trace_pci_nvme_err_req_status(nvme_cid(req), nvme_nsid(req->ns),
+  req->status, req->cmd.opcode);
+}
+
 QTAILQ_REMOVE(>sq->out_req_list, req, entry);
 QTAILQ_INSERT_TAIL(>req_list, req, entry);
 timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 180c43d258..ff3ca4bbf6 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -89,6 +89,7 @@ pci_nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
 
 # nvme traces for error conditions
 pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
+pci_nvme_err_req_status(uint16_t cid, uint32_t nsid, uint16_t status, uint8_t 
opc) "cid %"PRIu16" nsid %"PRIu32" status 0x%"PRIx16" opc 0x%"PRIx8""
 pci_nvme_err_addr_read(uint64_t addr) "addr 0x%"PRIx64""
 pci_nvme_err_addr_write(uint64_t addr) "addr 0x%"PRIx64""
 pci_nvme_err_cfs(void) "controller fatal status"
-- 
2.24.1




[PATCH 1/9] hw/block/nvme: remove pointless rw indirection

2020-09-30 Thread Keith Busch
The code switches on the opcode to invoke a function specific to that
opcode. There's no point in consolidating back to a common function that
just switches on that same opcode without any actual common code.
Restore the opcode specific behavior without going back through another
level of switches.

Signed-off-by: Keith Busch 
---
 hw/block/nvme.c | 91 -
 1 file changed, 29 insertions(+), 62 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index da8344f196..db52ea0db9 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -927,68 +927,12 @@ static void nvme_rw_cb(void *opaque, int ret)
 nvme_enqueue_req_completion(nvme_cq(req), req);
 }
 
-static uint16_t nvme_do_aio(BlockBackend *blk, int64_t offset, size_t len,
-NvmeRequest *req)
-{
-BlockAcctCookie *acct = >acct;
-BlockAcctStats *stats = blk_get_stats(blk);
-
-bool is_write = false;
-
-trace_pci_nvme_do_aio(nvme_cid(req), req->cmd.opcode,
-  nvme_io_opc_str(req->cmd.opcode), blk_name(blk),
-  offset, len);
-
-switch (req->cmd.opcode) {
-case NVME_CMD_FLUSH:
-block_acct_start(stats, acct, 0, BLOCK_ACCT_FLUSH);
-req->aiocb = blk_aio_flush(blk, nvme_rw_cb, req);
-break;
-
-case NVME_CMD_WRITE_ZEROES:
-block_acct_start(stats, acct, len, BLOCK_ACCT_WRITE);
-req->aiocb = blk_aio_pwrite_zeroes(blk, offset, len,
-   BDRV_REQ_MAY_UNMAP, nvme_rw_cb,
-   req);
-break;
-
-case NVME_CMD_WRITE:
-is_write = true;
-
-/* fallthrough */
-
-case NVME_CMD_READ:
-block_acct_start(stats, acct, len,
- is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
-
-if (req->qsg.sg) {
-if (is_write) {
-req->aiocb = dma_blk_write(blk, >qsg, offset,
-   BDRV_SECTOR_SIZE, nvme_rw_cb, req);
-} else {
-req->aiocb = dma_blk_read(blk, >qsg, offset,
-  BDRV_SECTOR_SIZE, nvme_rw_cb, req);
-}
-} else {
-if (is_write) {
-req->aiocb = blk_aio_pwritev(blk, offset, >iov, 0,
- nvme_rw_cb, req);
-} else {
-req->aiocb = blk_aio_preadv(blk, offset, >iov, 0,
-nvme_rw_cb, req);
-}
-}
-
-break;
-}
-
-return NVME_NO_COMPLETE;
-}
-
 static uint16_t nvme_flush(NvmeCtrl *n, NvmeRequest *req)
 {
-NvmeNamespace *ns = req->ns;
-return nvme_do_aio(ns->blkconf.blk, 0, 0, req);
+block_acct_start(blk_get_stats(n->conf.blk), >acct, 0,
+ BLOCK_ACCT_FLUSH);
+req->aiocb = blk_aio_flush(n->conf.blk, nvme_rw_cb, req);
+return NVME_NO_COMPLETE;
 }
 
 static uint16_t nvme_write_zeroes(NvmeCtrl *n, NvmeRequest *req)
@@ -1009,7 +953,11 @@ static uint16_t nvme_write_zeroes(NvmeCtrl *n, 
NvmeRequest *req)
 return status;
 }
 
-return nvme_do_aio(ns->blkconf.blk, offset, count, req);
+block_acct_start(blk_get_stats(n->conf.blk), >acct, 0,
+ BLOCK_ACCT_WRITE);
+req->aiocb = blk_aio_pwrite_zeroes(n->conf.blk, offset, count,
+   BDRV_REQ_MAY_UNMAP, nvme_rw_cb, req);
+return NVME_NO_COMPLETE;
 }
 
 static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
@@ -1023,6 +971,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
 uint64_t data_offset = nvme_l2b(ns, slba);
 enum BlockAcctType acct = req->cmd.opcode == NVME_CMD_WRITE ?
 BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
+BlockBackend *blk = ns->blkconf.blk;
 uint16_t status;
 
 trace_pci_nvme_rw(nvme_cid(req), nvme_io_opc_str(rw->opcode),
@@ -1045,7 +994,25 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeRequest *req)
 goto invalid;
 }
 
-return nvme_do_aio(ns->blkconf.blk, data_offset, data_size, req);
+block_acct_start(blk_get_stats(blk), >acct, data_size, acct);
+if (req->qsg.sg) {
+if (acct == BLOCK_ACCT_WRITE) {
+req->aiocb = dma_blk_write(blk, >qsg, data_offset,
+   BDRV_SECTOR_SIZE, nvme_rw_cb, req);
+} else {
+req->aiocb = dma_blk_read(blk, >qsg, data_offset,
+  BDRV_SECTOR_SIZE, nvme_rw_cb, req);
+}
+} else {
+if (acct == BLOCK_ACCT_WRITE) {
+req->aiocb = blk_aio_pwritev(blk, data_offset, >iov, 0,
+ nvme_rw_cb, req);
+} else {
+req->aiocb = blk_aio_preadv(blk, data_offset, >iov, 0,
+nvme_rw_cb, req);
+}
+}
+return NVME_NO_COMPLETE;
 
 invalid:
 

[PATCH 4/9] hw/block/nvme: validate command set selected

2020-09-30 Thread Keith Busch
Fail to start the controller if the user requests a command set that the
controller does not support.

Signed-off-by: Keith Busch 
---
 hw/block/nvme.c   | 6 +-
 hw/block/trace-events | 1 +
 include/block/nvme.h  | 4 
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 41389b2b09..6c582e6874 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -2049,6 +2049,10 @@ static int nvme_start_ctrl(NvmeCtrl *n)
 trace_pci_nvme_err_startfail_acq_misaligned(n->bar.acq);
 return -1;
 }
+if (unlikely(!(NVME_CAP_CSS(n->bar.cap) & (1 << NVME_CC_CSS(n->bar.cc) 
{
+trace_pci_nvme_err_startfail_css(NVME_CC_CSS(n->bar.cc));
+return -1;
+}
 if (unlikely(NVME_CC_MPS(n->bar.cc) <
  NVME_CAP_MPSMIN(n->bar.cap))) {
 trace_pci_nvme_err_startfail_page_too_small(
@@ -2750,7 +2754,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
*pci_dev)
 NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
 NVME_CAP_SET_CQR(n->bar.cap, 1);
 NVME_CAP_SET_TO(n->bar.cap, 0xf);
-NVME_CAP_SET_CSS(n->bar.cap, 1);
+NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
 NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
 
 n->bar.vs = NVME_SPEC_VER;
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 446cca08e9..7720e1b4d9 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -133,6 +133,7 @@ pci_nvme_err_startfail_cqent_too_small(uint8_t log2ps, 
uint8_t maxlog2ps) "nvme_
 pci_nvme_err_startfail_cqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) 
"nvme_start_ctrl failed because the completion queue entry size is too large: 
log2size=%u, max=%u"
 pci_nvme_err_startfail_sqent_too_small(uint8_t log2ps, uint8_t maxlog2ps) 
"nvme_start_ctrl failed because the submission queue entry size is too small: 
log2size=%u, min=%u"
 pci_nvme_err_startfail_sqent_too_large(uint8_t log2ps, uint8_t maxlog2ps) 
"nvme_start_ctrl failed because the submission queue entry size is too large: 
log2size=%u, max=%u"
+pci_nvme_err_startfail_css(uint8_t css) "nvme_start_ctrl failed because 
invalid command set selected:%u"
 pci_nvme_err_startfail_asqent_sz_zero(void) "nvme_start_ctrl failed because 
the admin submission queue size is zero"
 pci_nvme_err_startfail_acqent_sz_zero(void) "nvme_start_ctrl failed because 
the admin completion queue size is zero"
 pci_nvme_err_startfail(void) "setting controller enable bit failed"
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 868cf53f0b..bc20a2ba5e 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -82,6 +82,10 @@ enum NvmeCapMask {
 #define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
 << CAP_PMR_SHIFT)
 
+enum NvmeCapCss {
+NVME_CAP_CSS_NVM = 1 << 0,
+};
+
 enum NvmeCcShift {
 CC_EN_SHIFT = 0,
 CC_CSS_SHIFT= 4,
-- 
2.24.1




[PATCH 5/9] hw/block/nvme: support for admin-only command set

2020-09-30 Thread Keith Busch
Signed-off-by: Keith Busch 
---
 hw/block/nvme.c  | 1 +
 include/block/nvme.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 6c582e6874..ec7363ea40 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -2755,6 +2755,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
*pci_dev)
 NVME_CAP_SET_CQR(n->bar.cap, 1);
 NVME_CAP_SET_TO(n->bar.cap, 0xf);
 NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_NVM);
+NVME_CAP_SET_CSS(n->bar.cap, NVME_CAP_CSS_ADMIN_ONLY);
 NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
 
 n->bar.vs = NVME_SPEC_VER;
diff --git a/include/block/nvme.h b/include/block/nvme.h
index bc20a2ba5e..521533fd2a 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -83,7 +83,8 @@ enum NvmeCapMask {
 << CAP_PMR_SHIFT)
 
 enum NvmeCapCss {
-NVME_CAP_CSS_NVM = 1 << 0,
+NVME_CAP_CSS_NVM= 1 << 0,
+NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
 };
 
 enum NvmeCcShift {
-- 
2.24.1




[PATCH 0/9] nvme qemu cleanups and fixes

2020-09-30 Thread Keith Busch
After going through the zns enabling, I notice the controller enabling
is not correct. Then I just continued maked more stuff. The series, I
think, contains some of the less controversial patches from the two
conflicting zns series, preceeded by some cleanups and fixes from me.

If this is all fine, I took the liberty of porting the zns enabling to
it and made a public branch for consideration here:

 http://git.infradead.org/qemu-nvme.git/shortlog/refs/heads/kb-zns 

Dmitry Fomichev (1):
  hw/block/nvme: report actual LBA data shift in LBAF

Keith Busch (5):
  hw/block/nvme: remove pointless rw indirection
  hw/block/nvme: fix log page offset check
  hw/block/nvme: support per-namespace smart log
  hw/block/nvme: validate command set selected
  hw/block/nvme: support for admin-only command set

Klaus Jensen (3):
  hw/block/nvme: reject io commands if only admin command set selected
  hw/block/nvme: add nsid to get/setfeat trace events
  hw/block/nvme: add trace event for requests with non-zero status code

 hw/block/nvme-ns.c|   5 ++
 hw/block/nvme.c   | 194 --
 hw/block/trace-events |   6 +-
 include/block/nvme.h  |  11 +++
 4 files changed, 114 insertions(+), 102 deletions(-)

-- 
2.24.1




[PATCH 2/9] hw/block/nvme: fix log page offset check

2020-09-30 Thread Keith Busch
Return error if the requested offset starts after the size of the log
being returned. Also, move the check for earlier in the function so
we're not doing unnecessary calculations.

Signed-off-by: Keith Busch 
---
 hw/block/nvme.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index db52ea0db9..8d2b5be567 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1179,6 +1179,10 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t 
rae, uint32_t buf_len,
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
+if (off >= sizeof(smart)) {
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
 for (int i = 1; i <= n->num_namespaces; i++) {
 NvmeNamespace *ns = nvme_ns(n, i);
 if (!ns) {
@@ -1193,10 +1197,6 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t 
rae, uint32_t buf_len,
 write_commands += s->nr_ops[BLOCK_ACCT_WRITE];
 }
 
-if (off > sizeof(smart)) {
-return NVME_INVALID_FIELD | NVME_DNR;
-}
-
 trans_len = MIN(sizeof(smart) - off, buf_len);
 
 memset(, 0x0, sizeof(smart));
@@ -1234,12 +1234,11 @@ static uint16_t nvme_fw_log_info(NvmeCtrl *n, uint32_t 
buf_len, uint64_t off,
 .afi = 0x1,
 };
 
-strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
-
-if (off > sizeof(fw_log)) {
+if (off >= sizeof(fw_log)) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
+strpadcpy((char *)_log.frs1, sizeof(fw_log.frs1), "1.0", ' ');
 trans_len = MIN(sizeof(fw_log) - off, buf_len);
 
 return nvme_dma(n, (uint8_t *) _log + off, trans_len,
@@ -1252,16 +1251,15 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t 
rae, uint32_t buf_len,
 uint32_t trans_len;
 NvmeErrorLog errlog;
 
-if (!rae) {
-nvme_clear_events(n, NVME_AER_TYPE_ERROR);
+if (off >= sizeof(errlog)) {
+return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-if (off > sizeof(errlog)) {
-return NVME_INVALID_FIELD | NVME_DNR;
+if (!rae) {
+nvme_clear_events(n, NVME_AER_TYPE_ERROR);
 }
 
 memset(, 0x0, sizeof(errlog));
-
 trans_len = MIN(sizeof(errlog) - off, buf_len);
 
 return nvme_dma(n, (uint8_t *), trans_len,
-- 
2.24.1




Re: [PATCH v4 1/2] Introduce (x86) CPU model deprecation API

2020-09-30 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 03:14:14PM +0800, Robert Hoo wrote:
> Complement versioned CPU model framework with the ability of marking some
> versions deprecated. When that CPU model is chosen, get some warning. The
> warning message is customized, e.g. telling in which future QEMU version will
> it be obsoleted.
> The deprecation message will also appear by x86_cpu_list_entry(), e.g. '-cpu
> help'.
> QMP 'query-cpu-definitions' will also return a bool value indicating the
> deprecation status.
> 
> Signed-off-by: Robert Hoo 
> ---
> Changelog
> v4:
> Move deprecation_note from X86CPUModel to X86CPUDefinition, to make it
> simple. Also, simplify 2 fields (deprecation_note and deprecated) into 1
> (deprecation_note).
> 
> v3:
> Make the deprecation implementation CPUClass generic.
> 
> v2:
> Move deprecation check from parse_cpu_option() to machine_run_board_init(), so
> that it can cover implicit cpu_type assignment cases.
> Add qapi new member documentation. Thanks Eric for comment and guidance on 
> qapi.
> 
> ---
>  hw/core/machine.c| 12 ++--
>  include/hw/core/cpu.h|  3 +++
>  qapi/machine-target.json |  7 ++-
>  target/i386/cpu.c|  8 
>  4 files changed, 27 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index ea26d61..67fff0b 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1095,6 +1095,8 @@ MemoryRegion *machine_consume_memdev(MachineState 
> *machine,
>  void machine_run_board_init(MachineState *machine)
>  {
>  MachineClass *machine_class = MACHINE_GET_CLASS(machine);
> +ObjectClass *oc = object_class_by_name(machine->cpu_type);

machine->cpu_type can be NULL...

> +CPUClass *cc;
>  
>  if (machine->ram_memdev_id) {
>  Object *o;
> @@ -1114,11 +1116,10 @@ void machine_run_board_init(MachineState *machine)
>   * specified a CPU with -cpu check here that the user CPU is supported.
>   */
>  if (machine_class->valid_cpu_types && machine->cpu_type) {
> -ObjectClass *class = object_class_by_name(machine->cpu_type);
>  int i;
>  
>  for (i = 0; machine_class->valid_cpu_types[i]; i++) {
> -if (object_class_dynamic_cast(class,
> +if (object_class_dynamic_cast(oc,
>
> machine_class->valid_cpu_types[i])) {
>  /* The user specificed CPU is in the valid field, we are
>   * good to go.
> @@ -1141,6 +1142,13 @@ void machine_run_board_init(MachineState *machine)
>  }
>  }
>  
> +/* Check if CPU type is deprecated and warn if so */
> +cc = CPU_CLASS(oc);
> +if (cc->deprecation_note) {

...so this will crash.

I've changed this to "if (cc && cc->deprecation_note)".

> +warn_report("CPU model %s is deprecated -- %s", machine->cpu_type,
> +cc->deprecation_note);
> +}
> +
>  machine_class->init(machine);
>  }
>  
> diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> index 99dc33f..c40c29d 100644
> --- a/include/hw/core/cpu.h
> +++ b/include/hw/core/cpu.h
> @@ -155,6 +155,8 @@ struct TranslationBlock;
>   * @disas_set_info: Setup architecture specific components of disassembly 
> info
>   * @adjust_watchpoint_address: Perform a target-specific adjustment to an
>   * address before attempting to match it against watchpoints.
> + * @deprecation_note: If this CPUClass is deprecated, this field provides
> + *related information.
>   *
>   * Represents a CPU family or model.
>   */
> @@ -221,6 +223,7 @@ struct CPUClass {
>  vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
>  void (*tcg_initialize)(void);
>  
> +const char *deprecation_note;
>  /* Keep non-pointer data at the end to minimize holes.  */
>  int gdb_num_core_regs;
>  bool gdb_stop_before_watchpoint;
> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index 698850c..fec3bb8 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -286,6 +286,10 @@
>  #in the VM configuration, because aliases may stop being
>  #migration-safe in the future (since 4.1)
>  #
> +# @deprecated: If true, this CPU model is deprecated and may be removed in
> +#  in some future version of QEMU according to the QEMU 
> deprecation
> +#  policy. (since 5.2)
> +#
>  # @unavailable-features is a list of QOM property names that
>  # represent CPU model attributes that prevent the CPU from running.
>  # If the QOM property is read-only, that means there's no known
> @@ -310,7 +314,8 @@
>  'static': 'bool',
>  '*unavailable-features': [ 'str' ],
>  'typename': 'str',
> -'*alias-of' : 'str' },
> +'*alias-of' : 'str',
> +'deprecated' : 'bool' },
>'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) 
> || defined(TARGET_S390X) || 

RE: [RFC PATCH v4 22/29] Hexagon (target/hexagon) macros

2020-09-30 Thread Taylor Simpson


> -Original Message-
> From: Philippe Mathieu-Daudé  On
> Behalf Of Philippe Mathieu-Daudé
> Sent: Tuesday, September 29, 2020 6:34 AM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: richard.hender...@linaro.org; laur...@vivier.eu; riku.voi...@iki.fi;
> aleksandar.m.m...@gmail.com; a...@rev.ng
> Subject: Re: [RFC PATCH v4 22/29] Hexagon (target/hexagon) macros
>
> On 9/28/20 7:28 PM, Taylor Simpson wrote:
> > macros to interface with the generator
> > macros referenced in instruction semantics
> >
> > +#ifndef HEXAGON_MACROS_H
> > +#define HEXAGON_MACROS_H
> > +
> > +#include "qemu/osdep.h"
>
> Please do not include "qemu/osdep.h" in header.
>
> > +#include "qemu/host-utils.h"
>
> "qemu/host-utils.h" doesn't seem used.
>
> > +#include "cpu.h"
> > +#include "hex_regs.h"
> > +#include "reg_fields.h"
> > +
> [...]

To clarify, does the "[...]" mean I should remove all the includes (and include 
them in the .c files that include this header file)?

Thanks,
Taylor




Re: [PATCH V1 2/3] amd-iommu: Sync IOVA-to-GPA translation during page invalidation

2020-09-30 Thread Wei Huang
On 09/29 01:34, Alex Williamson wrote:
> On Mon, 28 Sep 2020 15:05:05 -0500
> Wei Huang  wrote:
> 
> > Add support to sync the IOVA-to-GPA translation at the time of IOMMU
> > page invalidation. This function is called when two IOMMU commands,
> > AMDVI_CMD_INVAL_AMDVI_PAGES and AMDVI_CMD_INVAL_AMDVI_ALL, are
> > intercepted. Address space notifiers are called accordingly.
> > 
> > Co-developed-by: Wei Huang 
> > Signed-off-by: Suravee Suthikulpanit 
> > ---
> >  hw/i386/amd_iommu.c | 177 
> >  hw/i386/amd_iommu.h |  10 +++
> >  hw/vfio/common.c|   3 +-
> >  3 files changed, 189 insertions(+), 1 deletion(-)
> ...
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index 13471ae29436..243216499ce0 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -346,7 +346,8 @@ static int vfio_dma_map(VFIOContainer *container, 
> > hwaddr iova,
> >   * the VGA ROM space.
> >   */
> >  if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, ) == 0 ||
> > -(errno == EBUSY && vfio_dma_unmap(container, iova, size) == 0 &&
> > +((errno == EEXIST || errno == EBUSY) &&
> > + vfio_dma_unmap(container, iova, size) == 0 &&
> >   ioctl(container->fd, VFIO_IOMMU_MAP_DMA, ) == 0)) {
> >  return 0;
> >  }
> 
> 
> This seems like it should be a separate patch.  AFAICT the commit log
> doesn't even hint at why this change is necessary.  I think the -EBUSY
> error pre-dates vIOMMU as well.  Responding the same for an -EEXIST
> almost suggests a coherency issue between QEMU and the kernel, or a
> direct mapping replacement without an invalidation, which doesn't seem
> to be what this patch is implementing.  Thanks,

I went back to check it. Removing this checking code (original code) didn't
trigger any issues with Intel 10G passthru NIC. I think this was from the
residual debugging code when we started to implement it. Sorry for the
confusion. I will remove this code in V2 with more tests.

-Wei

> 
> Alex
> 



RE: [RFC PATCH v4 27/29] Hexagon (linux-user/hexagon) Linux user emulation

2020-09-30 Thread Taylor Simpson


> -Original Message-
> From: Laurent Vivier 
> Sent: Monday, September 28, 2020 3:03 PM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: richard.hender...@linaro.org; phi...@redhat.com; riku.voi...@iki.fi;
> aleksandar.m.m...@gmail.com; a...@rev.ng
> Subject: Re: [RFC PATCH v4 27/29] Hexagon (linux-user/hexagon) Linux user
> emulation
>
> > +
> > +syscall_nr_generators += {
> > +  'hexagon': generator(sh,
> > +   arguments: [ 'cat', 'syscall_nr.h', '>', '@OUTPUT@' 
> > ],
> > + output: '@BASENAME@_nr.h')
>
> Why do we need that?
> The syscall_nr_generators is used to generate syscall_nr.h from syscall.tbl

The other linux-user targets have this in their meson.build files.  I'll remove 
if it's not needed.

>
> > +}
> > diff --git a/linux-user/meson.build b/linux-user/meson.build
> > index 2b94e4b..8b1dfc8 100644
> > --- a/linux-user/meson.build
> > +++ b/linux-user/meson.build
> > @@ -22,6 +22,7 @@ syscall_nr_generators = {}
> >
> >  subdir('alpha')
> >  subdir('arm')
> > +subdir('hexagon')
>
> so you don't need that either

OK

> > -grep -e "#define __NR_" -e "#define __NR3264"
> > +grep -e "#define __NR_" -e "#define __NR3264" | grep -v
> __NR_syscalls
>
> Why do you remove __NR_syscalls?

Older kernels have a bunch of
#undef __NR_syscalls
#define __NR_syscalls  X

The script removes all #undef's but leaves the #define's, so we get compile 
errors.  That symbol isn't used by qemu so it's safe to remove.




[PATCH 13/14] arc: Add support for ARCv2

2020-09-30 Thread cupertinomiranda
From: Shahab Vahedi 

Add remaining bits of the Synopsys ARCv2 (EM/HS) support into QEMU,
configure bits, arch_init and configuration files for softmmu (hardware
emulation).

Signed-off-by: Shahab Vahedi 
---
 configure   |  5 +
 default-configs/arc-softmmu.mak |  5 +
 disas.c |  2 ++
 disas/meson.build   |  1 +
 hw/meson.build  |  1 +
 include/disas/dis-asm.h | 10 +-
 include/elf.h   |  3 +++
 include/exec/poison.h   |  2 ++
 include/sysemu/arch_init.h  |  1 +
 meson.build |  3 ++-
 softmmu/arch_init.c |  2 ++
 target/meson.build  |  1 +
 12 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/arc-softmmu.mak

diff --git a/configure b/configure
index ecc8e90e8b..65862d8371 100755
--- a/configure
+++ b/configure
@@ -7570,6 +7570,9 @@ case "$target_name" in
 mttcg="yes"
 TARGET_SYSTBL_ABI=common
   ;;
+  arc)
+gdb_xml_files="arc-core-v2.xml arc-aux-minimal.xml arc-aux-other.xml"
+  ;;
   arm|armeb)
 TARGET_ARCH=arm
 TARGET_SYSTBL_ABI=common,oabi
@@ -7852,8 +7855,10 @@ DIRS="$DIRS docs docs/interop fsdev scsi"
 DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios"
 DIRS="$DIRS contrib/plugins/"
+#DIRS="$DIRS tests/tcg/arc"
 LINKS="Makefile"
 LINKS="$LINKS tests/tcg/lm32/Makefile"
+#LINKS="$LINKS tests/tcg/arc/Makefile.target"
 LINKS="$LINKS tests/tcg/Makefile.target"
 LINKS="$LINKS pc-bios/optionrom/Makefile"
 LINKS="$LINKS pc-bios/s390-ccw/Makefile"
diff --git a/default-configs/arc-softmmu.mak b/default-configs/arc-softmmu.mak
new file mode 100644
index 00..4300a90c93
--- /dev/null
+++ b/default-configs/arc-softmmu.mak
@@ -0,0 +1,5 @@
+# Default configuration for arc-softmmu
+
+CONFIG_VIRTIO_MMIO=y
+CONFIG_SERIAL=y
+CONFIG_OPENCORES_ETH=y
diff --git a/disas.c b/disas.c
index c1397d3933..41aabbca63 100644
--- a/disas.c
+++ b/disas.c
@@ -671,6 +671,8 @@ void disas(FILE *out, void *code, unsigned long size, const 
char *note)
 print_insn = print_insn_s390;
 #elif defined(__hppa__)
 print_insn = print_insn_hppa;
+#elif defined(__arc__)
+print_insn = print_insn_arc;
 #endif
 
 if (s.info.cap_arch >= 0 && cap_disas_host(, code, size, note)) {
diff --git a/disas/meson.build b/disas/meson.build
index bde8280c73..47ff300d0f 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -4,6 +4,7 @@ subdir('libvixl')
 common_ss.add(when: 'CONFIG_ALPHA_DIS', if_true: files('alpha.c'))
 common_ss.add(when: 'CONFIG_ARM_A64_DIS', if_true: files('arm-a64.cc'))
 common_ss.add_all(when: 'CONFIG_ARM_A64_DIS', if_true: libvixl_ss)
+common_ss.add(when: 'CONFIG_ARC_DIS', if_true: files('arc.c'))
 common_ss.add(when: 'CONFIG_ARM_DIS', if_true: files('arm.c'))
 common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c'))
 common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
diff --git a/hw/meson.build b/hw/meson.build
index 010de7219c..e2b14a9ed8 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -43,6 +43,7 @@ subdir('xen')
 subdir('xenpv')
 
 subdir('alpha')
+subdir('arc')
 subdir('arm')
 subdir('avr')
 subdir('cris')
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 9856bf7921..621164c510 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -206,7 +206,14 @@ enum bfd_architecture
   bfd_arch_v850,   /* NEC V850 */
 #define bfd_mach_v850  0
   bfd_arch_arc,/* Argonaut RISC Core */
-#define bfd_mach_arc_base 0
+#define bfd_mach_arc_a40
+#define bfd_mach_arc_a51
+#define bfd_mach_arc_arc6002
+#define bfd_mach_arc_arc6014
+#define bfd_mach_arc_arc7003
+#define bfd_mach_arc_arcv2 5
+#define bfd_mach_arc_arcv2em   6
+#define bfd_mach_arc_arcv2hs   7
   bfd_arch_m32r,   /* Mitsubishi M32R/D */
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
@@ -460,6 +467,7 @@ int print_insn_xtensa   (bfd_vma, 
disassemble_info*);
 int print_insn_riscv32  (bfd_vma, disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
 int print_insn_rx(bfd_vma, disassemble_info *);
+int print_insn_arc  (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/include/elf.h b/include/elf.h
index c117a4d1ab..5f6165da37 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -201,6 +201,9 @@ typedef struct mips_elf_abiflags_v0 {
 
 #define EM_TILEGX   191 /* TILE-Gx */
 
+#define EM_ARC_COMPACT  93  /* Synopsys ARCompact */
+#define EM_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */
+
 #define EM_MOXIE   223 /* Moxie processor family */
 #define EM_MOXIE_OLD   0xFEED
 
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 7b9ac361dc..635ccc66a1 100644
--- a/include/exec/poison.h
+++ 

[PATCH 12/14] arc: Add Synopsys ARC emulation boards

2020-09-30 Thread cupertinomiranda
From: Claudiu Zissulescu 

Add the Synopsys ARC boards, arc_sim for testing, sim-hs main emulation
board using standard UART and nsim which includes a Synopsys ARC specific
UART implementation.

Signed-off-by: Claudiu Zissulescu 
---
 hw/arc/Makefile.objs  |  21 +++
 hw/arc/arc_sim.c  | 143 
 hw/arc/arc_uart.c | 267 ++
 hw/arc/board-hsdk.c   | 107 +++
 hw/arc/boot.c |  95 ++
 hw/arc/boot.h |  21 +++
 hw/arc/meson.build|  13 ++
 hw/arc/nsim.c |  86 
 hw/arc/pic_cpu.c  | 111 
 hw/arc/sample.c   |  77 +++
 hw/arc/sim-hs.c   | 107 +++
 include/hw/arc/arc_uart.h |  43 ++
 include/hw/arc/cpudevs.h  |  10 ++
 13 files changed, 1101 insertions(+)
 create mode 100644 hw/arc/Makefile.objs
 create mode 100644 hw/arc/arc_sim.c
 create mode 100644 hw/arc/arc_uart.c
 create mode 100644 hw/arc/board-hsdk.c
 create mode 100644 hw/arc/boot.c
 create mode 100644 hw/arc/boot.h
 create mode 100644 hw/arc/meson.build
 create mode 100644 hw/arc/nsim.c
 create mode 100644 hw/arc/pic_cpu.c
 create mode 100644 hw/arc/sample.c
 create mode 100644 hw/arc/sim-hs.c
 create mode 100644 include/hw/arc/arc_uart.h
 create mode 100644 include/hw/arc/cpudevs.h

diff --git a/hw/arc/Makefile.objs b/hw/arc/Makefile.objs
new file mode 100644
index 00..28d7766cd9
--- /dev/null
+++ b/hw/arc/Makefile.objs
@@ -0,0 +1,21 @@
+#
+#  QEMU ARC CPU
+#
+#  Copyright (c) 2019
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  http://www.gnu.org/licenses/lgpl-2.1.html
+#
+
+obj-y   = arc_sim.o arc_uart.o sample.o pic_cpu.o boot.o board-hsdk.o sim-hs.o 
nsim.o
diff --git a/hw/arc/arc_sim.c b/hw/arc/arc_sim.c
new file mode 100644
index 00..8020a03d85
--- /dev/null
+++ b/hw/arc/arc_sim.c
@@ -0,0 +1,143 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "elf.h"
+#include "hw/char/serial.h"
+#include "net/net.h"
+#include "hw/loader.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "hw/arc/cpudevs.h"
+#include "boot.h"
+
+static void arc_sim_net_init(MemoryRegion *address_space,
+ hwaddr base,
+ hwaddr descriptors,
+ qemu_irq irq, NICInfo *nd)
+{
+DeviceState *dev;
+SysBusDevice *s;
+
+dev = qdev_new("open_eth");
+qdev_set_nic_properties(dev, nd);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+
+s = SYS_BUS_DEVICE(dev);
+sysbus_connect_irq(s, 0, irq);
+memory_region_add_subregion(address_space, base,
+sysbus_mmio_get_region(s, 0));
+memory_region_add_subregion(address_space, descriptors,
+sysbus_mmio_get_region(s, 1));
+}
+
+static uint64_t arc_io_read(void *opaque, hwaddr addr, unsigned size)
+{
+return 0;
+}
+
+static void arc_io_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+switch (addr) {
+case 0x08: /* board reset. */
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+break;
+default:
+break;
+}
+}
+
+static const MemoryRegionOps arc_io_ops = {
+.read = arc_io_read,
+.write = arc_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void arc_sim_init(MachineState *machine)
+{
+static struct arc_boot_info boot_info;
+unsigned int smp_cpus = 

[PATCH 11/14] arc: Add gdbstub and XML for debugging support

2020-09-30 Thread cupertinomiranda
From: Shahab Vahedi 

Register layout for the target and the mechanisms to read and set them.

Signed-off-by: Shahab Vahedi 
---
 gdb-xml/arc-aux-minimal.xml |  32 +++
 gdb-xml/arc-aux-other.xml   | 235 
 gdb-xml/arc-core-v2.xml |  45 
 target/arc/gdbstub.c| 421 
 4 files changed, 733 insertions(+)
 create mode 100644 gdb-xml/arc-aux-minimal.xml
 create mode 100644 gdb-xml/arc-aux-other.xml
 create mode 100644 gdb-xml/arc-core-v2.xml
 create mode 100644 target/arc/gdbstub.c

diff --git a/gdb-xml/arc-aux-minimal.xml b/gdb-xml/arc-aux-minimal.xml
new file mode 100644
index 00..7809c97a8d
--- /dev/null
+++ b/gdb-xml/arc-aux-minimal.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/arc-aux-other.xml b/gdb-xml/arc-aux-other.xml
new file mode 100644
index 00..86b114af98
--- /dev/null
+++ b/gdb-xml/arc-aux-other.xml
@@ -0,0 +1,235 @@
+
+
+
+
+
+  
+
+
+
+
+
+
+  
+  
+
+
+
+
+
+  
+  
+
+
+
+
+
+  
+  
+
+
+  
+  
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+
+
+
+  
+  
+
+
+
+
+
+
+  
+  
+
+
+
+
+
+
+
+
+  
+  
+
+
+
+  
+  
+
+  
+  
+
+
+
+  
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+
+
+
+  
+  
+
+
+
+
+
+  
+  
+
+
+  
+  
+
+
+
+
+  
+  
+
+
+  
+  
+
+
+
+
+
+
+
+  
+  
+
+
+
+  
+  
+
+
+  
+  
+
+
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/arc-core-v2.xml b/gdb-xml/arc-core-v2.xml
new file mode 100644
index 00..550dae3411
--- /dev/null
+++ b/gdb-xml/arc-core-v2.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/arc/gdbstub.c b/target/arc/gdbstub.c
new file mode 100644
index 00..574e8fdf4b
--- /dev/null
+++ b/target/arc/gdbstub.c
@@ -0,0 +1,421 @@
+
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+#include "qemu/osdep.h"
+#include "exec/gdbstub.h"
+#include "arc-common.h"
+#include "target/arc/regs.h"
+#include "internals.h"
+#include "irq.h"
+
+/* gets the register address for a particular processor */
+#define REG_ADDR(reg, processor_type) \
+arc_aux_reg_address_for((reg), (processor_type))
+
+int arc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+ARCCPU *cpu = ARC_CPU(cs);
+CPUARCState *env = >env;
+uint32_t regval = 0;
+
+switch (n) {
+case 0 ... 31:
+   regval = env->r[n];
+   break;
+case GDB_REG_58:
+   regval = env->r[58];
+   break;
+case GDB_REG_59:
+   regval = env->r[59];
+   break;
+case GDB_REG_60:
+   regval = env->r[60];
+   break;
+case GDB_REG_63:
+   regval = env->r[63];
+   break;
+default:
+   assert(!"Unsupported register is being read.");
+}
+
+return gdb_get_reg32(mem_buf, regval);
+}
+
+int arc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ARCCPU *cpu = ARC_CPU(cs);
+CPUARCState *env = >env;
+uint32_t regval = ldl_p(mem_buf);
+
+switch (n) {
+case 0 ... 31:
+env->r[n] = regval;
+break;
+case GDB_REG_58:
+env->r[58] = regval;
+break;
+case GDB_REG_59:
+env->r[59] = regval;
+break;
+case GDB_REG_60:
+env->r[60] = regval;
+break;
+case GDB_REG_63:
+env->r[63] = regval;
+break;
+default:
+

[PATCH 07/14] arc: Add BCR and AUX registers implementation

2020-09-30 Thread cupertinomiranda
From: Cupertino Miranda 

Add the infrastructure to define build configuration (BCR) and auxiliary
registers allowing independent modules (MMU, MPU, etc.) to use and extend
them.

Signed-off-by: Cupertino Miranda 
---
 target/arc/cache.c | 180 
 target/arc/cache.h |  42 +++
 target/arc/regs-detail.def | 542 +
 target/arc/regs.c  | 139 ++
 target/arc/regs.def| 399 +++
 target/arc/regs.h  | 118 
 6 files changed, 1420 insertions(+)
 create mode 100644 target/arc/cache.c
 create mode 100644 target/arc/cache.h
 create mode 100644 target/arc/regs-detail.def
 create mode 100644 target/arc/regs.c
 create mode 100644 target/arc/regs.def
 create mode 100644 target/arc/regs.h

diff --git a/target/arc/cache.c b/target/arc/cache.c
new file mode 100644
index 00..fe0921823b
--- /dev/null
+++ b/target/arc/cache.c
@@ -0,0 +1,180 @@
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2019 Synopsys, Inc.
+ *
+ * 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 .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "cpu.h"
+#include "target/arc/regs.h"
+#include "target/arc/cache.h"
+
+void arc_cache_aux_set(const struct arc_aux_reg_detail *aux_reg_detail,
+   uint32_t val, void *data)
+{
+
+CPUARCState *env = (CPUARCState *) data;
+struct arc_cache *cache = >cache;
+
+switch (aux_reg_detail->id) {
+case AUX_ID_ic_ivic:
+case AUX_ID_ic_ivil:
+case AUX_ID_dc_ivdc:
+case AUX_ID_dc_ivdl:
+case AUX_ID_dc_flsh:
+case AUX_ID_dc_fldl:
+case AUX_ID_dc_startr:
+   /* Do nothing as we don't simulate cache memories */
+   break;
+
+case AUX_ID_ic_ctrl:
+cache->ic_disabled = val & 1;
+break;
+
+case AUX_ID_ic_ivir:
+cache->ic_ivir = val & 0xff00;
+break;
+
+case AUX_ID_ic_endr:
+cache->ic_endr = val & 0xff00;
+break;
+
+case AUX_ID_ic_ptag:
+cache->ic_ptag = val;
+break;
+
+case AUX_ID_ic_ptag_hi:
+cache->ic_ptag_hi = val & 0xff;
+break;
+
+/*
+ * Description of the register content in order:
+ *   DC - Disable Cache: Enables/Disables the cache: 0 - Enabled, 1 - Disabled
+ *   IM - Invalidate Mode: Selects the invalidate type
+ */
+case AUX_ID_dc_ctrl:
+cache->dc_disabled = val & 1; /* DC */
+cache->dc_inv_mode = (val >> 6) & 1; /* IM */
+break;
+
+case AUX_ID_dc_endr:
+cache->dc_endr = val & 0xff00;
+break;
+
+case AUX_ID_dc_ptag_hi:
+cache->dc_ptag_hi = val & 0xff;
+break;
+
+default:
+hw_error("%s@%d: Attempt to write read-only register 0x%02x!\n",
+ __func__, __LINE__, (unsigned int)aux_reg_detail->id);
+break;
+}
+
+return;
+}
+
+uint32_t arc_cache_aux_get(const struct arc_aux_reg_detail *aux_reg_detail,
+   void *data)
+{
+CPUARCState *env = (CPUARCState *) data;
+struct arc_cache *cache = >cache;
+uint32_t reg = 0;
+
+switch (aux_reg_detail->id) {
+/*
+ * Description of the register content in order.
+ * Layout:   -DFF  
+ *   D - indicates that IC is disabled on reset
+ *   FL - Feature level: 10b - line lock, invalidate, advanced debug features
+ *   BSize - indicates the cache block size in bytes: 0011b - 64 bytes
+ *   Cache capacity: 0111b - 64 Kbytes
+ *   Cache Associativiy: 0010b - Four-way set associative
+ *   Version number: 4 - ARCv2
+ */
+case AUX_ID_i_cache_build:
+reg = (0 << 22) | /* D */
+  (2 << 20) | /* FL */
+  (3 << 16) | /* BBSixe*/
+  (7 << 12) | /* Cache capacity */
+  (2 << 8)  | /* Cache Associativiy */
+  (4 << 0);   /* Version Number */
+break;
+
+case AUX_ID_ic_ctrl:
+reg = cache->ic_disabled & 1;
+break;
+
+case AUX_ID_ic_ivir:
+reg = cache->ic_ivir;
+break;
+
+case AUX_ID_ic_endr:
+reg = cache->ic_endr;
+break;
+
+case AUX_ID_ic_ptag:
+reg = cache->ic_ptag;
+break;
+
+case AUX_ID_ic_ptag_hi:
+reg = cache->ic_ptag_hi;
+break;
+
+/*
+ * Description of the register content in order:
+ *   FL - Feature level: 10b - line lock, invalidate, advanced debug features
+ *   BSize - indicates the cache 

[PATCH 08/14] arc: Add IRQ and timer subsystem support

2020-09-30 Thread cupertinomiranda
From: Claudiu Zissulescu 

Signed-off-by: Claudiu Zissulescu 
---
 target/arc/irq.c   | 658 +
 target/arc/irq.h   |  37 +++
 target/arc/timer.c | 456 +++
 target/arc/timer.h |  32 +++
 4 files changed, 1183 insertions(+)
 create mode 100644 target/arc/irq.c
 create mode 100644 target/arc/irq.h
 create mode 100644 target/arc/timer.c
 create mode 100644 target/arc/timer.h

diff --git a/target/arc/irq.c b/target/arc/irq.c
new file mode 100644
index 00..ebbb2e1442
--- /dev/null
+++ b/target/arc/irq.c
@@ -0,0 +1,658 @@
+/*
+ * QEMU ARC CPU - IRQ subsystem
+ *
+ * Copyright (c) 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/irq.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "irq.h"
+#include "exec/cpu_ldst.h"
+#include "translate.h"
+#include "qemu/host-utils.h"
+
+/* Static functions and variables. */
+
+static uint32_t save_reg_pair_32[] = {
+0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
+};
+
+static uint32_t save_reg_pair_16[] = {
+0, 2, 10, 12, 14, 26, 28, 30
+};
+
+bool enabled_interrupts = false;
+
+/* Given a struct STATUS_R, pack it to 32 bit. */
+uint32_t pack_status32(status_t *status_r)
+{
+uint32_t res = 0x;
+
+res |= (status_r->IEf & 0x1) << 31;
+res |= (status_r->USf & 0x1) << 20;
+res |= (status_r->ADf & 0x1) << 19;
+res |= (status_r->RBf & 0x7) << 16;
+res |= (status_r->ESf & 0x1) << 15;
+res |= (status_r->SCf & 0x1) << 14;
+res |= (status_r->DZf & 0x1) << 13;
+res |= (status_r->Lf  & 0x1) << 12;
+res |= (status_r->Zf  & 0x1) << 11;
+res |= (status_r->Nf  & 0x1) << 10;
+res |= (status_r->Cf  & 0x1) << 9;
+res |= (status_r->Vf  & 0x1) << 8;
+res |= (status_r->Uf  & 0x1) << 7;
+res |= (status_r->DEf & 0x1) << 6;
+res |= (status_r->AEf & 0x1) << 5;
+res |= (status_r->Ef  & 0xf) << 1;
+
+return res;
+}
+
+/* Reverse of the above function. */
+void unpack_status32(status_t *status_r, uint32_t value)
+{
+status_r->IEf = ((value >> 31) & 0x1);
+status_r->USf = ((value >> 20) & 0x1);
+status_r->ADf = ((value >> 19) & 0x1);
+status_r->RBf = ((value >> 16) & 0x7);
+status_r->ESf = ((value >> 15) & 0x1);
+status_r->SCf = ((value >> 14) & 0x1);
+status_r->DZf = ((value >> 13) & 0x1);
+status_r->Lf  = ((value >> 12) & 0x1);
+status_r->Zf  = ((value >> 11) & 0x1);
+status_r->Nf  = ((value >> 10) & 0x1);
+status_r->Cf  = ((value >> 9)  & 0x1);
+status_r->Vf  = ((value >> 8)  & 0x1);
+status_r->Uf  = ((value >> 7)  & 0x1);
+status_r->DEf = ((value >> 6)  & 0x1);
+status_r->AEf = ((value >> 5)  & 0x1);
+status_r->Ef  = ((value >> 1)  & 0xf);
+}
+
+/* Return from fast interrupts. */
+
+static void arc_rtie_firq(CPUARCState *env)
+{
+assert(env->stat.AEf == 0);
+
+qemu_log_mask(CPU_LOG_INT, "[IRQ] exit firq: U=%d, AUX_IRQ_ACT.U=%d\n",
+  env->stat.Uf, env->aux_irq_act >> 31);
+
+/* Clear currently active interrupt. */
+env->aux_irq_act &= 0xfffe;
+
+/* Check if we need to restore userland SP. */
+if (((env->aux_irq_act & 0x) == 0) && (env->aux_irq_act & 0x8000)) 
{
+switchSP(env);
+}
+
+env->stat = env->stat_l1; /* FIXME use status32_p0 reg. */
+env->aux_irq_act &= ~(env->stat.Uf << 31); /* Keep U-bit in sync. */
+
+/* FIXME! fix current reg bank if RB bit is changed. */
+
+CPU_PCL(env) = CPU_ILINK(env);
+env->pc = CPU_ILINK(env);
+}
+
+/* Implements a pop operation from the CPU stack. */
+static uint32_t irq_pop(CPUARCState *env, const char *str)
+{
+uint32_t rval;
+rval = cpu_ldl_data(env, CPU_SP(env));
+
+qemu_log_mask(CPU_LOG_INT, "[IRQ] Pop [SP:0x%08x] => 0x%08x (%s)\n",
+  CPU_SP(env), rval, str ? str : "unk");
+CPU_SP(env) += 4;
+return rval;
+}
+
+/* Return from regular interrupts. */
+
+static void arc_rtie_irq(CPUARCState *env)
+{
+uint32_t tmp;
+ARCCPU *cpu = env_archcpu(env);
+
+assert((env->aux_irq_act & 0x) != 0);
+assert(env->stat.AEf == 0);
+
+/* Clear currently active interrupt. */
+tmp = ctz32(env->aux_irq_act & 0x);
+
+qemu_log_mask(CPU_LOG_INT,
+  

[PATCH 09/14] arc: Add memory management unit (MMU) support

2020-09-30 Thread cupertinomiranda
From: Cupertino Miranda 

Add Synopsys ARC MMU version 4 support. The implementation is
restricted to 8K page size support.

Signed-off-by: Cupertino Miranda 
---
 target/arc/mmu.c | 775 +++
 target/arc/mmu.h | 165 ++
 2 files changed, 940 insertions(+)
 create mode 100644 target/arc/mmu.c
 create mode 100644 target/arc/mmu.h

diff --git a/target/arc/mmu.c b/target/arc/mmu.c
new file mode 100644
index 00..77d0a2af97
--- /dev/null
+++ b/target/arc/mmu.c
@@ -0,0 +1,775 @@
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2018 Cupertino Miranda (cmira...@synopsys.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+#include "mmu.h"
+#include "target/arc/regs.h"
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+
+
+uint32_t
+arc_mmu_aux_get(const struct arc_aux_reg_detail *aux_reg_detail, void *data)
+{
+CPUARCState *env = (CPUARCState *) data;
+struct arc_mmu *mmu = >mmu;
+uint32_t reg = 0;
+
+switch (aux_reg_detail->id) {
+case AUX_ID_mmu_build:
+/*
+ * For now hardcode the TLB geometry and canonical page sizes
+ * MMUv4: 2M Super Page, 8k Page, 4 way set associative,
+ *1K entries (256x4), 4 uITLB, 8 uDTLB
+ */
+reg = 0x04e21a4a;
+break;
+case AUX_ID_tlbindex:
+reg = mmu->tlbindex;
+break;
+case AUX_ID_tlbpd0:
+reg = mmu->tlbpd0;
+break;
+case AUX_ID_tlbpd1:
+reg = mmu->tlbpd1;
+break;
+case AUX_ID_tlbpd1_hi:
+reg = mmu->tlbpd1_hi;
+break;
+case AUX_ID_scratch_data0:
+reg = mmu->scratch_data0;
+break;
+case AUX_ID_tlbcommand:
+reg = mmu->tlbcmd;
+break;
+case AUX_ID_pid:
+reg = (mmu->enabled << 31) | mmu->pid_asid;
+break;
+case AUX_ID_sasid0:
+reg = mmu->sasid0;
+break;
+case AUX_ID_sasid1:
+reg = mmu->sasid1;
+break;
+default:
+break;
+}
+
+return reg;
+}
+
+void
+arc_mmu_aux_set(const struct arc_aux_reg_detail *aux_reg_detail,
+uint32_t val, void *data)
+{
+CPUARCState *env = (CPUARCState *) data;
+CPUState *cs = env_cpu(env);
+struct arc_mmu *mmu = >mmu;
+
+switch (aux_reg_detail->id) {
+/* AUX_ID_tlbcommand is more involved and handled seperately */
+case AUX_ID_tlbindex:
+mmu->tlbindex = val;
+break;
+case AUX_ID_tlbpd0:
+mmu->tlbpd0 = val;
+break;
+case AUX_ID_tlbpd1:
+mmu->tlbpd1 = val;
+break;
+case AUX_ID_tlbpd1_hi:
+mmu->tlbpd1_hi = val;
+break;
+case AUX_ID_scratch_data0:
+mmu->scratch_data0 = val;
+break;
+case AUX_ID_pid:
+qemu_log_mask(CPU_LOG_MMU,
+  "[MMU] Writing PID_ASID with value 0x%08x at 0x%08x\n",
+  val, env->pc);
+mmu->enabled = (val >> 31);
+mmu->pid_asid = val & 0xff;
+tlb_flush(cs);
+break;
+case AUX_ID_sasid0:
+mmu->sasid0 = val;
+break;
+case AUX_ID_sasid1:
+mmu->sasid1 = val;
+break;
+default:
+break;
+}
+}
+
+/* vaddr can't have top bit */
+#define VPN(addr) ((addr) & (PAGE_MASK & (~0x8000)))
+#define PFN(addr) ((addr) & PAGE_MASK)
+
+static void
+arc_mmu_debug_tlb_for_set(CPUARCState *env, int set)
+{
+int j;
+bool set_printed = false;
+
+for (j = 0; j < N_WAYS; j++) {
+struct arc_tlb_e *tlb = >mmu.nTLB[set][j];
+
+if ((tlb->pd0 & PD0_V) != 0) {
+if (set_printed == false) {
+printf("set %d\n", set);
+set_printed = true;
+}
+if (set_printed == true) {
+printf(" way %d\n", j);
+}
+printf("  tlppd0: %08x: vaddr=\t%08x %s %s%s asid=%02x\n",
+   (unsigned int) tlb->pd0, (unsigned int) VPN(tlb->pd0),
+   (char *) ((tlb->pd0 & PD0_SZ) != 0 ? "sz1" : "sz0"),
+   (char *) ((tlb->pd0 & PD0_V) != 0 ? "V" : ""),
+   (char *) ((tlb->pd0 & PD0_G) != 0 ? "g" : ""),
+   tlb->pd0 & PD0_ASID);
+
+printf("  tlppd1: %08x: paddr=\t%08x k:%s%s%s u:%s%s%s f:%s\n",
+   (unsigned int) 

[PATCH 10/14] arc: Add memory protection unit (MPU) support

2020-09-30 Thread cupertinomiranda
From: Shahab Vahedi 

Add memory implementation for Synopsys MPU unit version 3.
Synopsys MPU allows to create memory regions against unauthorized
execution/read/writes accesses.

Signed-off-by: Shahab Vahedi 
---
 target/arc/mpu.c | 653 +++
 target/arc/mpu.h | 140 ++
 2 files changed, 793 insertions(+)
 create mode 100644 target/arc/mpu.c
 create mode 100644 target/arc/mpu.h

diff --git a/target/arc/mpu.c b/target/arc/mpu.c
new file mode 100644
index 00..60f56100d0
--- /dev/null
+++ b/target/arc/mpu.c
@@ -0,0 +1,653 @@
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2019 Shahab Vahedi (Synopsys)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "mpu.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "mmu.h"
+
+/*
+ * In case of exception, this signals the effective region
+ * was the default one
+ */
+#define MPU_DEFAULT_REGION_NR 0xff
+
+/* Defines used by in-house functions */
+#define MPU_EN_EN_BIT   30
+#define MPU_EN_KR_BIT8
+#define MPU_EN_KW_BIT7
+#define MPU_EN_KE_BIT6
+#define MPU_EN_UR_BIT5
+#define MPU_EN_UW_BIT4
+#define MPU_EN_UE_BIT3
+
+#define MPU_ECR_EC_CODE_BIT 16
+#define MPU_ECR_VT_BIT   8
+
+#define MPU_BASE_ADDR_MASK  0xffe0  /* ignore least 5 bits */
+#define MPU_BASE_VALID_MASK 0x0001  /* bit #0 */
+
+/*
+ * Given a number of bits as width, calc the mask to
+ * "and" with. e.g.: 3 bits --> 8 - 1 --> 7 (111b)
+ */
+#define MPU_WIDTH_TO_MASK(w) ((1 << (w)) - 1)
+#define MPU_PERMS_REG_LOWER_SIZE_WIDTH  2
+#define MPU_PERMS_REG_HIGHER_SIZE_WIDTH 3
+#define MPU_PERMS_REG_HIGHER_SIZE_POS   9
+
+/*
+ * After knowing the operating mode (user/kernel),
+ * this struct represents the effective permissions.
+ */
+typedef struct MPUEffectPerm {
+bool read;
+bool write;
+bool exec;
+} MPUEffectPerm;
+
+/* Packer and unpackers (local to this translation unit) */
+static inline uint32_t pack_enable(const bool ena)
+{
+return ena << MPU_EN_EN_BIT;
+}
+
+static inline void unpack_enable(bool *enabled, uint32_t value)
+{
+*enabled = (value >> MPU_EN_EN_BIT) & 1;
+}
+
+static inline uint32_t pack_permissions(const MPUPermissions *perms)
+{
+return perms->KR << MPU_EN_KR_BIT |
+   perms->KW << MPU_EN_KW_BIT |
+   perms->KE << MPU_EN_KE_BIT |
+   perms->UR << MPU_EN_UR_BIT |
+   perms->UW << MPU_EN_UW_BIT |
+   perms->UE << MPU_EN_UE_BIT;
+}
+
+static inline void unpack_permissions(MPUPermissions *perms, uint32_t value)
+{
+perms->KR = (value >> MPU_EN_KR_BIT) & 1;
+perms->KW = (value >> MPU_EN_KW_BIT) & 1;
+perms->KE = (value >> MPU_EN_KE_BIT) & 1;
+perms->UR = (value >> MPU_EN_UR_BIT) & 1;
+perms->UW = (value >> MPU_EN_UW_BIT) & 1;
+perms->UE = (value >> MPU_EN_UE_BIT) & 1;
+}
+
+static inline uint32_t pack_enable_reg(const MPUEnableReg *mpuen)
+{
+return pack_enable(mpuen->enabled) |
+   pack_permissions(>permission);
+}
+
+static inline void unpack_enable_reg(MPUEnableReg *mpuen, uint32_t value)
+{
+unpack_enable(>enabled, value);
+unpack_permissions(>permission, value);
+}
+
+static inline uint32_t pack_ecr(const MPUECR *mpuecr)
+{
+return ARC_MPU_ECR_VEC_NUM << MPU_ECR_EC_CODE_BIT |
+   (mpuecr->violation & 3) << MPU_ECR_VT_BIT  |
+   mpuecr->region;
+}
+
+static inline uint32_t pack_base_reg(const MPUBaseReg *mpurdb)
+{
+return mpurdb->addr | mpurdb->valid;
+}
+
+static inline void unpack_base_reg(MPUBaseReg *mpurdb, uint32_t value)
+{
+mpurdb->addr  = value & MPU_BASE_ADDR_MASK;
+mpurdb->valid = value & MPU_BASE_VALID_MASK;
+}
+
+
+/*
+ * Break the "size" field into "higher" and "lower" parts
+ * e.g.: a b c d e --> a b c . . . d e
+ * higher lower
+ */
+static uint32_t pack_region_size_bits(uint8_t size_bits)
+{
+uint32_t lower =
+size_bits & MPU_WIDTH_TO_MASK(MPU_PERMS_REG_LOWER_SIZE_WIDTH);
+uint32_t higher = size_bits >> MPU_PERMS_REG_LOWER_SIZE_WIDTH;
+higher &= MPU_WIDTH_TO_MASK(MPU_PERMS_REG_HIGHER_SIZE_WIDTH);
+return (higher << MPU_PERMS_REG_HIGHER_SIZE_POS) | lower;
+}
+
+/*
+ * Put the higher and lower parts of "size" field together
+ * e.g.: a b c . . . d e ---> abcde
+ *   higher lower
+ */
+static void unpack_region_size_bits(uint8_t *size_bits, 

[PATCH 04/14] arc: TCG and decoder glue code and helpers

2020-09-30 Thread cupertinomiranda
From: Cupertino Miranda 

Signed-off-by: Cupertino Miranda 
---
 target/arc/extra_mapping.def   |  40 ++
 target/arc/helper.c| 293 +
 target/arc/helper.h|  46 ++
 target/arc/op_helper.c | 749 +
 target/arc/semfunc_mapping.def | 329 +++
 5 files changed, 1457 insertions(+)
 create mode 100644 target/arc/extra_mapping.def
 create mode 100644 target/arc/helper.c
 create mode 100644 target/arc/helper.h
 create mode 100644 target/arc/op_helper.c
 create mode 100644 target/arc/semfunc_mapping.def

diff --git a/target/arc/extra_mapping.def b/target/arc/extra_mapping.def
new file mode 100644
index 00..6bc36d8d46
--- /dev/null
+++ b/target/arc/extra_mapping.def
@@ -0,0 +1,40 @@
+/*
+ * QEMU ARC EXTRA MAPPING
+ *
+ * Copyright (c) 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+SEMANTIC_FUNCTION(SWI, 1)
+SEMANTIC_FUNCTION(SWI, 1)
+SEMANTIC_FUNCTION(UNIMP, 0)
+SEMANTIC_FUNCTION(RTIE, 0)
+SEMANTIC_FUNCTION(SLEEP, 1)
+
+MAPPING(swi, SWI, 0)
+CONSTANT(SWI, swi_s, 0, 0)
+MAPPING(swi_s, SWI, 1, 0)
+MAPPING(trap_s, TRAP, 1, 0)
+MAPPING(rtie, RTIE, 0)
+MAPPING(sleep, SLEEP, 1, 0)
+MAPPING(vadd2, VADD, 3, 0, 1, 2)
+MAPPING(vadd2h, VADD, 3, 0, 1, 2)
+MAPPING(vadd4h, VADD, 3, 0, 1, 2)
+MAPPING(vsub2, VSUB, 3, 0, 1, 2)
+MAPPING(vsub2h, VSUB, 3, 0, 1, 2)
+MAPPING(vsub4h, VSUB, 3, 0, 1, 2)
+MAPPING(mpyd, MPYD, 3, 0, 1, 2)
+MAPPING(mpydu, MPYD, 3, 0, 1, 2)
diff --git a/target/arc/helper.c b/target/arc/helper.c
new file mode 100644
index 00..cbc072e66b
--- /dev/null
+++ b/target/arc/helper.c
@@ -0,0 +1,293 @@
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2019
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+#include "qemu/osdep.h"
+
+#include "cpu.h"
+#include "hw/irq.h"
+#include "include/hw/sysbus.h"
+#include "include/sysemu/sysemu.h"
+#include "qemu/qemu-print.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "irq.h"
+
+#if defined(CONFIG_USER_ONLY)
+
+void arc_cpu_do_interrupt(CPUState *cs)
+{
+ARCCPU *cpu = ARC_CPU(cs);
+CPUARCState *env = >env;
+
+cs->exception_index = -1;
+CPU_ILINK(env) = env->pc;
+}
+
+#else /* !CONFIG_USER_ONLY */
+
+void arc_cpu_do_interrupt(CPUState *cs)
+{
+ARCCPU  *cpu= ARC_CPU(cs);
+CPUARCState *env= >env;
+uint32_t offset = 0;
+uint32_t vectno;
+const char  *name;
+
+/*
+ * NOTE: Special LP_END exception. Immediatelly return code execution to
+ * lp_start.
+ * Now also used for delayslot MissI cases.
+ * This special exception should not execute any of the exception
+ * handling code. Instead it returns immediately after setting PC to the
+ * address passed as exception parameter.
+ */
+if (cs->exception_index == EXCP_LPEND_REACHED
+|| cs->exception_index == EXCP_FAKE) {
+env->pc = env->param;
+CPU_PCL(env) = env->pc & 0xfffe;
+return;
+}
+
+/* If we take an exception within an exception => fatal Machine Check. */
+if (env->stat.AEf == 1) {
+cs->exception_index = EXCP_MACHINE_CHECK;
+env->causecode = 0;
+env->param = 0;
+env->mmu.enabled = false; /* no more MMU */
+env->mpu.enabled = false; /* no more MPU */
+}
+vectno = cs->exception_index & 0x0F;
+offset = vectno << 2;
+
+/* Generic computation for exceptions. */
+switch (cs->exception_index) {
+case EXCP_RESET:
+name = "Reset";
+break;
+case EXCP_MEMORY_ERROR:
+name = "Memory Error";
+break;
+case EXCP_INST_ERROR:
+

[PATCH 05/14] arc: TCG instruction generator and hand-definitions

2020-09-30 Thread cupertinomiranda
From: Shahab Vahedi 

Add the most generic parts of TCG constructions. It contains the basic 
infrastructure
for fundamental ARC features, such as ZOL (zero overhead loops) and delay-slots.
Also includes hand crafted TCG for more intricate instructions, such as vector
instructions.

Signed-off-by: Shahab Vahedi 
---
 target/arc/translate.c | 1344 
 target/arc/translate.h |  202 ++
 2 files changed, 1546 insertions(+)
 create mode 100644 target/arc/translate.c
 create mode 100644 target/arc/translate.h

diff --git a/target/arc/translate.c b/target/arc/translate.c
new file mode 100644
index 00..1d679db943
--- /dev/null
+++ b/target/arc/translate.c
@@ -0,0 +1,1344 @@
+/*
+ *  QEMU ARC CPU
+ * Copyright (C) 2019 Free Software Foundation, Inc.
+
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with GAS or GDB; see the file COPYING3.  If not, write to
+ * the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "translate.h"
+#include "qemu/qemu-print.h"
+#include "tcg/tcg-op-gvec.h"
+#include "target/arc/semfunc.h"
+#include "target/arc/arc-common.h"
+
+/* Globals */
+TCGvcpu_gp;/*  Global Pointer  */
+TCGvcpu_fp;/*  Frame Pointer   */
+TCGvcpu_sp;/*  Stack Pointer   */
+TCGvcpu_ilink1;/*  Level 1 interrupt link register */
+TCGvcpu_ilink2;/*  Level 2 interrupt link register */
+TCGvcpu_blink; /*  Branch link register*/
+TCGvcpu_acclo; /*  64-bit accumulator register: low*/
+TCGvcpu_acchi; /*  64-bit accumulator register: high   */
+TCGvcpu_limm;  /*  Long immediate data indicator   */
+TCGvcpu_pcl;   /*  Program Counter [31:2], read-only.  */
+
+TCGvcpu_S1f;
+TCGvcpu_S2f;
+TCGvcpu_CSf;
+
+TCGvcpu_Lf;
+TCGvcpu_Zf;
+TCGvcpu_Nf;
+TCGvcpu_Cf;
+TCGvcpu_Vf;
+TCGvcpu_Uf;
+
+TCGvcpu_DEf;
+TCGvcpu_ESf;
+TCGvcpu_AEf;
+TCGvcpu_Hf;
+TCGvcpu_IEf;
+TCGvcpu_Ef;
+
+TCGvcpu_is_delay_slot_instruction;
+
+TCGvcpu_l1_Lf;
+TCGvcpu_l1_Zf;
+TCGvcpu_l1_Nf;
+TCGvcpu_l1_Cf;
+TCGvcpu_l1_Vf;
+TCGvcpu_l1_Uf;
+
+TCGvcpu_l1_DEf;
+TCGvcpu_l1_AEf;
+TCGvcpu_l1_Hf;
+
+TCGvcpu_l2_Lf;
+TCGvcpu_l2_Zf;
+TCGvcpu_l2_Nf;
+TCGvcpu_l2_Cf;
+TCGvcpu_l2_Vf;
+TCGvcpu_l2_Uf;
+
+TCGvcpu_l2_DEf;
+TCGvcpu_l2_AEf;
+TCGvcpu_l2_Hf;
+
+TCGvcpu_er_Lf;
+TCGvcpu_er_Zf;
+TCGvcpu_er_Nf;
+TCGvcpu_er_Cf;
+TCGvcpu_er_Vf;
+TCGvcpu_er_Uf;
+
+TCGvcpu_er_DEf;
+TCGvcpu_er_AEf;
+TCGvcpu_er_Hf;
+
+TCGvcpu_eret;
+TCGvcpu_erbta;
+TCGvcpu_ecr;
+TCGvcpu_efa;
+
+TCGvcpu_bta;
+TCGvcpu_bta_l1;
+TCGvcpu_bta_l2;
+
+TCGvcpu_pc;
+TCGvcpu_lpc;
+/* replaced by AUX_REG array */
+TCGvcpu_lps;
+TCGvcpu_lpe;
+
+TCGvcpu_r[64];
+
+TCGvcpu_intvec;
+
+TCGvcpu_debug_LD;
+TCGvcpu_debug_SH;
+TCGvcpu_debug_BH;
+TCGvcpu_debug_UB;
+TCGvcpu_debug_ZZ;
+TCGvcpu_debug_RA;
+TCGvcpu_debug_IS;
+TCGvcpu_debug_FH;
+TCGvcpu_debug_SS;
+
+TCGvcpu_lock_lf_var;
+
+/* NOTE: Pseudo register required for comparison with lp_end */
+TCGvcpu_npc;
+
+/* Macros */
+
+#include "exec/gen-icount.h"
+#define REG(x)  (cpu_r[x])
+
+/* macro used to fix middle-endianess. */
+#define ARRANGE_ENDIAN(endianess, buf)  \
+((endianess) ? arc_getm32(buf) : bswap32(buf))
+
+/*
+ * The macro to add boiler plate code for conditional execution.
+ * It will add tcg_gen codes only if there is a condition to
+ * be checked (ctx->insn.cc != 0). This macro assumes that there
+ * is a "ctx" variable of type "DisasCtxt *" in context. Remember
+ * to pair it with CC_EPILOGUE macro.
+ */
+#define CC_PROLOGUE   \
+  TCGv cc = tcg_temp_local_new(); \
+  TCGLabel *done = gen_new_label();   \
+  do {\
+if (ctx->insn.cc) {   \
+arc_gen_verifyCCFlag(ctx, cc);\
+tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done); \
+} \
+  } while (0)
+
+/*
+ * The finishing counter part of CC_PROLUGE. This is supposed
+ * to be put at the 

[PATCH 02/14] arc: Decoder code

2020-09-30 Thread cupertinomiranda
From: Claudiu Zissulescu 

The decoder and the disassembler inspired by ARC GNU binutils.

Signed-off-by: Claudiu Zissulescu 
---
 disas/arc.c |  460 ++
 target/arc/decoder.c| 1276 +++
 target/arc/decoder.h|  350 +++
 target/arc/flags.def|   85 +++
 target/arc/operands.def |  123 
 5 files changed, 2294 insertions(+)
 create mode 100644 disas/arc.c
 create mode 100644 target/arc/decoder.c
 create mode 100644 target/arc/decoder.h
 create mode 100644 target/arc/flags.def
 create mode 100644 target/arc/operands.def

diff --git a/disas/arc.c b/disas/arc.c
new file mode 100644
index 00..1041b5a5b5
--- /dev/null
+++ b/disas/arc.c
@@ -0,0 +1,460 @@
+/*
+ * Disassembler code for ARC.
+ * Copyright 2020 Free Software Foundation, Inc.
+ * Written by Claudiu Zissulescu.
+ *
+ * QEMU ARCv2 Disassembler.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "disas/dis-asm.h"
+#include "target/arc/arc-common.h"
+#include "target/arc/decoder.h"
+#include "target/arc/regs.h"
+
+/* Register names. */
+
+static const char * const regnames[64] = {
+"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "fp", "sp", "ilink", "r30", "blink",
+
+"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+"r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
+"r56", "r57", "r58", "r59", "lp_count", "rezerved", "LIMM", "pcl"
+};
+
+#define ARRANGE_ENDIAN(info, buf)   \
+(info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32(bfd_getl32(buf))\
+ : bfd_getb32(buf))
+
+/*
+ * Helper function to convert middle-endian data to something more
+ * meaningful.
+ */
+
+static bfd_vma bfd_getm32(unsigned int data)
+{
+bfd_vma value = 0;
+
+value  = (data & 0x) << 16;
+value |= (data & 0x) >> 16;
+return value;
+}
+
+/* Helper for printing instruction flags. */
+
+static bfd_boolean special_flag_p(const char *opname, const char *flgname)
+{
+const struct arc_flag_special *flg_spec;
+unsigned i, j, flgidx;
+
+for (i = 0; i < arc_num_flag_special; ++i) {
+flg_spec = _flag_special_cases[i];
+
+if (strcmp(opname, flg_spec->name) != 0) {
+continue;
+}
+
+/* Found potential special case instruction. */
+for (j = 0; ; ++j) {
+flgidx = flg_spec->flags[j];
+if (flgidx == 0) {
+break; /* End of the array. */
+}
+
+if (strcmp(flgname, arc_flag_operands[flgidx].name) == 0) {
+return TRUE;
+}
+}
+}
+return FALSE;
+}
+
+/* Print instruction flags. */
+
+static void print_flags(const struct arc_opcode *opcode,
+uint64_t insn,
+struct disassemble_info *info)
+{
+const unsigned char *flgidx;
+unsigned int value;
+
+/* Now extract and print the flags. */
+for (flgidx = opcode->flags; *flgidx; flgidx++) {
+/* Get a valid flag class. */
+const struct arc_flag_class *cl_flags = _flag_classes[*flgidx];
+const unsigned *flgopridx;
+
+/* Check first the extensions. Not supported yet. */
+if (cl_flags->flag_class & F_CLASS_EXTEND) {
+value = insn & 0x1F;
+}
+
+for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) {
+const struct arc_flag_operand *flg_operand =
+_flag_operands[*flgopridx];
+
+/* Implicit flags are only used for the insn decoder. */
+if (cl_flags->flag_class & F_CLASS_IMPLICIT) {
+continue;
+}
+
+if (!flg_operand->favail) {
+continue;
+}
+
+value = (insn >> flg_operand->shift) &
+((1 << flg_operand->bits) - 1);
+if (value == flg_operand->code) {
+/* FIXME!: print correctly nt/t flag. */
+if (!special_flag_p(opcode->name, flg_operand->name)) {
+(*info->fprintf_func)(info->stream, ".");
+}
+  

[PATCH 01/14] arc: Add initial core cpu files

2020-09-30 Thread cupertinomiranda
From: Cupertino Miranda 

Signed-off-by: Cupertino Miranda 
---
 target/arc/Makefile.objs |  34 +++
 target/arc/arc-common.h  |  55 
 target/arc/cpu-param.h   |  20 ++
 target/arc/cpu-qom.h |  53 
 target/arc/cpu.c | 468 ++
 target/arc/cpu.h | 532 +++
 target/arc/internals.h   |  37 +++
 target/arc/meson.build   |  20 ++
 8 files changed, 1219 insertions(+)
 create mode 100644 target/arc/Makefile.objs
 create mode 100644 target/arc/arc-common.h
 create mode 100644 target/arc/cpu-param.h
 create mode 100644 target/arc/cpu-qom.h
 create mode 100644 target/arc/cpu.c
 create mode 100644 target/arc/cpu.h
 create mode 100644 target/arc/internals.h
 create mode 100644 target/arc/meson.build

diff --git a/target/arc/Makefile.objs b/target/arc/Makefile.objs
new file mode 100644
index 00..7b2afd08e4
--- /dev/null
+++ b/target/arc/Makefile.objs
@@ -0,0 +1,34 @@
+#
+#  QEMU ARC CPU
+#
+#  Copyright (c) 2020
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+obj-y   += translate.o
+obj-y   += helper.o
+obj-y   += cpu.o
+obj-y   += op_helper.o
+obj-y   += gdbstub.o
+obj-y   += decoder.o
+obj-y   += regs.o
+obj-y   += semfunc.o
+obj-y   += semfunc-helper.o
+obj-y   += mmu.o
+obj-y   += mpu.o
+obj-y   += timer.o
+obj-y   += irq.o
+obj-y   += cache.o
diff --git a/target/arc/arc-common.h b/target/arc/arc-common.h
new file mode 100644
index 00..8013e1d2ed
--- /dev/null
+++ b/target/arc/arc-common.h
@@ -0,0 +1,55 @@
+/*
+ *  Common header file to be used by cpu and disassembler.
+ *  Copyright (C) 2017 Free Software Foundation, Inc.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GAS or GDB; see the file COPYING3. If not, write to
+ *  the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ */
+
+#ifndef ARC_COMMON_H
+#define ARC_COMMON_H
+
+#include "qemu/osdep.h"
+
+/* CPU combi. */
+#define ARC_OPCODE_ARCALL  (ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700   \
+| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS)
+#define ARC_OPCODE_ARCFPX  (ARC_OPCODE_ARC700 | ARC_OPCODE_ARCv2EM)
+#define ARC_OPCODE_ARCV1   (ARC_OPCODE_ARC700 | ARC_OPCODE_ARC600)
+#define ARC_OPCODE_ARCV2   (ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS)
+#define ARC_OPCODE_ARCMPY6E  (ARC_OPCODE_ARC700 | ARC_OPCODE_ARCV2)
+
+
+enum arc_cpu_family {
+  ARC_OPCODE_NONE= 0,
+  ARC_OPCODE_DEFAULT = 1 << 0,
+  ARC_OPCODE_ARC600  = 1 << 1,
+  ARC_OPCODE_ARC700  = 1 << 2,
+  ARC_OPCODE_ARCv2EM = 1 << 3,
+  ARC_OPCODE_ARCv2HS = 1 << 4
+};
+
+typedef struct {
+uint32_t value;
+uint32_t type;
+} operand_t;
+
+typedef struct {
+uint32_t class;
+uint32_t limm;
+uint8_t len;
+bool limm_p;
+operand_t operands[3];
+uint8_t n_ops;
+uint8_t cc;
+uint8_t aa;
+uint8_t zz;
+bool d;
+bool f;
+bool di;
+bool x;
+} insn_t;
+
+#endif
diff --git a/target/arc/cpu-param.h b/target/arc/cpu-param.h
new file mode 100644
index 00..a38548d3db
--- /dev/null
+++ b/target/arc/cpu-param.h
@@ -0,0 +1,20 @@
+/*
+ * ARC cpu parameters for qemu.
+ *
+ * Copyright (c) 2019 Shahab Vahedi
+ * SPDX-License-Identifier: LGPL-2.0+
+ */
+
+#ifndef ARC_CPU_PARAM_H
+#define ARC_CPU_PARAM_H 1
+
+#define TARGET_LONG_BITS32
+#define TARGET_PAGE_BITS13
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#define NB_MMU_MODES2
+
+#endif
+
+/*-*-indent-tabs-mode:nil;tab-width:4;indent-line-function:'insert-tab'-*-*/
+/* vim: set ts=4 sw=4 et: */
diff --git a/target/arc/cpu-qom.h b/target/arc/cpu-qom.h
new file mode 100644
index 00..413b693558
--- /dev/null
+++ b/target/arc/cpu-qom.h
@@ -0,0 +1,53 @@
+/*
+ * QEMU ARC CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 

[PATCH 00/14] *** ARC port for review ***

2020-09-30 Thread cupertinomiranda
From: Cupertino Miranda 

Hello everyone,

It is with utmost pleasure that on behalf of Synopsys I initiate the
upstream process for our ARCv2 architecture QEMU port.

I am one of the main contributors to this port and member of the
Synopsys GNU toolchain team, together with Claudiu Zissulescu and 
Shahab Vahedi.

ARCv2 processors use RISC, and employ the 16-/32-bit instruction set
architecture (ISA).
ARC processors are configurable and extensible for a wide range of uses
in system on a chip (SoC) devices.
It is a common processor in deeply embedded systems, used in storage,
digital home, mobile, automotive, and Internet of Things (IoT) 
applications.

To facilitate reviewing, we split the files through several commits,
attempting to keep file size to reviewable chunks.

The port as presented implements the system softmmu hardware emulation,
capable to boot and run Linux kernel.
It has also been integrated as a patch in Zephyr project, where it is
being used.
To validate and guarantee correctness of the port through development, 
we have created TCG tests from the very beggining, covering the most 
fundamental CPU features.
For the remaining instructions we validate the port through compiler 
testsuites, like DejaGNU, comparing results with real hardware 
executions.

Would like also to thank our colleagues Vineet Gupta and Alexey Broadkin
for their contributions, which due to the collapse of the development
commits, got their contributions overcast by major ones.

Link for Synopsys ARC processor page:
 - https://www.synopsys.com/designware-ip/processor-solutions.html

ARC PRM for both HS and EM processors can be found in:
 - 
https://www.synopsys.com/dw/doc.php/ds/cc/programmers-reference-manual-ARC-EM.pdf
 - 
https://www.synopsys.com/dw/doc.php/ds/cc/programmers-reference-manual-ARC-HS.pdf.

Looking forward to your comments and suggestions.

Best regards,
Cupertino Miranda

*** BLURB HERE ***

Claudiu Zissulescu (5):
  arc: Decoder code
  arc: Opcode definitions table
  arc: Add IRQ and timer subsystem support
  arc: Add Synopsys ARC emulation boards
  tests/tcg: ARC: Add TCG instruction definition tests

Cupertino Miranda (5):
  arc: Add initial core cpu files
  arc: TCG and decoder glue code and helpers
  arc: TCG instruction definitions
  arc: Add BCR and AUX registers implementation
  arc: Add memory management unit (MMU) support

Shahab Vahedi (4):
  arc: TCG instruction generator and hand-definitions
  arc: Add memory protection unit (MPU) support
  arc: Add gdbstub and XML for debugging support
  arc: Add support for ARCv2

 configure | 5 +
 default-configs/arc-softmmu.mak   | 5 +
 disas.c   | 2 +
 disas/arc.c   |   460 +
 disas/meson.build | 1 +
 gdb-xml/arc-aux-minimal.xml   |32 +
 gdb-xml/arc-aux-other.xml |   235 +
 gdb-xml/arc-core-v2.xml   |45 +
 hw/arc/Makefile.objs  |21 +
 hw/arc/arc_sim.c  |   143 +
 hw/arc/arc_uart.c |   267 +
 hw/arc/board-hsdk.c   |   107 +
 hw/arc/boot.c |95 +
 hw/arc/boot.h |21 +
 hw/arc/meson.build|13 +
 hw/arc/nsim.c |86 +
 hw/arc/pic_cpu.c  |   111 +
 hw/arc/sample.c   |77 +
 hw/arc/sim-hs.c   |   107 +
 hw/meson.build| 1 +
 include/disas/dis-asm.h   |10 +-
 include/elf.h | 3 +
 include/exec/poison.h | 2 +
 include/hw/arc/arc_uart.h |43 +
 include/hw/arc/cpudevs.h  |10 +
 include/sysemu/arch_init.h| 1 +
 meson.build   | 3 +-
 softmmu/arch_init.c   | 2 +
 target/arc/Makefile.objs  |34 +
 target/arc/arc-common.h   |55 +
 target/arc/cache.c|   180 +
 target/arc/cache.h|42 +
 target/arc/cpu-param.h|20 +
 target/arc/cpu-qom.h  |53 +
 target/arc/cpu.c  |   468 +
 target/arc/cpu.h  |   532 +
 target/arc/decoder.c  |  1276 ++
 target/arc/decoder.h  |   350 +
 target/arc/extra_mapping.def  |40 +
 target/arc/flags.def  |85 +
 target/arc/gdbstub.c  |   421 +
 target/arc/helper.c   |   293 +
 target/arc/helper.h   |46 +
 target/arc/internals.h|37 +
 target/arc/irq.c  |   658 +
 target/arc/irq.h  |37 +
 target/arc/meson.build|20 +
 target/arc/mmu.c  |   775 +
 target/arc/mmu.h  |   165 +
 

[PULL v8 00/86] Misc QEMU patches for 2020-09-24

2020-09-30 Thread Paolo Bonzini
The following changes since commit cbba3dc6ea3fc9aa66e9f9eb41051536e3ad7cd0:

  Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging 
(2020-09-30 11:40:38 +0100)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 37aeb7a28ddbf52dd25dd53ae1b8391bc2287858:

  hw/net/can: Correct Kconfig dependencies (2020-09-30 19:11:37 +0200)


* SCSI fix (Dmitry, Li Feng, Li Qiang)
* memory API fixes (Eduardo)
* removal of deprecated '-numa node', 'cpu-add', '-smp' (Igor)
* ACPI fix for VMBus (Jon)
* relocatable install (myself)
* always remove docker containers (myself)
* serial cleanups (Philippe)
* vmware cpuid leaf for tsc and apic frequency (Sunil)
* KVM_FEATURE_ASYNC_PF_INT support (Vitaly)
* i386 XSAVE bugfix (Xiaoyao)
* QOM developer documentation in docs/devel (Eduardo)
* new checkpatch tests (Dov)
* x86_64 syscall fix (Douglas)
* interrupt-based APF fix (Vitaly)
* always create kvmclock (Vitaly)
* fix bios-tables-test (Eduardo)
* KVM PV features cleanup (myself)
* CAN FD (Pavel)

meson:
* fixes (Marc-André, Max, Stefan, Alexander, myself)
* moved libmpathpersist, cocoa, malloc tests (myself)
* support for 0.56 introspected test dependencies (myself)


Alexander Bulekov (1):
  oss-fuzz: move linker arg to fix coverage-build

Anthony PERARD (1):
  meson: fix installation of keymaps

Claudio Fontana (1):
  tests: add missing genh dependency

Daniel P. Berrangé (1):
  char: fix logging when chardev write fails

Dmitry Fomichev (1):
  scsi-generic: Fix HM-zoned device scan

Douglas Crosher (1):
  helper_syscall x86_64: clear exception_is_int

Dov Murik (1):
  checkpatch: Detect '%#' or '%0#' in printf-style format strings

Eduardo Habkost (10):
  memory: Convert IOMMUMemoryRegionClass doc comment to kernel-doc
  qom: Document all function parameters in doc comments
  qom: Use kernel-doc private/public tags in structs
  qom: Use ``code`` Sphinx syntax where appropriate
  qom: Add kernel-doc markup to introduction doc comment
  qom: Reformat section titles using Sphinx syntax
  qom: Indent existing code examples
  qom: Add code block markup to all code blocks
  docs: Create docs/devel/qom.rst
  bios-tables-test: Remove kernel-irqchip=off option

Igor Mammedov (4):
  numa: drop support for '-numa node' (without memory specified)
  doc: Cleanup "'-mem-path' fallback to RAM" deprecation text
  numa: remove fixup numa_state->num_nodes to MAX_NODES
  smp: drop support for deprecated (invalid topologies)

Jan Charvat (5):
  net/can: Initial host SocketCan support for CAN FD.
  hw/net/can: sja1000 ignore CAN FD frames
  net/can: Add can_dlc2len and can_len2dlc for CAN FD.
  hw/net/can/ctucafd: Add CTU CAN FD core register definitions.
  hw/net/can: CTU CAN FD IP open hardware core emulation.

Jon Doron (1):
  acpi: i386: Move VMBus DSDT entry to SB

Li Feng (1):
  vhost-scsi: support inflight io track

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

Marc-André Lureau (2):
  meson: fix MSI rule
  meson: error out if qemu_suffix starts with /

Paolo Bonzini (28):
  meson: clean up build_by_default
  ninjatool: rebuild multi-output targets if outputs are missing
  meson: move libudev test
  meson: move libmpathpersist test
  meson: extend libmpathpersist test for static linking
  configure: move malloc_trim/tcmalloc/jemalloc to meson
  configure: fix --meson=/path/to/meson
  configure: move cocoa option to Meson
  configure: do not limit Hypervisor.framework test to Darwin
  meson: qtest: set "depends" correctly
  mtest2make: add support for introspected test dependencies
  meson: report accelerator support
  oslib: do not call g_strdup from qemu_get_exec_dir
  fuzz: use qemu_get_exec_dir
  oslib-posix: default exec_dir to bindir
  cutils: introduce get_relocated_path
  oslib-posix: relocate path to /var
  module: relocate path to modules
  net: relocate paths to helpers and scripts
  vl: relocate paths to data directories
  vl: relocate path to configuration file
  qemu-bridge-helper: relocate path to default ACL
  qga: relocate path to default configuration and hook
  ui: relocate paths to icons and translations
  configure: use a platform-neutral prefix
  tests/tcg: reinstate or replace desired parts of rules.mak
  docs: Move object.h overview doc comment to qom.rst
  target/i386: kvm: do not use kvm_check_extension to find paravirtual 
capabilities

Pavel Pisa (2):
  hw/net/can: Documentation for CTU CAN FD IP open hardware core emulation.
  hw/net/can: Correct Kconfig 

[PULL 30/86] meson: move libmpathpersist test

2020-09-30 Thread Paolo Bonzini
This is the first compiler/linker test that has been moved to Meson.
Add more section headings to keep things clearer.

This also fixes static linking to libmpathpersist, which has a
dependency on libmultipath but no pkg-config file to describe it.

Signed-off-by: Paolo Bonzini 
---
 configure | 77 +++-
 meson.build   | 81 +++
 meson_options.txt |  2 ++
 3 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/configure b/configure
index 6f2599f99f..aade6eb285 100755
--- a/configure
+++ b/configure
@@ -403,7 +403,7 @@ netmap="no"
 sdl="auto"
 sdl_image="auto"
 virtfs=""
-mpath=""
+mpath="auto"
 vnc="enabled"
 sparse="no"
 vde=""
@@ -1116,9 +1116,9 @@ for opt do
   ;;
   --enable-virtfs) virtfs="yes"
   ;;
-  --disable-mpath) mpath="no"
+  --disable-mpath) mpath="disabled"
   ;;
-  --enable-mpath) mpath="yes"
+  --enable-mpath) mpath="enabled"
   ;;
   --disable-vnc) vnc="disabled"
   ;;
@@ -3852,57 +3852,6 @@ if test "$modules" = yes; then
 fi
 fi
 
-##
-# libmpathpersist probe
-
-if test "$mpath" != "no" ; then
-  # probe for the new API
-  cat > $TMPC <
-#include 
-unsigned mpath_mx_alloc_len = 1024;
-int logsink;
-static struct config *multipath_conf;
-extern struct udev *udev;
-extern struct config *get_multipath_config(void);
-extern void put_multipath_config(struct config *conf);
-struct udev *udev;
-struct config *get_multipath_config(void) { return multipath_conf; }
-void put_multipath_config(struct config *conf) { }
-
-int main(void) {
-udev = udev_new();
-multipath_conf = mpath_lib_init();
-return 0;
-}
-EOF
-  if compile_prog "" "-ludev -lmultipath -lmpathpersist" ; then
-mpathpersist=yes
-mpathpersist_new_api=yes
-  else
-# probe for the old API
-cat > $TMPC <
-#include 
-unsigned mpath_mx_alloc_len = 1024;
-int logsink;
-int main(void) {
-struct udev *udev = udev_new();
-mpath_lib_init(udev);
-return 0;
-}
-EOF
-if compile_prog "" "-ludev -lmultipath -lmpathpersist" ; then
-  mpathpersist=yes
-  mpathpersist_new_api=no
-else
-  mpathpersist=no
-fi
-  fi
-else
-  mpathpersist=no
-fi
-
 ##
 # pthread probe
 PTHREADLIBS_LIST="-pthread -lpthread -lpthreadGC2"
@@ -6337,23 +6286,11 @@ if test "$softmmu" = yes ; then
   fi
   virtfs=no
 fi
-if test "$mpath" != no && test "$mpathpersist" = yes ; then
-  mpath=yes
-else
-  if test "$mpath" = yes; then
-error_exit "Multipath requires libmpathpersist devel"
-  fi
-  mpath=no
-fi
   else
 if test "$virtfs" = yes; then
   error_exit "VirtFS is supported only on Linux"
 fi
 virtfs=no
-if test "$mpath" = yes; then
-  error_exit "Multipath is supported only on Linux"
-fi
-mpath=no
   fi
 fi
 
@@ -6894,12 +6831,6 @@ fi
 if test "$virtfs" = "yes" ; then
   echo "CONFIG_VIRTFS=y" >> $config_host_mak
 fi
-if test "$mpath" = "yes" ; then
-  echo "CONFIG_MPATH=y" >> $config_host_mak
-  if test "$mpathpersist_new_api" = "yes"; then
-echo "CONFIG_MPATH_NEW_API=y" >> $config_host_mak
-  fi
-fi
 if test "$vhost_scsi" = "yes" ; then
   echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
 fi
@@ -7988,7 +7919,7 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \
 -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; 
fi) \
 -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
 -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; 
fi) \
-   -Dsdl=$sdl -Dsdl_image=$sdl_image \
+   -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
-Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png 
\
-Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f\
 $cross_arg \
diff --git a/meson.build b/meson.build
index cd3d1ee260..8e9cd67235 100644
--- a/meson.build
+++ b/meson.build
@@ -86,6 +86,14 @@ if 'SPARSE_CFLAGS' in config_host
'compile_commands.json'])
 endif
 
+###
+# Target-specific checks and dependencies #
+###
+
+if targetos != 'linux' and get_option('mpath').enabled()
+  error('Multipath is supported only on Linux')
+endif
+
 m = cc.find_library('m', required: false)
 util = cc.find_library('util', required: false)
 winmm = []
@@ -117,6 +125,11 @@ elif targetos == 'haiku'
 cc.find_library('network'),
 cc.find_library('bsd')]
 endif
+
+
+# Dependencies #
+
+
 # The path to glib.h is added to all compilation commands.  This was
 # grandfathered in from the QEMU Makefiles.
 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
@@ -223,10 +236,6 @@ if 'CONFIG_SPICE' in config_host
  link_args: config_host['SPICE_LIBS'].split())
 endif
 rt = 

[PULL 31/86] meson: extend libmpathpersist test for static linking

2020-09-30 Thread Paolo Bonzini
libmultipath has a dependency on libdevmapper, so
include it as well when static linking.  It seems that
the rabbit hole ends there.

Signed-off-by: Paolo Bonzini 
---
 meson.build | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/meson.build b/meson.build
index 8e9cd67235..5dd7728cc9 100644
--- a/meson.build
+++ b/meson.build
@@ -302,14 +302,25 @@ if targetos == 'linux' and have_tools and not 
get_option('mpath').disabled()
   mpath_lib_init(udev);
   return 0;
   }'''
-  libmultipath = cc.find_library('multipath',
- required: get_option('mpath'),
- static: enable_static)
-  libmpathpersist = cc.find_library('mpathpersist',
-required: get_option('mpath'),
-static: enable_static)
-  if libmultipath.found() and libmpathpersist.found() and libudev.found()
-mpathlibs = [libmultipath, libmpathpersist, libudev]
+  mpathlibs = [libudev]
+  if enable_static
+mpathlibs += cc.find_library('devmapper',
+   required: get_option('mpath'),
+   static: enable_static)
+  endif
+  mpathlibs += cc.find_library('multipath',
+   required: get_option('mpath'),
+   static: enable_static)
+  mpathlibs += cc.find_library('mpathpersist',
+   required: get_option('mpath'),
+   static: enable_static)
+  foreach lib: mpathlibs
+if not lib.found()
+  mpathlibs = []
+  break
+endif
+  endforeach
+  if mpathlibs.length() > 0
 if cc.links(mpath_test_source_new, dependencies: mpathlibs)
   mpathpersist = declare_dependency(dependencies: mpathlibs)
   mpathpersist_new_api = true
-- 
2.26.2



[PULL 29/86] meson: move libudev test

2020-09-30 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 configure   | 14 --
 meson.build |  7 ---
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index f9e2f3de65..6f2599f99f 100755
--- a/configure
+++ b/configure
@@ -908,7 +908,6 @@ Linux)
   linux_user="yes"
   kvm="yes"
   QEMU_INCLUDES="-isystem ${source_path}/linux-headers -Ilinux-headers 
$QEMU_INCLUDES"
-  libudev="yes"
 ;;
 esac
 
@@ -6287,15 +6286,6 @@ if test "$libnfs" != "no" ; then
 fi
 
 ##
-# Do we have libudev
-if test "$libudev" != "no" ; then
-  if $pkg_config libudev && test "$static" != "yes"; then
-libudev="yes"
-libudev_libs=$($pkg_config --libs libudev)
-  else
-libudev="no"
-  fi
-fi
 
 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
 if test "$solaris" = "no" && test "$tsan" = "no"; then
@@ -7456,10 +7446,6 @@ if test "$gcov" = "yes" ; then
   echo "CONFIG_GCOV=y" >> $config_host_mak
 fi
 
-if test "$libudev" != "no"; then
-echo "CONFIG_LIBUDEV=y" >> $config_host_mak
-echo "LIBUDEV_LIBS=$libudev_libs" >> $config_host_mak
-fi
 if test "$fuzzing" != "no"; then
 echo "CONFIG_FUZZ=y" >> $config_host_mak
 fi
diff --git a/meson.build b/meson.build
index 975a187e2c..cd3d1ee260 100644
--- a/meson.build
+++ b/meson.build
@@ -257,8 +257,8 @@ if 'CONFIG_CURL' in config_host
 link_args: config_host['CURL_LIBS'].split())
 endif
 libudev = not_found
-if 'CONFIG_LIBUDEV' in config_host
-  libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
+if targetos == 'linux' and (have_system or have_tools)
+  libudev = dependency('libudev', static: enable_static)
 endif
 brlapi = not_found
 if 'CONFIG_BRLAPI' in config_host
@@ -440,6 +440,7 @@ has_gettid = cc.has_function('gettid')
 
 # Create config-host.h
 
+config_host_data.set('CONFIG_LIBUDEV', libudev.found())
 config_host_data.set('CONFIG_SDL', sdl.found())
 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
 config_host_data.set('CONFIG_VNC', vnc.found())
@@ -1450,7 +1451,7 @@ summary_info += {'sheepdog support':  
config_host.has_key('CONFIG_SHEEPDOG')}
 summary_info += {'capstone':  config_host.has_key('CONFIG_CAPSTONE')}
 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
-summary_info += {'libudev':   config_host.has_key('CONFIG_LIBUDEV')}
+summary_info += {'libudev':   libudev.found()}
 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == 
'--defconfig'}
 summary_info += {'plugin support':config_host.has_key('CONFIG_PLUGIN')}
 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
-- 
2.26.2





Re: [PATCH v4 41/46] qapi/introspect.py: create a typed 'Node' data structure

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 02:58:04PM -0400, John Snow wrote:
> On 9/30/20 2:39 PM, Eduardo Habkost wrote:
> > On Wed, Sep 30, 2020 at 12:31:45AM -0400, John Snow wrote:
> > > This replaces _make_tree with Node.__init__(), effectively. By creating
> > > it as a generic container, we can more accurately describe the exact
> > > nature of this particular Node.
> > > 
> > > Signed-off-by: John Snow 
> > > ---
> > >   scripts/qapi/introspect.py | 77 +++---
> > >   1 file changed, 38 insertions(+), 39 deletions(-)
> > > 
> > > diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> > > index 43b6ba5df1f..86286e755ca 100644
> > > --- a/scripts/qapi/introspect.py
> > > +++ b/scripts/qapi/introspect.py
> > > @@ -12,11 +12,12 @@
> > >   from typing import (
> > >   Dict,
> > > +Generic,
> > > +Iterable,
> > >   List,
> > >   Optional,
> > >   Sequence,
> > > -Tuple,
> > > -Union,
> > > +TypeVar,
> > >   )
> > >   from .common import (
> > > @@ -43,42 +44,42 @@
> > >   # The correct type for TreeNode is actually:
> > > -# Union[AnnotatedNode, List[TreeNode], Dict[str, TreeNode], str, bool]
> > > +# Union[Node[TreeNode], List[TreeNode], Dict[str, TreeNode], str, bool]
> > >   # but mypy does not support recursive types yet.
> > >   TreeNode = object
> > > +_NodeType = TypeVar('_NodeType', bound=TreeNode)
> > >   _DObject = Dict[str, object]
> > > -Extra = Dict[str, object]
> > > -AnnotatedNode = Tuple[TreeNode, Extra]
> > 
> > Do you have plans to make Node replace TreeNode completely?
> > 
> > I'd understand this patch as a means to reach that goal, but I'm
> > not sure the intermediate state of having both Node and TreeNode
> > types (that can be confused with each other) is desirable.
> > 
> 
> The problem is that _tree_to_qlit still accepts a broad array of types. The
> "TreeNode" comment above explains that those types are:
> 
> Node[TreeNode], List[TreeNode], Dict[str, TreeNode], str, bool
> 
> Three are containers, two are leaf values.
> of the containers, the Node container is special in that it houses
> explicitly one of the four other types (but never itself.)
> 
> Even if I somehow always enforced Node[T] heading into _tree_to_qlit, I
> would still need to describe what 'T' is, which is another recursive type
> that I cannot exactly describe with mypy's current descriptive power:
> 
> INNER_TYPE = List[Node[INNER_TYPE]], Dict[str, Node[INNER_TYPE]], str, bool
> 
> And that's not really a huge win, or indeed any different to the existing
> TreeNode being an "object".
> 
> So ... no, I felt like I was going to stop here, where we have
> fundamentally:
> 
> 1. Undecorated nodes (list, dict, str, bool) ("TreeNode")
> 2. Decorated nodes (Node[T]) ("Node")
> 
> which leads to the question: Why bother swapping Tuple for Node at that
> point?
> 
> My answer is simply that having a strong type name allows us to distinguish
> this from garden-variety Tuples that might sneak in for other reasons in
> other data types.

Would:
  AnnotatedNode = NewType('AnnotatedNode', Tuple[TreeNode, Extra])
be enough, then?

> 
> Maybe we want a different nomenclature though, like Node vs AnnotatedNode?

Yes, I believe having a more explicit name would be better.


> 
> --js
> 
> (Also: 'TreeNode' is just an alias for object, it doesn't mean anything
> grammatically. I could just as soon erase it entirely if you felt it
> provided no value. It doesn't enforce that it only takes objects we declared
> were 'TreeNode' types, for instance. It's just a preprocessor name,
> basically.)
> 
> > > -def _make_tree(obj: Union[_DObject, str], ifcond: List[str],
> > > -   comment: Optional[str] = None) -> AnnotatedNode:
> > > -extra: Extra = {
> > > -'if': ifcond,
> > > -'comment': comment,
> > > -}
> > > -return (obj, extra)
> > > +class Node(Generic[_NodeType]):
> > > +"""
> > > +Node generally contains a SchemaInfo-like type (as a dict),
> > > +But it also used to wrap comments/ifconds around leaf value types.
> > > +"""
> > > +# Remove after 3.7 adds @dataclass:
> > > +# pylint: disable=too-few-public-methods
> > > +def __init__(self, data: _NodeType, ifcond: Iterable[str],
> > > + comment: Optional[str] = None):
> > > +self.data = data
> > > +self.comment: Optional[str] = comment
> > > +self.ifcond: Sequence[str] = tuple(ifcond)
> > > -def _tree_to_qlit(obj: TreeNode,
> > > -  level: int = 0,
> > > +def _tree_to_qlit(obj: TreeNode, level: int = 0,
> > > suppress_first_indent: bool = False) -> str:
> > >   def indent(level: int) -> str:
> > >   return level * 4 * ' '
> > > -if isinstance(obj, tuple):
> > > -ifobj, extra = obj
> > > -ifcond = extra.get('if')
> > > -comment = extra.get('comment')
> > > +if isinstance(obj, Node):
> > >   ret = ''
> > > -

Re: [Bug 1896096] Re: Git version: Build process is broken in block_curl.c.o

2020-09-30 Thread Paolo Bonzini
Yes, of course.

Il mer 30 set 2020, 21:25 Frederic Bezies <1896...@bugs.launchpad.net> ha
scritto:

> Just asking: any hope to see this patch added to qemu git source code?
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1896096
>
> Title:
>   Git version: Build process is broken in block_curl.c.o
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1896096/+subscriptions
>
>

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

Title:
  Git version: Build process is broken in block_curl.c.o

Status in QEMU:
  Invalid

Bug description:
  Gcc version: 10.2.0
  Glusterfs: 8.1
  Libguestfs: 1.42

  Configure options used:

  configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --libexecdir=/usr/lib/qemu \
  --extra-ldflags="$LDFLAGS" \
  --smbd=/usr/bin/smbd \
  --enable-modules \
  --enable-sdl \
  --disable-werror \
  --enable-slirp=system \
  --enable-xfsctl \
  --audio-drv-list="pa alsa sdl"
  
  Error log attached. Here is the beginning:

  /usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/Scrt1.o: 
in function `_start':
  (.text+0x24): undefined reference to `main'
  /usr/bin/ld: libblock-curl.a(block_curl.c.o): in function `curl_block_init':

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



[Bug 1896096] Re: Git version: Build process is broken in block_curl.c.o

2020-09-30 Thread Frederic Bezies
Just asking: any hope to see this patch added to qemu git source code?

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

Title:
  Git version: Build process is broken in block_curl.c.o

Status in QEMU:
  Invalid

Bug description:
  Gcc version: 10.2.0
  Glusterfs: 8.1
  Libguestfs: 1.42

  Configure options used:

  configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --libexecdir=/usr/lib/qemu \
  --extra-ldflags="$LDFLAGS" \
  --smbd=/usr/bin/smbd \
  --enable-modules \
  --enable-sdl \
  --disable-werror \
  --enable-slirp=system \
  --enable-xfsctl \
  --audio-drv-list="pa alsa sdl"
  
  Error log attached. Here is the beginning:

  /usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/Scrt1.o: 
in function `_start':
  (.text+0x24): undefined reference to `main'
  /usr/bin/ld: libblock-curl.a(block_curl.c.o): in function `curl_block_init':

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



Re: [PATCH v3 00/11] user-mode: Prune build dependencies (part 3)

2020-09-30 Thread Paolo Bonzini
Il mer 30 set 2020, 20:57 Alex Bennée  ha scritto:

> > 1-8 is fine, but I think 9-11 is too much complication (especially not
> > really future-proof) for the benefit.
>
> Isn't qdev considered an internal API for our object and device lifetime
> handling (which should be shared) versus QAPI which only exists for
> system emulation and tool integration?
>

qdev is nothing more than a bunch of QOM classes, and QAPI is an integral
part of QOM (though properties, which are used when setting up CPUs in user
more emulation)

Therefore, even though most of the QAPI schema is specific to system
emulation and tools, a small part is used by common code.

Paolo

>


Re: [PATCH v4 39/46] qapi/introspect.py: Unify return type of _make_tree()

2020-09-30 Thread John Snow

On 9/30/20 2:57 PM, Eduardo Habkost wrote:

On Wed, Sep 30, 2020 at 02:32:49PM -0400, John Snow wrote:

On 9/30/20 2:24 PM, Eduardo Habkost wrote:

On Wed, Sep 30, 2020 at 12:31:43AM -0400, John Snow wrote:

Returning a *something* or a Tuple of *something* is hard to accurately
type. Let's just always return a tuple for structural consistency.

Instances of the 'TreeNode' type can be replaced with the slightly more
specific 'AnnotatedNode' type.

Signed-off-by: John Snow 


So, the only place where this seems to make a difference is
_tree_to_qlit().

We just need to prove that
_tree_to_qlit(o, ...)
will have exactly the same result as
_tree_to_qlit((o, None), ...).

For reference, this is the beginning of _tree_to_qlit():

| def _tree_to_qlit(obj: TreeNode,
|   level: int = 0,
|   suppress_first_indent: bool = False) -> str:
|
| def indent(level: int) -> str:
| return level * 4 * ' '
|
| if isinstance(obj, tuple):
| ifobj, extra = obj

`obj` is the return value of _make_tree()

`ifobj` is the original `obj` argument to _make_tree().

| ifcond = extra.get('if')

ifcond will be None.

| comment = extra.get('comment')

comment will be None

| ret = ''
| if comment:
| ret += indent(level) + '/* %s */\n' % comment

nop

| if ifcond:
| ret += gen_if(ifcond)

nop

| ret += _tree_to_qlit(ifobj, level)

ret will be '', so this is equivalent to:

ret = _tree_to_qlit(ifobj, level)

which is almost good.

The only difference seems to that suppress_first_indent=True will
be ignored.  We should pass suppress_first_indent as argument in
the recursive call above, just in case.



This is a really good spot, and I indeed hadn't considered it at all when I
did this.

(I simply made the change and observed it worked just fine!)


The existing code will behave weirdly if there are comments or
conditions and suppress_first_indent=True, but I suggest we try
to address this issue later.

| if ifcond:
| ret += '\n' + gen_endif(ifcond)

nop

| return ret



Hm, yes, it's a hypothetical case, but perhaps we can use an assertion to
help guard against it if development creates that case later by accident.

That ought to be good enough for now to not waste time accommodating a
(presently) fictional circumstance?

Thanks for the good sleuthing here.


With the current code, both
   ret += _tree_to_qlit(ifobj, level)
and
   ret += _tree_to_qlit(ifobj, level, suppress_first_indent)
will behave exactly the same.

The former will behave weirdly if we wrap a dictionary value using
_tree_node().  We don't do that today.

The latter will behave weirdly if there's a comment or ifcond
attached in a dictionary value.  We don't do that today.

I believe the latter is less likely to be triggered by accident.

But I'd be happy with either:

   # _make_tree() shouldn't be use to wrap nodes that
   # may be printed using suppress_first_indent=True
   # (in other words, dictionary values shouldn't be wrapped using _make_tree())
   assert(not suppress_first_indent)
   ret += _tree_to_qlit(ifobj, level)

or

   # we can't add ifcond or comments to nodes that may be
   # printed using suppress_first_indent=True
   # (in other words, dictionary values can't have ifcond or comments)
   assert(not suppress_first_indent or (not comment and not ifcond))
   ret += _tree_to_qlit(ifobj, level, suppress_first_indent)


If we have time to spare later, we could do this:

   def _value_to_qlit(obj: Union[None, str, Dict[str, object], List[object], 
bool],
  level: int = 0,
  suppress_first_indent: bool = False) -> str:
   ...
   if obj is None:
   ...
   elif isinstance(obj, str):
   ...
   elif isinstance(obj, list):
   ...
   ...
   
   def _tree_to_qlit(obj: TreeNode, level: int = 0) -> str:

   if isinstance(obj, AnnotatedNode):
  ...
   else:
  return _value_to_qlit(obj, level)

This way, it will be impossible to set suppress_first_indent=True
on an annotated node.



Maybe it's the right thing to separate out container types from leaf 
types and make this mutually recursive.


I debating doing that earlier, but the patches were already so strangled 
and messy I was afraid of plunging deeper into refactors.


Maybe I'll go take a nap and do it when I wake up. :)

--js




Re: [PATCH v4 41/46] qapi/introspect.py: create a typed 'Node' data structure

2020-09-30 Thread John Snow

On 9/30/20 2:39 PM, Eduardo Habkost wrote:

On Wed, Sep 30, 2020 at 12:31:45AM -0400, John Snow wrote:

This replaces _make_tree with Node.__init__(), effectively. By creating
it as a generic container, we can more accurately describe the exact
nature of this particular Node.

Signed-off-by: John Snow 
---
  scripts/qapi/introspect.py | 77 +++---
  1 file changed, 38 insertions(+), 39 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 43b6ba5df1f..86286e755ca 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -12,11 +12,12 @@
  
  from typing import (

  Dict,
+Generic,
+Iterable,
  List,
  Optional,
  Sequence,
-Tuple,
-Union,
+TypeVar,
  )
  
  from .common import (

@@ -43,42 +44,42 @@
  
  
  # The correct type for TreeNode is actually:

-# Union[AnnotatedNode, List[TreeNode], Dict[str, TreeNode], str, bool]
+# Union[Node[TreeNode], List[TreeNode], Dict[str, TreeNode], str, bool]
  # but mypy does not support recursive types yet.
  TreeNode = object
+_NodeType = TypeVar('_NodeType', bound=TreeNode)
  _DObject = Dict[str, object]
-Extra = Dict[str, object]
-AnnotatedNode = Tuple[TreeNode, Extra]


Do you have plans to make Node replace TreeNode completely?

I'd understand this patch as a means to reach that goal, but I'm
not sure the intermediate state of having both Node and TreeNode
types (that can be confused with each other) is desirable.



The problem is that _tree_to_qlit still accepts a broad array of types. 
The "TreeNode" comment above explains that those types are:


Node[TreeNode], List[TreeNode], Dict[str, TreeNode], str, bool

Three are containers, two are leaf values.
of the containers, the Node container is special in that it houses 
explicitly one of the four other types (but never itself.)


Even if I somehow always enforced Node[T] heading into _tree_to_qlit, I 
would still need to describe what 'T' is, which is another recursive 
type that I cannot exactly describe with mypy's current descriptive power:


INNER_TYPE = List[Node[INNER_TYPE]], Dict[str, Node[INNER_TYPE]], str, bool

And that's not really a huge win, or indeed any different to the 
existing TreeNode being an "object".


So ... no, I felt like I was going to stop here, where we have 
fundamentally:


1. Undecorated nodes (list, dict, str, bool) ("TreeNode")
2. Decorated nodes (Node[T]) ("Node")

which leads to the question: Why bother swapping Tuple for Node at that 
point?


My answer is simply that having a strong type name allows us to 
distinguish this from garden-variety Tuples that might sneak in for 
other reasons in other data types.


Maybe we want a different nomenclature though, like Node vs AnnotatedNode?

--js

(Also: 'TreeNode' is just an alias for object, it doesn't mean anything 
grammatically. I could just as soon erase it entirely if you felt it 
provided no value. It doesn't enforce that it only takes objects we 
declared were 'TreeNode' types, for instance. It's just a preprocessor 
name, basically.)


  
  
-def _make_tree(obj: Union[_DObject, str], ifcond: List[str],

-   comment: Optional[str] = None) -> AnnotatedNode:
-extra: Extra = {
-'if': ifcond,
-'comment': comment,
-}
-return (obj, extra)
+class Node(Generic[_NodeType]):
+"""
+Node generally contains a SchemaInfo-like type (as a dict),
+But it also used to wrap comments/ifconds around leaf value types.
+"""
+# Remove after 3.7 adds @dataclass:
+# pylint: disable=too-few-public-methods
+def __init__(self, data: _NodeType, ifcond: Iterable[str],
+ comment: Optional[str] = None):
+self.data = data
+self.comment: Optional[str] = comment
+self.ifcond: Sequence[str] = tuple(ifcond)
  
  
-def _tree_to_qlit(obj: TreeNode,

-  level: int = 0,
+def _tree_to_qlit(obj: TreeNode, level: int = 0,
suppress_first_indent: bool = False) -> str:
  
  def indent(level: int) -> str:

  return level * 4 * ' '
  
-if isinstance(obj, tuple):

-ifobj, extra = obj
-ifcond = extra.get('if')
-comment = extra.get('comment')
+if isinstance(obj, Node):
  ret = ''
-if comment:
-ret += indent(level) + '/* %s */\n' % comment
-if ifcond:
-ret += gen_if(ifcond)
-ret += _tree_to_qlit(ifobj, level)
-if ifcond:
-ret += '\n' + gen_endif(ifcond)
+if obj.comment:
+ret += indent(level) + '/* %s */\n' % obj.comment
+if obj.ifcond:
+ret += gen_if(obj.ifcond)
+ret += _tree_to_qlit(obj.data, level)
+if obj.ifcond:
+ret += '\n' + gen_endif(obj.ifcond)
  return ret
  
  ret = ''

@@ -125,7 +126,7 @@ def __init__(self, prefix: str, unmask: bool):
  ' * QAPI/QMP schema introspection', __doc__)
  

Re: [PATCH v4 39/46] qapi/introspect.py: Unify return type of _make_tree()

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 02:32:49PM -0400, John Snow wrote:
> On 9/30/20 2:24 PM, Eduardo Habkost wrote:
> > On Wed, Sep 30, 2020 at 12:31:43AM -0400, John Snow wrote:
> > > Returning a *something* or a Tuple of *something* is hard to accurately
> > > type. Let's just always return a tuple for structural consistency.
> > > 
> > > Instances of the 'TreeNode' type can be replaced with the slightly more
> > > specific 'AnnotatedNode' type.
> > > 
> > > Signed-off-by: John Snow 
> > 
> > So, the only place where this seems to make a difference is
> > _tree_to_qlit().
> > 
> > We just need to prove that
> >_tree_to_qlit(o, ...)
> > will have exactly the same result as
> >_tree_to_qlit((o, None), ...).
> > 
> > For reference, this is the beginning of _tree_to_qlit():
> > 
> > | def _tree_to_qlit(obj: TreeNode,
> > |   level: int = 0,
> > |   suppress_first_indent: bool = False) -> str:
> > |
> > | def indent(level: int) -> str:
> > | return level * 4 * ' '
> > |
> > | if isinstance(obj, tuple):
> > | ifobj, extra = obj
> > 
> > `obj` is the return value of _make_tree()
> > 
> > `ifobj` is the original `obj` argument to _make_tree().
> > 
> > | ifcond = extra.get('if')
> > 
> > ifcond will be None.
> > 
> > | comment = extra.get('comment')
> > 
> > comment will be None
> > 
> > | ret = ''
> > | if comment:
> > | ret += indent(level) + '/* %s */\n' % comment
> > 
> > nop
> > 
> > | if ifcond:
> > | ret += gen_if(ifcond)
> > 
> > nop
> > 
> > | ret += _tree_to_qlit(ifobj, level)
> > 
> > ret will be '', so this is equivalent to:
> > 
> >ret = _tree_to_qlit(ifobj, level)
> > 
> > which is almost good.
> > 
> > The only difference seems to that suppress_first_indent=True will
> > be ignored.  We should pass suppress_first_indent as argument in
> > the recursive call above, just in case.
> > 
> 
> This is a really good spot, and I indeed hadn't considered it at all when I
> did this.
> 
> (I simply made the change and observed it worked just fine!)
> 
> > The existing code will behave weirdly if there are comments or
> > conditions and suppress_first_indent=True, but I suggest we try
> > to address this issue later.
> > 
> > | if ifcond:
> > | ret += '\n' + gen_endif(ifcond)
> > 
> > nop
> > 
> > | return ret
> > 
> 
> Hm, yes, it's a hypothetical case, but perhaps we can use an assertion to
> help guard against it if development creates that case later by accident.
> 
> That ought to be good enough for now to not waste time accommodating a
> (presently) fictional circumstance?
> 
> Thanks for the good sleuthing here.

With the current code, both
  ret += _tree_to_qlit(ifobj, level)
and
  ret += _tree_to_qlit(ifobj, level, suppress_first_indent)
will behave exactly the same.

The former will behave weirdly if we wrap a dictionary value using
_tree_node().  We don't do that today.

The latter will behave weirdly if there's a comment or ifcond
attached in a dictionary value.  We don't do that today.

I believe the latter is less likely to be triggered by accident.

But I'd be happy with either:

  # _make_tree() shouldn't be use to wrap nodes that
  # may be printed using suppress_first_indent=True
  # (in other words, dictionary values shouldn't be wrapped using _make_tree())
  assert(not suppress_first_indent)
  ret += _tree_to_qlit(ifobj, level)

or

  # we can't add ifcond or comments to nodes that may be
  # printed using suppress_first_indent=True
  # (in other words, dictionary values can't have ifcond or comments)
  assert(not suppress_first_indent or (not comment and not ifcond))
  ret += _tree_to_qlit(ifobj, level, suppress_first_indent)


If we have time to spare later, we could do this:

  def _value_to_qlit(obj: Union[None, str, Dict[str, object], List[object], 
bool],
 level: int = 0,
 suppress_first_indent: bool = False) -> str:
  ...
  if obj is None:
  ...
  elif isinstance(obj, str):
  ...
  elif isinstance(obj, list):
  ...
  ...
  
  def _tree_to_qlit(obj: TreeNode, level: int = 0) -> str:
  if isinstance(obj, AnnotatedNode):
 ...
  else:
 return _value_to_qlit(obj, level)

This way, it will be impossible to set suppress_first_indent=True
on an annotated node.

-- 
Eduardo




Re: [PATCH v3 00/11] user-mode: Prune build dependencies (part 3)

2020-09-30 Thread Alex Bennée


Paolo Bonzini  writes:

> On 30/09/20 19:15, Eduardo Habkost wrote:
>> On Wed, Sep 30, 2020 at 06:49:38PM +0200, Philippe Mathieu-Daudé wrote:
>>> This is the third part of a series reducing user-mode
>>> dependencies. By stripping out unused code, the build
>>> and testing time is reduced (as is space used by objects).
>> I'm queueing patches 2-9 on machine-next.  Thanks!
>> 
>> Markus, Eric: I can merge the QAPI patches (1, 11) if I get an
>> Acked-by.
>> 
>> I'll send separate comments on patch 10.
>> 
>
> 1-8 is fine, but I think 9-11 is too much complication (especially not
> really future-proof) for the benefit.

Isn't qdev considered an internal API for our object and device lifetime
handling (which should be shared) versus QAPI which only exists for
system emulation and tool integration? That is of course assuming
libvirt is never going to want to know about linux-user emulation?

>
> Paolo


-- 
Alex Bennée



Re: [PATCH v4 41/46] qapi/introspect.py: create a typed 'Node' data structure

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 12:31:45AM -0400, John Snow wrote:
> This replaces _make_tree with Node.__init__(), effectively. By creating
> it as a generic container, we can more accurately describe the exact
> nature of this particular Node.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/introspect.py | 77 +++---
>  1 file changed, 38 insertions(+), 39 deletions(-)
> 
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 43b6ba5df1f..86286e755ca 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -12,11 +12,12 @@
>  
>  from typing import (
>  Dict,
> +Generic,
> +Iterable,
>  List,
>  Optional,
>  Sequence,
> -Tuple,
> -Union,
> +TypeVar,
>  )
>  
>  from .common import (
> @@ -43,42 +44,42 @@
>  
>  
>  # The correct type for TreeNode is actually:
> -# Union[AnnotatedNode, List[TreeNode], Dict[str, TreeNode], str, bool]
> +# Union[Node[TreeNode], List[TreeNode], Dict[str, TreeNode], str, bool]
>  # but mypy does not support recursive types yet.
>  TreeNode = object
> +_NodeType = TypeVar('_NodeType', bound=TreeNode)
>  _DObject = Dict[str, object]
> -Extra = Dict[str, object]
> -AnnotatedNode = Tuple[TreeNode, Extra]

Do you have plans to make Node replace TreeNode completely?

I'd understand this patch as a means to reach that goal, but I'm
not sure the intermediate state of having both Node and TreeNode
types (that can be confused with each other) is desirable.

>  
>  
> -def _make_tree(obj: Union[_DObject, str], ifcond: List[str],
> -   comment: Optional[str] = None) -> AnnotatedNode:
> -extra: Extra = {
> -'if': ifcond,
> -'comment': comment,
> -}
> -return (obj, extra)
> +class Node(Generic[_NodeType]):
> +"""
> +Node generally contains a SchemaInfo-like type (as a dict),
> +But it also used to wrap comments/ifconds around leaf value types.
> +"""
> +# Remove after 3.7 adds @dataclass:
> +# pylint: disable=too-few-public-methods
> +def __init__(self, data: _NodeType, ifcond: Iterable[str],
> + comment: Optional[str] = None):
> +self.data = data
> +self.comment: Optional[str] = comment
> +self.ifcond: Sequence[str] = tuple(ifcond)
>  
>  
> -def _tree_to_qlit(obj: TreeNode,
> -  level: int = 0,
> +def _tree_to_qlit(obj: TreeNode, level: int = 0,
>suppress_first_indent: bool = False) -> str:
>  
>  def indent(level: int) -> str:
>  return level * 4 * ' '
>  
> -if isinstance(obj, tuple):
> -ifobj, extra = obj
> -ifcond = extra.get('if')
> -comment = extra.get('comment')
> +if isinstance(obj, Node):
>  ret = ''
> -if comment:
> -ret += indent(level) + '/* %s */\n' % comment
> -if ifcond:
> -ret += gen_if(ifcond)
> -ret += _tree_to_qlit(ifobj, level)
> -if ifcond:
> -ret += '\n' + gen_endif(ifcond)
> +if obj.comment:
> +ret += indent(level) + '/* %s */\n' % obj.comment
> +if obj.ifcond:
> +ret += gen_if(obj.ifcond)
> +ret += _tree_to_qlit(obj.data, level)
> +if obj.ifcond:
> +ret += '\n' + gen_endif(obj.ifcond)
>  return ret
>  
>  ret = ''
> @@ -125,7 +126,7 @@ def __init__(self, prefix: str, unmask: bool):
>  ' * QAPI/QMP schema introspection', __doc__)
>  self._unmask = unmask
>  self._schema: Optional[QAPISchema] = None
> -self._trees: List[AnnotatedNode] = []
> +self._trees: List[Node[_DObject]] = []
>  self._used_types: List[QAPISchemaType] = []
>  self._name_map: Dict[str, str] = {}
>  self._genc.add(mcgen('''
> @@ -192,9 +193,8 @@ def _use_type(self, typ: QAPISchemaType) -> str:
>  
>  @classmethod
>  def _gen_features(cls,
> -  features: List[QAPISchemaFeature]
> -  ) -> List[AnnotatedNode]:
> -return [_make_tree(f.name, f.ifcond) for f in features]
> +  features: List[QAPISchemaFeature]) -> List[Node[str]]:
> +return [Node(f.name, f.ifcond) for f in features]
>  
>  def _gen_tree(self, name: str, mtype: str, obj: _DObject,
>ifcond: List[str],
> @@ -210,10 +210,10 @@ def _gen_tree(self, name: str, mtype: str, obj: 
> _DObject,
>  obj['meta-type'] = mtype
>  if features:
>  obj['features'] = self._gen_features(features)
> -self._trees.append(_make_tree(obj, ifcond, comment))
> +self._trees.append(Node(obj, ifcond, comment))
>  
>  def _gen_member(self,
> -member: QAPISchemaObjectTypeMember) -> AnnotatedNode:
> +member: QAPISchemaObjectTypeMember) -> Node[_DObject]:
>  obj: _DObject = {
>  'name': member.name,
>  'type': 

[Bug 1894804] Re: Second DEVICE_DELETED event missing during virtio-blk disk device detach

2020-09-30 Thread Lee Yarwood
@Christian Yes we can test this in OpenStack CI with PPAs if you could
provide Bionic based builds.

Better yet I could even try to setup a git bisect locally if you have
steps to build from a source tree somewhere?

@James Did you try using OpenStack CI sized hosts (8 vCPUs, 8GB of RAM)
and the QEMU virt_type? That was the most reliable way I found of
hitting this and running the `tox -e full` tempest target to envoke a
full tempest run.

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

Title:
  Second DEVICE_DELETED event missing during virtio-blk disk device
  detach

Status in QEMU:
  New
Status in qemu package in Ubuntu:
  Incomplete

Bug description:
  We are in the process of moving OpenStack CI across to use 20.04 Focal
  as the underlying OS and encountering the following issue in any test
  attempting to detach disk devices from running QEMU instances.

  We can see a single DEVICE_DELETED event raised to libvirtd for the
  /machine/peripheral/virtio-disk1/virtio-backend device but we do not
  see a second event for the actual disk. As a result the device is
  still marked as present in libvirt but QEMU reports it as missing in
  subsequent attempts to remove the device.

  The following log snippets can also be found in the following pastebin
  that's slightly easier to gork:

  http://paste.openstack.org/show/797564/

  https://review.opendev.org/#/c/746981/ libvirt: Bump
  MIN_{LIBVIRT,QEMU}_VERSION and NEXT_MIN_{LIBVIRT,QEMU}_VERSION

  https://zuul.opendev.org/t/openstack/build/4c56def513884c5eb3ba7b0adf7fa260
  nova-ceph-multistore

  
https://zuul.opendev.org/t/openstack/build/4c56def513884c5eb3ba7b0adf7fa260/log/controller/logs/dpkg-l.txt

  ii  libvirt-daemon   6.0.0-0ubuntu8.3 
 amd64Virtualization daemon
  ii  libvirt-daemon-driver-qemu   6.0.0-0ubuntu8.3 
 amd64Virtualization daemon QEMU connection driver
  ii  libvirt-daemon-system6.0.0-0ubuntu8.3 
 amd64Libvirt daemon configuration files
  ii  libvirt-daemon-system-systemd6.0.0-0ubuntu8.3 
 amd64Libvirt daemon configuration files (systemd)
  ii  libvirt-dev:amd646.0.0-0ubuntu8.3 
 amd64development files for the libvirt library
  ii  libvirt0:amd64   6.0.0-0ubuntu8.3 
 amd64library for interfacing with different virtualization systems
  [..]
  ii  qemu-block-extra:amd64   1:4.2-3ubuntu6.4 
 amd64extra block backend modules for qemu-system and qemu-utils
  ii  qemu-slof20191209+dfsg-1  
 all  Slimline Open Firmware -- QEMU PowerPC version
  ii  qemu-system  1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries
  ii  qemu-system-arm  1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (arm)
  ii  qemu-system-common   1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (common files)
  ii  qemu-system-data 1:4.2-3ubuntu6.4 
 all  QEMU full system emulation (data files)
  ii  qemu-system-mips 1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (mips)
  ii  qemu-system-misc 1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (miscellaneous)
  ii  qemu-system-ppc  1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (ppc)
  ii  qemu-system-s390x1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (s390x)
  ii  qemu-system-sparc1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (sparc)
  ii  qemu-system-x86  1:4.2-3ubuntu6.4 
 amd64QEMU full system emulation binaries (x86)
  ii  qemu-utils   1:4.2-3ubuntu6.4 
 amd64QEMU utilities

  
https://zuul.opendev.org/t/openstack/build/4c56def513884c5eb3ba7b0adf7fa260/log/controller/logs/libvirt/qemu
  /instance-003a_log.txt

  2020-09-07 19:29:55.021+: starting up libvirt version: 6.0.0, package: 
0ubuntu8.3 (Marc Deslauriers  Thu, 30 Jul 2020 
06:40:28 -0400), qemu version: 4.2.0Debian 1:4.2-3ubuntu6.4, kernel: 
5.4.0-45-generic, hostname: ubuntu-focal-ovh-bhs1-0019682147
  LC_ALL=C \
  PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
  HOME=/var/lib/libvirt/qemu/domain-86-instance-003a \
  

Re: [PATCH v4 39/46] qapi/introspect.py: Unify return type of _make_tree()

2020-09-30 Thread John Snow

On 9/30/20 2:24 PM, Eduardo Habkost wrote:

On Wed, Sep 30, 2020 at 12:31:43AM -0400, John Snow wrote:

Returning a *something* or a Tuple of *something* is hard to accurately
type. Let's just always return a tuple for structural consistency.

Instances of the 'TreeNode' type can be replaced with the slightly more
specific 'AnnotatedNode' type.

Signed-off-by: John Snow 


So, the only place where this seems to make a difference is
_tree_to_qlit().

We just need to prove that
   _tree_to_qlit(o, ...)
will have exactly the same result as
   _tree_to_qlit((o, None), ...).

For reference, this is the beginning of _tree_to_qlit():

| def _tree_to_qlit(obj: TreeNode,
|   level: int = 0,
|   suppress_first_indent: bool = False) -> str:
|
| def indent(level: int) -> str:
| return level * 4 * ' '
|
| if isinstance(obj, tuple):
| ifobj, extra = obj

`obj` is the return value of _make_tree()

`ifobj` is the original `obj` argument to _make_tree().

| ifcond = extra.get('if')

ifcond will be None.

| comment = extra.get('comment')

comment will be None

| ret = ''
| if comment:
| ret += indent(level) + '/* %s */\n' % comment

nop

| if ifcond:
| ret += gen_if(ifcond)

nop

| ret += _tree_to_qlit(ifobj, level)

ret will be '', so this is equivalent to:

   ret = _tree_to_qlit(ifobj, level)

which is almost good.

The only difference seems to that suppress_first_indent=True will
be ignored.  We should pass suppress_first_indent as argument in
the recursive call above, just in case.



This is a really good spot, and I indeed hadn't considered it at all 
when I did this.


(I simply made the change and observed it worked just fine!)


The existing code will behave weirdly if there are comments or
conditions and suppress_first_indent=True, but I suggest we try
to address this issue later.

| if ifcond:
| ret += '\n' + gen_endif(ifcond)

nop

| return ret



Hm, yes, it's a hypothetical case, but perhaps we can use an assertion 
to help guard against it if development creates that case later by accident.


That ought to be good enough for now to not waste time accommodating a 
(presently) fictional circumstance?


Thanks for the good sleuthing here.

--js




Re: [PATCH v4 37/46] qapi/instrospect.py: add preliminary type hint annotations

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 12:31:41AM -0400, John Snow wrote:
> From: Eduardo Habkost 
> 
> The typing of _make_tree and friends is a bit involved, but it can be
> done with some stubbed out types and a bit of elbow grease. The
> forthcoming patches attempt to make some simplifications, but having the
> type hints in advance can aid in review.
> 
> Signed-off-by: Eduardo Habkost 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v4 40/46] qapi/introspect.py: replace 'extra' dict with 'comment' argument

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 12:31:44AM -0400, John Snow wrote:
> This is only used to pass in a dictionary with a comment already set, so
> skip the runaround and just accept the comment.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v5 09/14] hw/block/nvme: Support Zoned Namespace Command Set

2020-09-30 Thread Klaus Jensen
On Sep 30 14:50, Niklas Cassel wrote:
> On Mon, Sep 28, 2020 at 11:35:23AM +0900, Dmitry Fomichev wrote:
> > The emulation code has been changed to advertise NVM Command Set when
> > "zoned" device property is not set (default) and Zoned Namespace
> > Command Set otherwise.
> > 
> > Handlers for three new NVMe commands introduced in Zoned Namespace
> > Command Set specification are added, namely for Zone Management
> > Receive, Zone Management Send and Zone Append.
> > 
> > Device initialization code has been extended to create a proper
> > configuration for zoned operation using device properties.
> > 
> > Read/Write command handler is modified to only allow writes at the
> > write pointer if the namespace is zoned. For Zone Append command,
> > writes implicitly happen at the write pointer and the starting write
> > pointer value is returned as the result of the command. Write Zeroes
> > handler is modified to add zoned checks that are identical to those
> > done as a part of Write flow.
> > 
> > The code to support for Zone Descriptor Extensions is not included in
> > this commit and ZDES 0 is always reported. A later commit in this
> > series will add ZDE support.
> > 
> > This commit doesn't yet include checks for active and open zone
> > limits. It is assumed that there are no limits on either active or
> > open zones.
> > 
> > Signed-off-by: Niklas Cassel 
> > Signed-off-by: Hans Holmberg 
> > Signed-off-by: Ajay Joshi 
> > Signed-off-by: Chaitanya Kulkarni 
> > Signed-off-by: Matias Bjorling 
> > Signed-off-by: Aravind Ramesh 
> > Signed-off-by: Shin'ichiro Kawasaki 
> > Signed-off-by: Adam Manzanares 
> > Signed-off-by: Dmitry Fomichev 
> > ---
> >  block/nvme.c |   2 +-
> >  hw/block/nvme-ns.c   | 185 -
> >  hw/block/nvme-ns.h   |   6 +-
> >  hw/block/nvme.c  | 872 +--
> >  include/block/nvme.h |   6 +-
> >  5 files changed, 1033 insertions(+), 38 deletions(-)
> > 
> > diff --git a/block/nvme.c b/block/nvme.c
> > index 05485fdd11..7a513c9a17 100644
> > --- a/block/nvme.c
> > +++ b/block/nvme.c
> > @@ -333,7 +333,7 @@ static inline int nvme_translate_error(const NvmeCqe *c)
> >  {
> >  uint16_t status = (le16_to_cpu(c->status) >> 1) & 0xFF;
> >  if (status) {
> > -trace_nvme_error(le32_to_cpu(c->result),
> > +trace_nvme_error(le32_to_cpu(c->result32),
> >   le16_to_cpu(c->sq_head),
> >   le16_to_cpu(c->sq_id),
> >   le16_to_cpu(c->cid),
> > diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
> > index 31b7f986c3..6d9dc9205b 100644
> > --- a/hw/block/nvme-ns.c
> > +++ b/hw/block/nvme-ns.c
> > @@ -33,14 +33,14 @@ static void nvme_ns_init(NvmeNamespace *ns)
> >  NvmeIdNs *id_ns = >id_ns;
> >  
> >  if (blk_get_flags(ns->blkconf.blk) & BDRV_O_UNMAP) {
> > -ns->id_ns.dlfeat = 0x9;
> > +ns->id_ns.dlfeat = 0x8;
> 
> You seem to change something that is NVM namespace specific here, why?
> If it is indeed needed, I assume that this change should be in a separate
> patch.
> 

Stood out to me as well - and I thought it was sound enough, but now I'm
not sure sure.

DLFEAT is set to 0x8, which only signifies that Deallocate in Write
Zeroes is supported. Previously, it would also signify that returned
values would be 0x00 (DLFEAT 0x8 | 0x1). But since Dmitry added the
fill_pattern parameter...


> > +static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamespace *ns, int 
> > lba_index,
> > +  Error **errp)
> > +{
> > +NvmeIdNsZoned *id_ns_z;
> > +
> > +if (n->params.fill_pattern == 0) {
> > +ns->id_ns.dlfeat |= 0x01;
> > +} else if (n->params.fill_pattern == 0xff) {
> > +ns->id_ns.dlfeat |= 0x02;
> > +}

... then, when initialized, we look at the fill_pattern and set DLFEAT
accordingly instead.

But since fill_pattern only works for ZNS namespaces, I think dlfeat
should still be 0x9 for NVM namespaces. For NVM namespaces, since
neither DULBE or DSM is not supported, there is really only Write Zeroes
that can explicitly "deallocate" a block, and since that *will* write
zeroes no matter if DEAC is set or not, 0x00 pattern is guaranteed.


signature.asc
Description: PGP signature


Re: [PATCH v4 39/46] qapi/introspect.py: Unify return type of _make_tree()

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 12:31:43AM -0400, John Snow wrote:
> Returning a *something* or a Tuple of *something* is hard to accurately
> type. Let's just always return a tuple for structural consistency.
> 
> Instances of the 'TreeNode' type can be replaced with the slightly more
> specific 'AnnotatedNode' type.
> 
> Signed-off-by: John Snow 

So, the only place where this seems to make a difference is
_tree_to_qlit().

We just need to prove that
  _tree_to_qlit(o, ...)
will have exactly the same result as
  _tree_to_qlit((o, None), ...).

For reference, this is the beginning of _tree_to_qlit():

| def _tree_to_qlit(obj: TreeNode,
|   level: int = 0,
|   suppress_first_indent: bool = False) -> str:
| 
| def indent(level: int) -> str:
| return level * 4 * ' '
| 
| if isinstance(obj, tuple):
| ifobj, extra = obj

`obj` is the return value of _make_tree()

`ifobj` is the original `obj` argument to _make_tree().

| ifcond = extra.get('if')

ifcond will be None.

| comment = extra.get('comment')

comment will be None

| ret = ''
| if comment:
| ret += indent(level) + '/* %s */\n' % comment

nop

| if ifcond:
| ret += gen_if(ifcond)

nop

| ret += _tree_to_qlit(ifobj, level)

ret will be '', so this is equivalent to:

  ret = _tree_to_qlit(ifobj, level)

which is almost good.

The only difference seems to that suppress_first_indent=True will
be ignored.  We should pass suppress_first_indent as argument in
the recursive call above, just in case.

The existing code will behave weirdly if there are comments or
conditions and suppress_first_indent=True, but I suggest we try
to address this issue later.

| if ifcond:
| ret += '\n' + gen_endif(ifcond)

nop

| return ret


> ---
>  scripts/qapi/introspect.py | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 5cbdc7414bd..1c3ba41f1dc 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -53,14 +53,12 @@
>  
>  def _make_tree(obj: Union[_DObject, str], ifcond: List[str],
> extra: Optional[Extra] = None
> -   ) -> Union[TreeNode, AnnotatedNode]:
> +   ) -> AnnotatedNode:
>  if extra is None:
>  extra = {}
>  if ifcond:
>  extra['if'] = ifcond
> -if extra:
> -return (obj, extra)
> -return obj
> +return (obj, extra)
>  
>  
>  def _tree_to_qlit(obj: TreeNode,
> @@ -128,7 +126,7 @@ def __init__(self, prefix: str, unmask: bool):
>  ' * QAPI/QMP schema introspection', __doc__)
>  self._unmask = unmask
>  self._schema: Optional[QAPISchema] = None
> -self._trees: List[TreeNode] = []
> +self._trees: List[AnnotatedNode] = []
>  self._used_types: List[QAPISchemaType] = []
>  self._name_map: Dict[str, str] = {}
>  self._genc.add(mcgen('''
> @@ -195,7 +193,8 @@ def _use_type(self, typ: QAPISchemaType) -> str:
>  
>  @classmethod
>  def _gen_features(cls,
> -  features: List[QAPISchemaFeature]) -> List[TreeNode]:
> +  features: List[QAPISchemaFeature]
> +  ) -> List[AnnotatedNode]:
>  return [_make_tree(f.name, f.ifcond) for f in features]
>  
>  def _gen_tree(self, name: str, mtype: str, obj: _DObject,
> @@ -215,7 +214,7 @@ def _gen_tree(self, name: str, mtype: str, obj: _DObject,
>  self._trees.append(_make_tree(obj, ifcond, extra))
>  
>  def _gen_member(self,
> -member: QAPISchemaObjectTypeMember) -> TreeNode:
> +member: QAPISchemaObjectTypeMember) -> AnnotatedNode:
>  obj: _DObject = {
>  'name': member.name,
>  'type': self._use_type(member.type)
> @@ -231,7 +230,7 @@ def _gen_variants(self, tag_name: str,
>  return {'tag': tag_name,
>  'variants': [self._gen_variant(v) for v in variants]}
>  
> -def _gen_variant(self, variant: QAPISchemaVariant) -> TreeNode:
> +def _gen_variant(self, variant: QAPISchemaVariant) -> AnnotatedNode:
>  obj: _DObject = {
>  'case': variant.name,
>  'type': self._use_type(variant.type)
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PATCH 0/4] assorted gcc 10/fedora32 compile warning fixes

2020-09-30 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200930155859.303148-1-borntrae...@de.ibm.com/



Hi,

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

Type: series
Message-id: 20200930155859.303148-1-borntrae...@de.ibm.com
Subject: [PATCH 0/4] assorted gcc 10/fedora32 compile warning fixes

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20200930043150.1454766-1-js...@redhat.com -> 
patchew/20200930043150.1454766-1-js...@redhat.com
 - [tag update]  patchew/20200930095321.2006-1-zhaolich...@huawei.com -> 
patchew/20200930095321.2006-1-zhaolich...@huawei.com
 - [tag update]  patchew/20200930151616.3588165-1-mky...@tachyum.com -> 
patchew/20200930151616.3588165-1-mky...@tachyum.com
 - [tag update]  patchew/20200930155859.303148-1-borntrae...@de.ibm.com -> 
patchew/20200930155859.303148-1-borntrae...@de.ibm.com
 * [new tag] patchew/20200930164949.1425294-1-phi...@redhat.com -> 
patchew/20200930164949.1425294-1-phi...@redhat.com
fatal: failed to write ref-pack file
fatal: The remote end hung up unexpectedly
Traceback (most recent call last):
  File "patchew-tester/src/patchew-cli", line 521, in test_one
git_clone_repo(clone, r["repo"], r["head"], logf, True)
  File "patchew-tester/src/patchew-cli", line 53, in git_clone_repo
subprocess.check_call(clone_cmd, stderr=logf, stdout=logf)
  File "/opt/rh/rh-python36/root/usr/lib64/python3.6/subprocess.py", line 291, 
in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['git', 'clone', '-q', 
'/home/patchew/.cache/patchew-git-cache/httpsgithubcompatchewprojectqemu-3c8cf5a9c21ff8782164d1def7f44bd888713384',
 '/var/tmp/patchew-tester-tmp-529h9bha/src']' returned non-zero exit status 128.



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

Re: [PATCH 03/16] target/mips/cp0_timer: Explicit unit in variable name

2020-09-30 Thread Aleksandar Markovic
On Monday, September 28, 2020, Philippe Mathieu-Daudé 
wrote:

> Name variables holding nanoseconds with the '_ns' suffix.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---


Reviewed-by: Aleksandar Markovic 


>  target/mips/cp0_timer.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
> index 9c38e9da1c8..5194c967ae3 100644
> --- a/target/mips/cp0_timer.c
> +++ b/target/mips/cp0_timer.c
> @@ -32,13 +32,14 @@
>  /* MIPS R4K timer */
>  static void cpu_mips_timer_update(CPUMIPSState *env)
>  {
> -uint64_t now, next;
> +uint64_t now_ns, next_ns;
>  uint32_t wait;
>
> -now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> -wait = env->CP0_Compare - env->CP0_Count - (uint32_t)(now /
> TIMER_PERIOD);
> -next = now + (uint64_t)wait * TIMER_PERIOD;
> -timer_mod(env->timer, next);
> +now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +wait = env->CP0_Compare - env->CP0_Count -
> +   (uint32_t)(now_ns / TIMER_PERIOD);
> +next_ns = now_ns + (uint64_t)wait * TIMER_PERIOD;
> +timer_mod(env->timer, next_ns);
>  }
>
>  /* Expire the timer.  */
> @@ -56,16 +57,16 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
>  if (env->CP0_Cause & (1 << CP0Ca_DC)) {
>  return env->CP0_Count;
>  } else {
> -uint64_t now;
> +uint64_t now_ns;
>
> -now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>  if (timer_pending(env->timer)
> -&& timer_expired(env->timer, now)) {
> +&& timer_expired(env->timer, now_ns)) {
>  /* The timer has already expired.  */
>  cpu_mips_timer_expire(env);
>  }
>
> -return env->CP0_Count + (uint32_t)(now / TIMER_PERIOD);
> +return env->CP0_Count + (uint32_t)(now_ns / TIMER_PERIOD);
>  }
>  }
>
> --
> 2.26.2
>
>


Re: [PATCH 02/16] target/mips: Move cpu_mips_get_random() with CP0 helpers

2020-09-30 Thread Aleksandar Markovic
On Monday, September 28, 2020, Philippe Mathieu-Daudé 
wrote:

> The get_random() helper uses the CP0_Wired register, which is
> unrelated to the CP0_Count register use as timer.
> Commit e16fe40c872 ("Move the MIPS CPU timer in a separate file")
> incorrectly moved this get_random() helper with timer specific
> code. Move it back to generic CP0 helpers.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---


Reviewed-by: Aleksandar Markovic 


>  target/mips/internal.h   |  2 +-
>  target/mips/cp0_helper.c | 25 +
>  target/mips/cp0_timer.c  | 25 -
>  3 files changed, 26 insertions(+), 26 deletions(-)
>
> diff --git a/target/mips/internal.h b/target/mips/internal.h
> index 7f159a9230c..087cabaa6d4 100644
> --- a/target/mips/internal.h
> +++ b/target/mips/internal.h
> @@ -144,6 +144,7 @@ void r4k_helper_tlbr(CPUMIPSState *env);
>  void r4k_helper_tlbinv(CPUMIPSState *env);
>  void r4k_helper_tlbinvf(CPUMIPSState *env);
>  void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);
> +uint32_t cpu_mips_get_random(CPUMIPSState *env);
>
>  void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
>  vaddr addr, unsigned size,
> @@ -209,7 +210,6 @@ void cpu_state_reset(CPUMIPSState *s);
>  void cpu_mips_realize_env(CPUMIPSState *env);
>
>  /* cp0_timer.c */
> -uint32_t cpu_mips_get_random(CPUMIPSState *env);
>  uint32_t cpu_mips_get_count(CPUMIPSState *env);
>  void cpu_mips_store_count(CPUMIPSState *env, uint32_t value);
>  void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value);
> diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c
> index de64add038b..12143ac55b9 100644
> --- a/target/mips/cp0_helper.c
> +++ b/target/mips/cp0_helper.c
> @@ -203,6 +203,31 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
>  *tcst |= asid;
>  }
>
> +/* XXX: do not use a global */
> +uint32_t cpu_mips_get_random(CPUMIPSState *env)
> +{
> +static uint32_t seed = 1;
> +static uint32_t prev_idx;
> +uint32_t idx;
> +uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
> +
> +if (nb_rand_tlb == 1) {
> +return env->tlb->nb_tlb - 1;
> +}
> +
> +/* Don't return same value twice, so get another value */
> +do {
> +/*
> + * Use a simple algorithm of Linear Congruential Generator
> + * from ISO/IEC 9899 standard.
> + */
> +seed = 1103515245 * seed + 12345;
> +idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
> +} while (idx == prev_idx);
> +prev_idx = idx;
> +return idx;
> +}
> +
>  /* CP0 helpers */
>  target_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
>  {
> diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
> index bd7efb152dd..9c38e9da1c8 100644
> --- a/target/mips/cp0_timer.c
> +++ b/target/mips/cp0_timer.c
> @@ -29,31 +29,6 @@
>
>  #define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */
>
> -/* XXX: do not use a global */
> -uint32_t cpu_mips_get_random(CPUMIPSState *env)
> -{
> -static uint32_t seed = 1;
> -static uint32_t prev_idx = 0;
> -uint32_t idx;
> -uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
> -
> -if (nb_rand_tlb == 1) {
> -return env->tlb->nb_tlb - 1;
> -}
> -
> -/* Don't return same value twice, so get another value */
> -do {
> -/*
> - * Use a simple algorithm of Linear Congruential Generator
> - * from ISO/IEC 9899 standard.
> - */
> -seed = 1103515245 * seed + 12345;
> -idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
> -} while (idx == prev_idx);
> -prev_idx = idx;
> -return idx;
> -}
> -
>  /* MIPS R4K timer */
>  static void cpu_mips_timer_update(CPUMIPSState *env)
>  {
> --
> 2.26.2
>
>


Re: [PATCH 08/10] scsi/scsi_bus: Add scsi_device_get

2020-09-30 Thread Maxim Levitsky
On Wed, 2020-09-30 at 19:46 +0200, Paolo Bonzini wrote:
> On 30/09/20 16:32, Maxim Levitsky wrote:
> > >   Compared to Maxim's patch, I am avoiding the extra argument
> > >   to do_scsi_device_find by moving the RCU_READ_LOCK_GUARD()
> > >   out of do_scsi_device_find itself.
> > Which is a good idea, although my mindset was like, I got a device,
> > lets just grab a ref to it before it disappears and then do
> > whatever I want.
> 
> Understood, but "I got a device, I know I'm under RCU so it can't
> disappear" is more efficient and just as common.  This also explains the
> difference in patch 7.

Fair point. I am still learing to correctly use RCU.

Best regards,
Maxim Levitsky
> 
> Paolo
> 





Re: [PATCH 06/10] device-core: use atomic_set on .realized property

2020-09-30 Thread Maxim Levitsky
On Wed, 2020-09-30 at 19:44 +0200, Paolo Bonzini wrote:
> On 30/09/20 16:31, Maxim Levitsky wrote:
> > > +
> > > +qatomic_set(>realized, value);
> > > +/*
> > > + * Ensure that concurrent users see this update prior to
> > > + * any other changes done by unrealize.
> > > + */
> > > +smp_wmb();
> > 
> > I''l probably never fully understand where to use read/write/full barrier.
> > If I understand corrctly, read barrier prevents reads done by this thread 
> > to be reordered,
> > by the CPU and write barrier prevents writes done by this CPU to be 
> > re-ordered.
> 
> I must say that the above is not really satisfactory.  The right thing
> to do would be to say which changes are done by unrealize; then you
> should make sure that *after* reading something that unrealize could
> undo you check if dev->realized is still true.
I didn't fully understand this to be honest.

I just wanted to explain what I know and what I don't know about hardware 
barriers.

I know that read barriers should be paired with write barriers, like if one CPU 
has a write barrier,
which ensures the orders of writes to two memory locations, the other CPU can 
then use a read barrier to ensure
that it sees those writes in this order.

I thus think that reads of dev->realized should be paired with read barrier, 
but here a full memory barrier isn't really needed.

Best regards,
Maxim Levitsky

> 
> scsi_device_find is one such case, but I'm not convinced it is enough.
> 
> Paolo
> 
> > Both (depending on the macro) usually imply compiler barrier (to avoid 
> > compilier re-ordering
> > stuff...)





[PULL 10/12] tests/acpi: add microvm pcie test

2020-09-30 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-11-kra...@redhat.com
---
 tests/qtest/bios-tables-test.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 7be2b3131e16..edf672d26f0b 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1091,6 +1091,18 @@ static void test_acpi_microvm_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_microvm_pcie_tcg(void)
+{
+test_data data;
+
+test_acpi_microvm_prepare();
+data.variant = ".pcie";
+data.tcg_only = true; /* need constant host-phys-bits */
+test_acpi_one(" -machine microvm,acpi=on,rtc=off,pcie=on",
+  );
+free_test_data();
+}
+
 static void test_acpi_virt_tcg_numamem(void)
 {
 test_data data = {
@@ -1213,6 +1225,9 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
 qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
 qtest_add_func("acpi/microvm", test_acpi_microvm_tcg);
+if (strcmp(arch, "x86_64") == 0) {
+qtest_add_func("acpi/microvm/pcie", test_acpi_microvm_pcie_tcg);
+}
 } else if (strcmp(arch, "aarch64") == 0) {
 qtest_add_func("acpi/virt", test_acpi_virt_tcg);
 qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
-- 
2.27.0




[PULL 06/12] microvm/pcie: add 64bit mmio window

2020-09-30 Thread Gerd Hoffmann
Place the 64bit window at the top of the physical address space, assign
25% of the avaiable address space.  Force cpu.host-phys-bits=on for
microvm machine typs so this actually works reliable.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-7-kra...@redhat.com
---
 hw/i386/microvm.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 273abe28c9c1..17e3f2f15265 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -198,6 +198,12 @@ static void microvm_devices_init(MicrovmMachineState *mms)
 }
 
 if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) {
+/* use topmost 25% of the address space available */
+hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
+if (phys_size > 0x100ll) {
+mms->gpex.mmio64.size = phys_size / 4;
+mms->gpex.mmio64.base = phys_size - mms->gpex.mmio64.size;
+}
 mms->gpex.mmio32.base = PCIE_MMIO_BASE;
 mms->gpex.mmio32.size = PCIE_MMIO_SIZE;
 mms->gpex.ecam.base   = PCIE_ECAM_BASE;
@@ -383,6 +389,9 @@ static void microvm_fix_kernel_cmdline(MachineState 
*machine)
 static void microvm_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
 {
+X86CPU *cpu = X86_CPU(dev);
+
+cpu->host_phys_bits = true; /* need reliable phys-bits */
 x86_cpu_pre_plug(hotplug_dev, dev, errp);
 }
 
-- 
2.27.0




[PULL 11/12] acpi/gpex: no reason to use a method for _CRS

2020-09-30 Thread Gerd Hoffmann
... just to return something which is constant anyway.

-Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
-{
-Return (ResourceTemplate ()
-{
-WordBusNumber (ResourceProducer, MinFixed, MaxFixed, 
PosDecode,
[ ... ]

+Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+{
+WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
[ ... ]

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-12-kra...@redhat.com
---
 hw/pci-host/gpex-acpi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 6fb951a0c19f..dbb350a837f8 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -57,7 +57,6 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 aml_append(method, aml_return(aml_int(cfg->ecam.base)));
 aml_append(dev, method);
 
-method = aml_method("_CRS", 0, AML_NOTSERIALIZED);
 Aml *rbuf = aml_resource_template();
 aml_append(rbuf,
 aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
@@ -89,8 +88,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 0x,
 cfg->mmio64.size));
 }
-aml_append(method, aml_return(rbuf));
-aml_append(dev, method);
+aml_append(dev, aml_name_decl("_CRS", rbuf));
 
 /* Declare an _OSC (OS Control Handoff) method */
 aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
-- 
2.27.0




[PULL 08/12] tests/acpi: add empty tests/data/acpi/microvm/DSDT.pcie file

2020-09-30 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-9-kra...@redhat.com
---
 tests/data/acpi/microvm/DSDT.pcie | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 tests/data/acpi/microvm/DSDT.pcie

diff --git a/tests/data/acpi/microvm/DSDT.pcie 
b/tests/data/acpi/microvm/DSDT.pcie
new file mode 100644
index ..e69de29bb2d1
-- 
2.27.0




[PULL 04/12] microvm: add irq table

2020-09-30 Thread Gerd Hoffmann
Add a comment with a table listing the IRQs,
both legacy pc and microvm side-by-side.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-5-kra...@redhat.com
---
 include/hw/i386/microvm.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
index 3b9fd4ff17fd..0d61697c97f0 100644
--- a/include/hw/i386/microvm.h
+++ b/include/hw/i386/microvm.h
@@ -27,6 +27,28 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "qom/object.h"
 
+/*
+ *  IRQ|  pc| microvm (acpi=on)
+ * ++--
+ *   0 |  pit   |
+ *   1 |  kbd   |
+ *   2 |  cascade   |
+ *   3 |  serial 1  |
+ *   4 |  serial 0  | serial
+ *   5 |  - |
+ *   6 |  floppy|
+ *   7 |  parallel  |
+ *   8 |  rtc   | rtc (rtc=on)
+ *   9 |  acpi  | acpi (ged)
+ *  10 |  pci lnk   |
+ *  11 |  pci lnk   |
+ *  12 |  ps2   |
+ *  13 |  fpu   |
+ *  14 |  ide 0 |
+ *  15 |  ide 1 |
+ *  16-23  |  pci gsi   | virtio
+ */
+
 /* Platform virtio definitions */
 #define VIRTIO_MMIO_BASE  0xfeb0
 #define VIRTIO_NUM_TRANSPORTS 8
-- 
2.27.0




[PULL 05/12] microvm: add pcie support

2020-09-30 Thread Gerd Hoffmann
Uses the existing gpex device which is also used as pcie host bridge on
arm/aarch64.  For now only a 32bit mmio window and no ioport support.

It is disabled by default, use "-machine microvm,pcie=on" to enable.
ACPI support must be enabled too because the bus is declared in the
DSDT table.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-6-kra...@redhat.com
---
 include/hw/i386/microvm.h | 18 +++--
 hw/i386/acpi-microvm.c| 12 ++
 hw/i386/microvm.c | 84 +++
 hw/i386/Kconfig   |  1 +
 4 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
index 0d61697c97f0..91b064575d55 100644
--- a/include/hw/i386/microvm.h
+++ b/include/hw/i386/microvm.h
@@ -25,6 +25,7 @@
 #include "hw/boards.h"
 #include "hw/i386/x86.h"
 #include "hw/acpi/acpi_dev_interface.h"
+#include "hw/pci-host/gpex.h"
 #include "qom/object.h"
 
 /*
@@ -42,10 +43,10 @@
  *   9 |  acpi  | acpi (ged)
  *  10 |  pci lnk   |
  *  11 |  pci lnk   |
- *  12 |  ps2   |
- *  13 |  fpu   |
- *  14 |  ide 0 |
- *  15 |  ide 1 |
+ *  12 |  ps2   | pcie
+ *  13 |  fpu   | pcie
+ *  14 |  ide 0 | pcie
+ *  15 |  ide 1 | pcie
  *  16-23  |  pci gsi   | virtio
  */
 
@@ -59,10 +60,17 @@
 #define GED_MMIO_BASE_REGS(GED_MMIO_BASE + 0x200)
 #define GED_MMIO_IRQ  9
 
+#define PCIE_MMIO_BASE0xc000
+#define PCIE_MMIO_SIZE0x2000
+#define PCIE_ECAM_BASE0xe000
+#define PCIE_ECAM_SIZE0x1000
+#define PCIE_IRQ_BASE 12
+
 /* Machine type options */
 #define MICROVM_MACHINE_PIT "pit"
 #define MICROVM_MACHINE_PIC "pic"
 #define MICROVM_MACHINE_RTC "rtc"
+#define MICROVM_MACHINE_PCIE"pcie"
 #define MICROVM_MACHINE_ISA_SERIAL  "isa-serial"
 #define MICROVM_MACHINE_OPTION_ROMS "x-option-roms"
 #define MICROVM_MACHINE_AUTO_KERNEL_CMDLINE "auto-kernel-cmdline"
@@ -80,6 +88,7 @@ struct MicrovmMachineState {
 OnOffAuto pic;
 OnOffAuto pit;
 OnOffAuto rtc;
+OnOffAuto pcie;
 bool isa_serial;
 bool option_roms;
 bool auto_kernel_cmdline;
@@ -89,6 +98,7 @@ struct MicrovmMachineState {
 bool kernel_cmdline_fixed;
 Notifier machine_done;
 Notifier powerdown_req;
+struct GPEXConfig gpex;
 };
 
 #define TYPE_MICROVM_MACHINE   MACHINE_TYPE_NAME("microvm")
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index df39c5d3bd90..f16f2311955c 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -33,6 +33,8 @@
 #include "hw/boards.h"
 #include "hw/i386/fw_cfg.h"
 #include "hw/i386/microvm.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pcie_host.h"
 #include "hw/virtio/virtio-mmio.h"
 
 #include "acpi-common.h"
@@ -87,6 +89,15 @@ static void acpi_dsdt_add_virtio(Aml *scope,
 }
 }
 
+static void acpi_dsdt_add_pci(Aml *scope, MicrovmMachineState *mms)
+{
+if (mms->pcie != ON_OFF_AUTO_ON) {
+return;
+}
+
+acpi_dsdt_add_gpex(scope, >gpex);
+}
+
 static void
 build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
MicrovmMachineState *mms)
@@ -112,6 +123,7 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
   GED_MMIO_IRQ, AML_SYSTEM_MEMORY, GED_MMIO_BASE);
 acpi_dsdt_add_power_button(sb_scope);
 acpi_dsdt_add_virtio(sb_scope, mms);
+acpi_dsdt_add_pci(sb_scope, mms);
 aml_append(dsdt, sb_scope);
 
 /* ACPI 5.0: Table 7-209 System State Package */
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 60d32722301f..273abe28c9c1 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -46,6 +46,7 @@
 #include "hw/virtio/virtio-mmio.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/generic_event_device.h"
+#include "hw/pci-host/gpex.h"
 
 #include "cpu.h"
 #include "elf.h"
@@ -101,6 +102,55 @@ static void microvm_gsi_handler(void *opaque, int n, int 
level)
 qemu_set_irq(s->ioapic_irq[n], level);
 }
 
+static void create_gpex(MicrovmMachineState *mms)
+{
+X86MachineState *x86ms = X86_MACHINE(mms);
+MemoryRegion *mmio32_alias;
+MemoryRegion *mmio64_alias;
+MemoryRegion *mmio_reg;
+MemoryRegion *ecam_alias;
+MemoryRegion *ecam_reg;
+DeviceState *dev;
+int i;
+
+dev = qdev_new(TYPE_GPEX_HOST);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+
+/* Map only the first size_ecam bytes of ECAM space */
+ecam_alias = g_new0(MemoryRegion, 1);
+ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+ ecam_reg, 0, mms->gpex.ecam.size);
+memory_region_add_subregion(get_system_memory(),
+mms->gpex.ecam.base, ecam_alias);
+
+/* Map the MMIO window into system 

[PULL 02/12] acpi: add acpi_dsdt_add_gpex

2020-09-30 Thread Gerd Hoffmann
Add helper function to generate dsdt aml code for the gpex pci host.
Largely copied from arm/virt.  Configuration is handled by passing
a config struct instead of looked up from memory map.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-3-kra...@redhat.com
---
 include/hw/pci-host/gpex.h |  11 +++
 hw/pci-host/gpex-acpi.c| 179 +
 hw/pci-host/meson.build|   1 +
 3 files changed, 191 insertions(+)
 create mode 100644 hw/pci-host/gpex-acpi.c

diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
index 7abdb8b406e0..d52ea80d4e04 100644
--- a/include/hw/pci-host/gpex.h
+++ b/include/hw/pci-host/gpex.h
@@ -20,6 +20,7 @@
 #ifndef HW_GPEX_H
 #define HW_GPEX_H
 
+#include "exec/hwaddr.h"
 #include "hw/sysbus.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie_host.h"
@@ -52,6 +53,16 @@ struct GPEXHost {
 int irq_num[GPEX_NUM_IRQS];
 };
 
+struct GPEXConfig {
+MemMapEntry ecam;
+MemMapEntry mmio32;
+MemMapEntry mmio64;
+MemMapEntry pio;
+int irq;
+};
+
 int gpex_set_irq_num(GPEXHost *s, int index, int gsi);
 
+void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg);
+
 #endif /* HW_GPEX_H */
diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
new file mode 100644
index ..6fb951a0c19f
--- /dev/null
+++ b/hw/pci-host/gpex-acpi.c
@@ -0,0 +1,179 @@
+#include "qemu/osdep.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/pci-host/gpex.h"
+
+void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
+{
+int nr_pcie_buses = cfg->ecam.size / PCIE_MMCFG_SIZE_MIN;
+Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
+int i, slot_no;
+
+Aml *dev = aml_device("%s", "PCI0");
+aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08")));
+aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
+aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
+aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
+aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
+
+/* Declare the PCI Routing Table. */
+Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS);
+for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
+int gsi = (i + slot_no) % PCI_NUM_PINS;
+Aml *pkg = aml_package(4);
+aml_append(pkg, aml_int((slot_no << 16) | 0x));
+aml_append(pkg, aml_int(i));
+aml_append(pkg, aml_name("GSI%d", gsi));
+aml_append(pkg, aml_int(0));
+aml_append(rt_pkg, pkg);
+}
+}
+aml_append(dev, aml_name_decl("_PRT", rt_pkg));
+
+/* Create GSI link device */
+for (i = 0; i < PCI_NUM_PINS; i++) {
+uint32_t irqs = cfg->irq + i;
+Aml *dev_gsi = aml_device("GSI%d", i);
+aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
+aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i)));
+crs = aml_resource_template();
+aml_append(crs,
+   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, , 1));
+aml_append(dev_gsi, aml_name_decl("_PRS", crs));
+crs = aml_resource_template();
+aml_append(crs,
+   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, , 1));
+aml_append(dev_gsi, aml_name_decl("_CRS", crs));
+method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
+aml_append(dev_gsi, method);
+aml_append(dev, dev_gsi);
+}
+
+method = aml_method("_CBA", 0, AML_NOTSERIALIZED);
+aml_append(method, aml_return(aml_int(cfg->ecam.base)));
+aml_append(dev, method);
+
+method = aml_method("_CRS", 0, AML_NOTSERIALIZED);
+Aml *rbuf = aml_resource_template();
+aml_append(rbuf,
+aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
+0x, 0x, nr_pcie_buses - 1, 0x,
+nr_pcie_buses));
+if (cfg->mmio32.size) {
+aml_append(rbuf,
+   aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, 
AML_MAX_FIXED,
+AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
+cfg->mmio32.base,
+cfg->mmio32.base + cfg->mmio32.size - 1,
+0x,
+cfg->mmio32.size));
+}
+if (cfg->pio.size) {
+aml_append(rbuf,
+   aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
+AML_ENTIRE_RANGE, 0x, 0x,
+cfg->pio.size - 1,
+

[PULL 00/12] Microvm 20200930 patches

2020-09-30 Thread Gerd Hoffmann
The following changes since commit b150cb8f67bf491a49a1cb1c7da151eeacbdbcc9:

  Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging 
(2020-09-29 13:18:54 +0100)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/microvm-20200930-pull-request

for you to fetch changes up to 7f6c3d1a574bddcda6931eb00287089998725f71:

  tests/acpi: update expected data files (2020-09-30 11:29:56 +0200)


microvm: add pcie support.



Gerd Hoffmann (12):
  move MemMapEntry
  acpi: add acpi_dsdt_add_gpex
  arm: use acpi_dsdt_add_gpex
  microvm: add irq table
  microvm: add pcie support
  microvm/pcie: add 64bit mmio window
  tests/acpi: allow updates for expected data files
  tests/acpi: add empty tests/data/acpi/microvm/DSDT.pcie file
  tests/acpi: factor out common microvm test setup
  tests/acpi: add microvm pcie test
  acpi/gpex: no reason to use a method for _CRS
  tests/acpi: update expected data files

 include/exec/hwaddr.h |   5 +
 include/hw/arm/virt.h |   5 -
 include/hw/i386/microvm.h |  32 ++
 include/hw/pci-host/gpex.h|  11 ++
 hw/arm/sbsa-ref.c |   5 -
 hw/arm/virt-acpi-build.c  | 175 ++---
 hw/i386/acpi-microvm.c|  12 ++
 hw/i386/microvm.c |  93 
 hw/pci-host/gpex-acpi.c   | 177 ++
 tests/qtest/bios-tables-test.c|  30 -
 hw/i386/Kconfig   |   1 +
 hw/pci-host/meson.build   |   1 +
 tests/data/acpi/microvm/DSDT.pcie | Bin 0 -> 3023 bytes
 tests/data/acpi/virt/DSDT | Bin 5200 -> 5196 bytes
 tests/data/acpi/virt/DSDT.memhp   | Bin 6561 -> 6557 bytes
 tests/data/acpi/virt/DSDT.numamem | Bin 5200 -> 5196 bytes
 16 files changed, 366 insertions(+), 181 deletions(-)
 create mode 100644 hw/pci-host/gpex-acpi.c
 create mode 100644 tests/data/acpi/microvm/DSDT.pcie

-- 
2.27.0





[PULL 01/12] move MemMapEntry

2020-09-30 Thread Gerd Hoffmann
It is defined twice already.  Move to a common header file to
remove duplication and make it available to everybody.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-2-kra...@redhat.com
---
 include/exec/hwaddr.h | 5 +
 include/hw/arm/virt.h | 5 -
 hw/arm/sbsa-ref.c | 5 -
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/include/exec/hwaddr.h b/include/exec/hwaddr.h
index a71c93cc810a..8f16d179a885 100644
--- a/include/exec/hwaddr.h
+++ b/include/exec/hwaddr.h
@@ -18,4 +18,9 @@ typedef uint64_t hwaddr;
 #define HWADDR_PRIx PRIx64
 #define HWADDR_PRIX PRIX64
 
+typedef struct MemMapEntry {
+hwaddr base;
+hwaddr size;
+} MemMapEntry;
+
 #endif
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index d018a4f29788..655b895d5eba 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -111,11 +111,6 @@ typedef enum VirtGICType {
 VIRT_GIC_VERSION_NOSEL,
 } VirtGICType;
 
-typedef struct MemMapEntry {
-hwaddr base;
-hwaddr size;
-} MemMapEntry;
-
 struct VirtMachineClass {
 MachineClass parent;
 bool disallow_affinity_adjustment;
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 257ada942550..9c3a893bedfd 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -80,11 +80,6 @@ enum {
 SBSA_EHCI,
 };
 
-typedef struct MemMapEntry {
-hwaddr base;
-hwaddr size;
-} MemMapEntry;
-
 struct SBSAMachineState {
 MachineState parent;
 struct arm_boot_info bootinfo;
-- 
2.27.0




[PULL 12/12] tests/acpi: update expected data files

2020-09-30 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-13-kra...@redhat.com
---
 tests/qtest/bios-tables-test-allowed-diff.h |   5 -
 tests/data/acpi/microvm/DSDT.pcie   | Bin 0 -> 3023 bytes
 tests/data/acpi/virt/DSDT   | Bin 5200 -> 5196 bytes
 tests/data/acpi/virt/DSDT.memhp | Bin 6561 -> 6557 bytes
 tests/data/acpi/virt/DSDT.numamem   | Bin 5200 -> 5196 bytes
 5 files changed, 5 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 53109c22a56f..dfb8523c8bf4 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,6 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/microvm/DSDT.pcie32",
-"tests/data/acpi/microvm/DSDT.pcie64",
-"tests/data/acpi/virt/DSDT",
-"tests/data/acpi/virt/DSDT.numamem",
-"tests/data/acpi/virt/DSDT.memhp",
diff --git a/tests/data/acpi/microvm/DSDT.pcie 
b/tests/data/acpi/microvm/DSDT.pcie
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4b765541e372f4ba4e25529c14acf696516c8f61
 100644
GIT binary patch
literal 3023
zcmZveJ!~UI6vyA%>v%o>$l7tfKOE>z2(-2p9Su_KwUZdd$)4A_AbirEgg_i=B7u>USJmoBTcK$Q(y?MX4yR*{?JHy}e
zM5$ZtLw_`+)y9gJB-#C^WHyN7IvbrYb4M>090Z>4`FbrR(zfpoyxV$i|6p(k+ATe)
zvdF@3frN8eQHzgqWKrqo7nCAGUY50}^E%)DDe!yV%lIwtZ6*K
z;5;%Mlxu1~lA#IX}e+RwK=>dI!E5S%75DbQM`=6?_O5V;-r?eaPJkos&{W?_&
zJg!m@jYOm#;h3OQxSKD1F_JUza&&7T)O(c6FeryX=ZF{BIGcn~7Ytz^hl0A`4
zY@3cflMK?to`@QornM(b6Um;)DE72tpo_DoD|?U^JGX>w)+XD0ScOf%XuNgmSV
zoDrP3xyUCmospc7CTCV~W(8+fazdJ%j^K0zrz1HbO-{TJMy2ss>gvVC%t=m2lT!&!
zB{-Gjgfuy^d+3_P_b4wo^O6(N!Eb=d9#}GwKsXGL*h1m~RO
zgfuy;g0m_(tCADaTIUzOY=)7n17WDEH?Rz`dAL8Kps9{;yt8moN
zpL~7%NXDu);#t5Ev96Mx^YL*b-ghQj7`Ba|My4)rc))p$i#DkWoKJG&7}kI7ig
zSH()pSlHlh#L{C|v8sj0Z@1`@Yw=8%;vl2m|F%de9wM4@V|{}+tH1|G{ymvar+?`#
zZC<=#%;;)x_x{m%+40BaIpvP}e>VTC
zt!@8s{8{VCJAZt1aiVM(G;norZJx5=INWJ+sE6FB8n+Yo@%VxD6=v$Ob$zn%c%0bj
zVV5UQ*_g*KPkt=vabBc;c~X5d>V$oJ@|w=(>FwYC4!6GSf4}%ofB9FxKgo?hq04gG
zvbe#qvTqN%p?Kc-49y40rt)so=NVT8)%lmN#tBB@WX~y=AYLc8xe#DNRqX~yo2YLc8xPAfJ$a^BSh86~NP`Ig
DNc#-*

diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
index 
545a18c3657781d350a006adfa5e58fa63e63922..54728e2b4b8b959f3f829386f6a388ef2600e747
 100644
GIT binary patch
delta 43
zcmZ2zJlB}ZCDSh86~sFEE3
DEVvAM

diff --git a/tests/data/acpi/virt/DSDT.numamem 
b/tests/data/acpi/virt/DSDT.numamem
index 
9b002836f35fd03afeab9e827fdde3134d26ed2e..bc519abff9cadc1552e4e586b0a3f5f0db498f4a
 100644
GIT binary patch
delta 43
zcmcbhaYlp7CDBB@WX~y=AYLc8xe#DNRqX~yo2YLc8xPAfJ$a^BSh86~NP`Ig
DNc#-*

-- 
2.27.0




[PULL 09/12] tests/acpi: factor out common microvm test setup

2020-09-30 Thread Gerd Hoffmann
... into new test_acpi_microvm_prepare helper

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-10-kra...@redhat.com
---
 tests/qtest/bios-tables-test.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 3c09b844f9de..7be2b3131e16 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1072,15 +1072,20 @@ static void test_acpi_virt_tcg_memhp(void)
 
 }
 
+static void test_acpi_microvm_prepare(test_data *data)
+{
+memset(data, 0, sizeof(*data));
+data->machine = "microvm";
+data->required_struct_types = NULL; /* no smbios */
+data->required_struct_types_len = 0;
+data->blkdev = "virtio-blk-device";
+}
+
 static void test_acpi_microvm_tcg(void)
 {
 test_data data;
 
-memset(, 0, sizeof(data));
-data.machine = "microvm";
-data.required_struct_types = NULL; /* no smbios */
-data.required_struct_types_len = 0;
-data.blkdev = "virtio-blk-device";
+test_acpi_microvm_prepare();
 test_acpi_one(" -machine microvm,acpi=on,rtc=off",
   );
 free_test_data();
-- 
2.27.0




[PULL 07/12] tests/acpi: allow updates for expected data files

2020-09-30 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-8-kra...@redhat.com
---
 tests/qtest/bios-tables-test-allowed-diff.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..53109c22a56f 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,6 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/microvm/DSDT.pcie32",
+"tests/data/acpi/microvm/DSDT.pcie64",
+"tests/data/acpi/virt/DSDT",
+"tests/data/acpi/virt/DSDT.numamem",
+"tests/data/acpi/virt/DSDT.memhp",
-- 
2.27.0




[PULL 03/12] arm: use acpi_dsdt_add_gpex

2020-09-30 Thread Gerd Hoffmann
Fill gpex config struct from memory map, then call the new
acpi_dsdt_add_gpex helper function.  No functional change.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Michael S. Tsirkin 
Message-id: 20200928104256.9241-4-kra...@redhat.com
---
 hw/arm/virt-acpi-build.c | 175 ++-
 1 file changed, 9 insertions(+), 166 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6bff5e373872..9747a6458f0b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -44,6 +44,7 @@
 #include "hw/acpi/tpm.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
+#include "hw/pci-host/gpex.h"
 #include "hw/arm/virt.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/platform-bus.h"
@@ -155,176 +156,18 @@ static void acpi_dsdt_add_pci(Aml *scope, const 
MemMapEntry *memmap,
   uint32_t irq, bool use_highmem, bool 
highmem_ecam)
 {
 int ecam_id = VIRT_ECAM_ID(highmem_ecam);
-Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
-int i, slot_no;
-hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base;
-hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size;
-hwaddr base_pio = memmap[VIRT_PCIE_PIO].base;
-hwaddr size_pio = memmap[VIRT_PCIE_PIO].size;
-hwaddr base_ecam = memmap[ecam_id].base;
-hwaddr size_ecam = memmap[ecam_id].size;
-int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
-
-Aml *dev = aml_device("%s", "PCI0");
-aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08")));
-aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
-aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
-aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
-aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
-aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
-/* Declare the PCI Routing Table. */
-Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS);
-for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) {
-for (i = 0; i < PCI_NUM_PINS; i++) {
-int gsi = (i + slot_no) % PCI_NUM_PINS;
-Aml *pkg = aml_package(4);
-aml_append(pkg, aml_int((slot_no << 16) | 0x));
-aml_append(pkg, aml_int(i));
-aml_append(pkg, aml_name("GSI%d", gsi));
-aml_append(pkg, aml_int(0));
-aml_append(rt_pkg, pkg);
-}
-}
-aml_append(dev, aml_name_decl("_PRT", rt_pkg));
-
-/* Create GSI link device */
-for (i = 0; i < PCI_NUM_PINS; i++) {
-uint32_t irqs =  irq + i;
-Aml *dev_gsi = aml_device("GSI%d", i);
-aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
-aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i)));
-crs = aml_resource_template();
-aml_append(crs,
-   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, , 1));
-aml_append(dev_gsi, aml_name_decl("_PRS", crs));
-crs = aml_resource_template();
-aml_append(crs,
-   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, , 1));
-aml_append(dev_gsi, aml_name_decl("_CRS", crs));
-method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
-aml_append(dev_gsi, method);
-aml_append(dev, dev_gsi);
-}
-
-method = aml_method("_CBA", 0, AML_NOTSERIALIZED);
-aml_append(method, aml_return(aml_int(base_ecam)));
-aml_append(dev, method);
-
-method = aml_method("_CRS", 0, AML_NOTSERIALIZED);
-Aml *rbuf = aml_resource_template();
-aml_append(rbuf,
-aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
-0x, 0x, nr_pcie_buses - 1, 0x,
-nr_pcie_buses));
-aml_append(rbuf,
-aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
- AML_NON_CACHEABLE, AML_READ_WRITE, 0x, base_mmio,
- base_mmio + size_mmio - 1, 0x, size_mmio));
-aml_append(rbuf,
-aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
- AML_ENTIRE_RANGE, 0x, 0x, size_pio - 1, base_pio,
- size_pio));
+struct GPEXConfig cfg = {
+.mmio32 = memmap[VIRT_PCIE_MMIO],
+.pio= memmap[VIRT_PCIE_PIO],
+.ecam   = memmap[ecam_id],
+.irq= irq,
+};
 
 if (use_highmem) {
-hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base;
-hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size;
-
-aml_append(rbuf,
-aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
- AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
- base_mmio_high,
- base_mmio_high + 

Re: [PATCH 01/10] qdev: add "check if address free" callback for buses

2020-09-30 Thread Paolo Bonzini
On 28/09/20 11:30, Stefan Hajnoczi wrote:
>> +bool (*check_address)(BusState *bus, DeviceState *dev, Error **errp);
> Please document this function.

I will add this:

/*
 * Return whether the device can be added to @bus,
 * based on the address that was set (via device properties)
 * before realize.  If not, on return @errp contains the
 * human-readable error message.
 */



signature.asc
Description: OpenPGP digital signature


Re: [PATCH 08/10] scsi/scsi_bus: Add scsi_device_get

2020-09-30 Thread Paolo Bonzini
On 30/09/20 16:32, Maxim Levitsky wrote:
>>  Compared to Maxim's patch, I am avoiding the extra argument
>>  to do_scsi_device_find by moving the RCU_READ_LOCK_GUARD()
>>  out of do_scsi_device_find itself.
> Which is a good idea, although my mindset was like, I got a device,
> lets just grab a ref to it before it disappears and then do
> whatever I want.

Understood, but "I got a device, I know I'm under RCU so it can't
disappear" is more efficient and just as common.  This also explains the
difference in patch 7.

Paolo




Re: [PATCH 06/10] device-core: use atomic_set on .realized property

2020-09-30 Thread Paolo Bonzini
On 30/09/20 16:31, Maxim Levitsky wrote:
>> +
>> +qatomic_set(>realized, value);
>> +/*
>> + * Ensure that concurrent users see this update prior to
>> + * any other changes done by unrealize.
>> + */
>> +smp_wmb();
>
> I''l probably never fully understand where to use read/write/full barrier.
> If I understand corrctly, read barrier prevents reads done by this thread to 
> be reordered,
> by the CPU and write barrier prevents writes done by this CPU to be 
> re-ordered.

I must say that the above is not really satisfactory.  The right thing
to do would be to say which changes are done by unrealize; then you
should make sure that *after* reading something that unrealize could
undo you check if dev->realized is still true.

scsi_device_find is one such case, but I'm not convinced it is enough.

Paolo

> Both (depending on the macro) usually imply compiler barrier (to avoid 
> compilier re-ordering
> stuff...)




Re: [PATCH v4 04/46] qapi: modify docstrings to be sphinx-compatible

2020-09-30 Thread John Snow

On 9/30/20 4:47 AM, Markus Armbruster wrote:

Sadly, the fact that start_if() and end_if() are functions isn't
immediately obvious anymore.

I've seen :func:`start_if` elsewhere.  Is this something we should or
want to use?


Looks like `start_if()` works just fine too. If you are hard-set in 
wanting to see those parentheses I can use this style, but admit I am 
not likely to use them myself in newer docstrings, and there's no way to 
enforce their presence OR absence that I am aware of.


I'll bake that change in for now until I see another reply.

--js




Re: [PATCH v3 00/11] user-mode: Prune build dependencies (part 3)

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 07:24:24PM +0200, Paolo Bonzini wrote:
> On 30/09/20 19:15, Eduardo Habkost wrote:
> > On Wed, Sep 30, 2020 at 06:49:38PM +0200, Philippe Mathieu-Daudé wrote:
> >> This is the third part of a series reducing user-mode
> >> dependencies. By stripping out unused code, the build
> >> and testing time is reduced (as is space used by objects).
> > I'm queueing patches 2-9 on machine-next.  Thanks!
> > 
> > Markus, Eric: I can merge the QAPI patches (1, 11) if I get an
> > Acked-by.
> > 
> > I'll send separate comments on patch 10.
> > 
> 
> 1-8 is fine, but I think 9-11 is too much complication (especially not
> really future-proof) for the benefit.

I'll dequeue patch 9 while this is discussed.

-- 
Eduardo




Re: [PATCH v3 00/11] user-mode: Prune build dependencies (part 3)

2020-09-30 Thread Paolo Bonzini
On 30/09/20 19:15, Eduardo Habkost wrote:
> On Wed, Sep 30, 2020 at 06:49:38PM +0200, Philippe Mathieu-Daudé wrote:
>> This is the third part of a series reducing user-mode
>> dependencies. By stripping out unused code, the build
>> and testing time is reduced (as is space used by objects).
> I'm queueing patches 2-9 on machine-next.  Thanks!
> 
> Markus, Eric: I can merge the QAPI patches (1, 11) if I get an
> Acked-by.
> 
> I'll send separate comments on patch 10.
> 

1-8 is fine, but I think 9-11 is too much complication (especially not
really future-proof) for the benefit.

Paolo




Re: [PATCH v4 38/46] qapi/introspect.py: add _gen_features helper

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 12:31:42AM -0400, John Snow wrote:
> _make_tree might receive a dict or some other type. Adding features
> information should arguably be performed by the caller at such a time
> when we know the type of the object and don't have to re-interrogate it.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/introspect.py | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index f7de3953391..5cbdc7414bd 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -52,16 +52,12 @@
>  
>  
>  def _make_tree(obj: Union[_DObject, str], ifcond: List[str],
> -   features: List[QAPISchemaFeature],
> extra: Optional[Extra] = None
> ) -> Union[TreeNode, AnnotatedNode]:
>  if extra is None:
>  extra = {}
>  if ifcond:
>  extra['if'] = ifcond
> -if features:
> -assert isinstance(obj, dict)
> -obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]

Now the reason for moving this code outside _make_tree() is more
obvious due to the type annotations.

Reviewed-by: Eduardo Habkost 

>  if extra:
>  return (obj, extra)
>  return obj
> @@ -197,6 +193,11 @@ def _use_type(self, typ: QAPISchemaType) -> str:
>  return '[' + self._use_type(typ.element_type) + ']'
>  return self._name(typ.name)
>  
> +@classmethod
> +def _gen_features(cls,
> +  features: List[QAPISchemaFeature]) -> List[TreeNode]:
> +return [_make_tree(f.name, f.ifcond) for f in features]
> +
>  def _gen_tree(self, name: str, mtype: str, obj: _DObject,
>ifcond: List[str],
>features: Optional[List[QAPISchemaFeature]]) -> None:
> @@ -209,7 +210,9 @@ def _gen_tree(self, name: str, mtype: str, obj: _DObject,
>  name = self._name(name)
>  obj['name'] = name
>  obj['meta-type'] = mtype
> -self._trees.append(_make_tree(obj, ifcond, features, extra))
> +if features:
> +obj['features'] = self._gen_features(features)
> +self._trees.append(_make_tree(obj, ifcond, extra))
>  
>  def _gen_member(self,
>  member: QAPISchemaObjectTypeMember) -> TreeNode:
> @@ -219,7 +222,9 @@ def _gen_member(self,
>  }
>  if member.optional:
>  obj['default'] = None
> -return _make_tree(obj, member.ifcond, member.features)
> +if member.features:
> +obj['features'] = self._gen_features(member.features)
> +return _make_tree(obj, member.ifcond)
>  
>  def _gen_variants(self, tag_name: str,
>variants: List[QAPISchemaVariant]) -> _DObject:
> @@ -231,7 +236,7 @@ def _gen_variant(self, variant: QAPISchemaVariant) -> 
> TreeNode:
>  'case': variant.name,
>  'type': self._use_type(variant.type)
>  }
> -return _make_tree(obj, variant.ifcond, None)
> +return _make_tree(obj, variant.ifcond)
>  
>  def visit_builtin_type(self, name: str, info: Optional[QAPISourceInfo],
> json_type: str) -> None:
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PATCH v4 04/46] qapi: modify docstrings to be sphinx-compatible

2020-09-30 Thread John Snow

On 9/30/20 4:47 AM, Markus Armbruster wrote:

John Snow  writes:


I did not say "sphinx beautiful", just "sphinx compatible". They will
not throw errors when parsed and interpreted as ReST.


"Bang on the keyboard until Sphinx doesn't throw errors anymore" might
be good enough for a certain kind of mathematician, but a constructive
solution needs a bit more direction.  Is there a specification to
follow?  Other useful resources?



I don't know if you are asking this question rhetorically, or in good faith.

Let me preface this by saying: This series, and these 119 patches, are 
not about finding a style guide for our docstring utilization or about 
proposing one. It is also not about rigorously adding such documentation 
or about finding ways to meaningfully publish it with e.g. Sphinx, or 
the styling of such pages.


Why bother to add docstrings at all, then? Because I needed them for my 
own sake when learning this code and I felt it would be a waste to just 
delete them, and I am of sound mind and able body and believe that some 
documentation was better than none. They are useful even just as plaintext.


Having said that, let's explore the actual style I tend to use.

I mentioned before in response to a review comment that there isn't 
really any standard for docstrings. There are a few competing "styles", 
but none of which are able to be programmatically checked and validated.


The primary guide for docstrings is PEP 257, of which I follow some but 
not all of the recommendations.


https://www.python.org/dev/peps/pep-0257/

In general,

- Always use triple-double quotes (unenforced)
- Modules, classes, and functions should have docstrings (pylint)
- No empty lines before or after the docstring (unenforced)
- Multi-line docstrings should take the form (unenforced):

"""
single-line summary of function.

Additional prose if needed describing the function.

:param x: Input such that blah blah.
:raises y: When input ``x`` is unsuitable because blah blah.
:returns: A value that blah blah.
"""

PEP257 suggests a form where the single-line summary appears on the same 
line as the opening triple quotes. I don't like this, and prefer 
symmetry. PEP257 *also* suggests that writing it my way is equivalent to 
their way, because any docstring processor should trim the first line. I 
take this as tacit admission that my way is acceptable and has merit.


What about the syntax or markup inside the docstring itself? there is 
*absolutely no standard*, but Sphinx autodoc recognizes a few field 
lists as significant in its parsing, so I prefer using them:


:param x: Denotes the parameter X. Do not use type information in the 
string, we rely on mypy for that now.


:raises y: explains a case in which an Exception type y may be raised 
either directly by this code or anticipated to be allowed to be raised 
by a helper call. (There's no standard here that I am aware of. I use my 
judgment. Always document direct raise calls, but use your judgment for 
sub-calls.)


:returns: explains the semantics of the return value.

That said, literally any sphinx/ReST markup is OK as long as it passes 
make sphinxdocs. Some sphinx markup is prohibited, like adding new 
full-throated sections. You can use arbitrary field lists, definition 
lists, pre-formatted text, examples, code blocks, whatever.


In general, you are not going to find the kind of semantic validation 
you want to ensure that the parameter names are correct, or that you 
spelled :param: right, or that you didn't miss a parameter or an 
exception. None of that tooling exists for Python.


Thus, it's all rather subjective. No right answers, no validation tools. 
Just whatever seems reasonable to a human eye until such time we 
actually decide to pursue publishing the API docs in the development 
manual, if indeed we ever do so at all.


That series sounds like a great opportunity to hash this all out. That 
is when I would like to remove --missing-docstring, too. There will 
absolutely be a "docstring series" in the future, but I am insisting 
stubbornly it happen after strict typing.




Signed-off-by: John Snow 
---
  scripts/qapi/gen.py| 6 --
  scripts/qapi/parser.py | 9 +
  2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index ca66c82b5b8..fc19b2aeb9b 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -154,9 +154,11 @@ def _bottom(self):
  
  @contextmanager

  def ifcontext(ifcond, *args):
-"""A 'with' statement context manager to wrap with start_if()/end_if()
+"""
+A 'with' statement context manager that wraps with `start_if` and `end_if`.


Sadly, the fact that start_if() and end_if() are functions isn't
immediately obvious anymore.

I've seen :func:`start_if` elsewhere.  Is this something we should or
want to use?



We *could*.

`start_if` relies on the default role, which I have provisionally set to 
"any" here, so this is shorthand for :any:`start_if`.


Re: [PATCH v7 06/13] qmp: Call monitor_set_cur() only in qmp_dispatch()

2020-09-30 Thread Dr. David Alan Gilbert
* Kevin Wolf (kw...@redhat.com) wrote:
> Am 30.09.2020 um 15:14 hat Markus Armbruster geschrieben:
> > Kevin Wolf  writes:
> > 
> > > Am 30.09.2020 um 11:26 hat Markus Armbruster geschrieben:
> > >> Kevin Wolf  writes:
> > >> 
> > >> > Am 28.09.2020 um 13:42 hat Markus Armbruster geschrieben:
> > >> >> Kevin Wolf  writes:
> > >> >> 
> > >> >> > Am 14.09.2020 um 17:10 hat Markus Armbruster geschrieben:
> > >> >> >> Kevin Wolf  writes:
> > [...]
> > >> >> >> > diff --git a/monitor/qmp.c b/monitor/qmp.c
> > >> >> >> > index 8469970c69..922fdb5541 100644
> > >> >> >> > --- a/monitor/qmp.c
> > >> >> >> > +++ b/monitor/qmp.c
> > >> >> >> > @@ -135,16 +135,10 @@ static void monitor_qmp_respond(MonitorQMP 
> > >> >> >> > *mon, QDict *rsp)
> > >> >> >> >  
> > >> >> >> >  static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
> > >> >> >> >  {
> > >> >> >> > -Monitor *old_mon;
> > >> >> >> >  QDict *rsp;
> > >> >> >> >  QDict *error;
> > >> >> >> >  
> > >> >> >> > -old_mon = monitor_set_cur(>common);
> > >> >> >> > -assert(old_mon == NULL);
> > >> >> >> > -
> > >> >> >> > -rsp = qmp_dispatch(mon->commands, req, 
> > >> >> >> > qmp_oob_enabled(mon));
> > >> >> >> > -
> > >> >> >> > -monitor_set_cur(NULL);
> > >> >> >> > +rsp = qmp_dispatch(mon->commands, req, 
> > >> >> >> > qmp_oob_enabled(mon), >common);
> > >> >> >> 
> > >> >> >> Long line.  Happy to wrap it in my tree.  A few more in PATCH 
> > >> >> >> 08-11.
> > >> >> >
> > >> >> > It's 79 characters. Should be fine even with your local deviation 
> > >> >> > from
> > >> >> > the coding style to require less than that for comments?
> > >> >> 
> > >> >> Let me rephrase my remark.
> > >> >> 
> > >> >> For me,
> > >> >> 
> > >> >> rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon),
> > >> >>>common);
> > >> >> 
> > >> >> is significantly easier to read than
> > >> >> 
> > >> >> rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon), 
> > >> >> >common);
> > >> >
> > >> > I guess this is highly subjective. I find wrapped lines harder to read.
> > >> > For answering subjective questions like this, we generally use the
> > >> > coding style document.
> > >> >
> > >> > Anyway, I guess following an idiosyncratic coding style that is
> > >> > different from every other subsystem in QEMU is possible (if
> > >> > inconvenient) if I know what it is.
> > >> 
> > >> The applicable coding style document is PEP 8.
> > >
> > > I'll happily apply PEP 8 to Python code, but this is C. I don't think
> > > PEP 8 applies very well to C code. (In fact, PEP 7 exists as a C style
> > > guide, but we're not writing C code for the Python project here...)
> > 
> > I got confused (too much Python code review), my apologies.
> > 
> > >> > My problem is more that I don't know what the exact rules are. Can they
> > >> > only be figured out experimentally by submitting patches and seeing
> > >> > whether you like them or not?
> > >> 
> > >> PEP 8:
> > >> 
> > >> A style guide is about consistency.  Consistency with this style
> > >> guide is important.  Consistency within a project is more important.
> > >> Consistency within one module or function is the most important.
> > >> 
> > >> In other words, you should make a reasonable effort to blend in.
> > >
> > > The project style guide for C is defined in CODING_STYLE.rst. Missing
> > > consistency with it is what I'm complaining about.
> > >
> > > I also agree that consistency within one module or function is most
> > > important, which is why I allow you to reformat my code. But I don't
> > > think it means that local coding style rules shouldn't be documented,
> > > especially if you can't just look at the code and see immediately how
> > > it's supposed to be.
> > >
> > >> >> Would you mind me wrapping this line in my tree?
> > >> >
> > >> > I have no say in this subsystem and I take it that you want all code to
> > >> > look as if you had written it yourself, so do as you wish.
> > >> 
> > >> I'm refusing the bait.
> > >> 
> > >> > But I understand that I'll have to respin anyway, so if you could
> > >> > explain what you're after, I might be able to apply the rules for the
> > >> > next version of the series.
> > >> 
> > >> First, PEP 8 again:
> > >> 
> > >> Limit all lines to a maximum of 79 characters.
> > >> 
> > >> For flowing long blocks of text with fewer structural restrictions
> > >> (docstrings or comments), the line length should be limited to 72
> > >> characters.
> > >
> > > Ok, that's finally clear limits at least.
> > >
> > > Any other rules from PEP 8 that you want to see applied to C code?
> > 
> > PEP 8 does not apply to C.
> > 
> > > Would you mind documenting this somewhere?
> > >
> > >> Second, an argument we two had on this list, during review of a prior
> > >> version of this patch series, talking about C:
> > >> 
> > >> Legibility.  Humans tend to have trouble following long lines with
> > >> 

Re: [PATCH 2/4] nbd: silence maybe-uninitialized warnings

2020-09-30 Thread Eric Blake
On 9/30/20 10:58 AM, Christian Borntraeger wrote:
> gcc 10 from Fedora 32 gives me:
> 
> Compiling C object libblock.fa.p/nbd_server.c.o
> ../nbd/server.c: In function ‘nbd_co_client_start’:
> ../nbd/server.c:625:14: error: ‘namelen’ may be used uninitialized in this 
> function [-Werror=maybe-uninitialized]
>   625 | rc = nbd_negotiate_send_info(client, NBD_INFO_NAME, namelen, 
> name,
>   |  
> ^
>   626 |  errp);
>   |  ~
> ../nbd/server.c:564:14: note: ‘namelen’ was declared here
>   564 | uint32_t namelen;
>   |  ^~~
> cc1: all warnings being treated as errors
> 
> As I cannot see how this can happen, let uns silence the warning.

gcc is smart enough to see that nbd_opt_read_name(... ), which
is the only use of namelen between declaration and use, does not always
initialize namelen; but fails to see we also exit this function early in
the same conditions when nbd_opt_read_name left namelen uninit.  The
workaround is fine.

Reviewed-by: Eric Blake 

I'm happy for this to go in through the trivial tree, but I'll also
queue it on my NBD tree if that is ready first.


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



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] linux-user: correct errno returned from accept4() syscall

2020-09-30 Thread Laurent Vivier
Le 30/09/2020 à 17:16, Matus Kysel a écrit :
> accept4() returned wrong errno, that did not match current linux
> 
> Signed-off-by: Matus Kysel 
> ---
>  linux-user/syscall.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 897d20c076..5b8c20cf21 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3491,16 +3491,16 @@ static abi_long do_accept4(int fd, abi_ulong 
> target_addr,
>  return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
>  }
>  
> -/* linux returns EINVAL if addrlen pointer is invalid */
> +/* linux returns EFAULT if addrlen pointer is invalid */
>  if (get_user_u32(addrlen, target_addrlen_addr))
> -return -TARGET_EINVAL;
> +return -TARGET_EFAULT;
>  
>  if ((int)addrlen < 0) {
>  return -TARGET_EINVAL;
>  }
>  
>  if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
> -return -TARGET_EINVAL;
> +return -TARGET_EFAULT;
>  
>  addr = alloca(addrlen);
>  
> 

Reviewed-by: Laurent Vivier 



Re: [PATCH v3 10/11] target/i386: Restrict X86CPUFeatureWord to X86 targets

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 06:49:48PM +0200, Philippe Mathieu-Daudé wrote:
> Only qemu-system-FOO and qemu-storage-daemon provide QMP
> monitors, therefore such declarations and definitions are
> irrelevant for user-mode emulation.
> 
> Restricting the x86-specific commands to machine-target.json
> pulls less QAPI-generated code into user-mode.
> 
> Add a stub to satisfy linking in user-mode:
> 
>   /usr/bin/ld: libqemu-i386-linux-user.fa.p/target_i386_cpu.c.o: in function 
> `x86_cpu_get_feature_words':
>   target/i386/cpu.c:4643: undefined reference to 
> `visit_type_X86CPUFeatureWordInfoList'
>   collect2: error: ld returned 1 exit status
>   make: *** [Makefile.ninja:1125: qemu-i386] Error 1
> 

If you don't want the QAPI definitions in user mode, there's no
reason to register the properties in user mode.  Wrapping #ifdef
around "feature-words" and "filtered-features" registration would
be simpler than adding a stub.

> Acked-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> v3: Reworded + Meson rebase
> ---
>  qapi/machine-target.json   | 45 ++
>  qapi/machine.json  | 42 ---
>  target/i386/cpu.c  |  2 +-
>  target/i386/feature-stub.c | 23 +++
>  target/i386/meson.build|  1 +
>  5 files changed, 70 insertions(+), 43 deletions(-)
>  create mode 100644 target/i386/feature-stub.c
> 
> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index 698850cc78..b4d769a53b 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -4,6 +4,51 @@
>  # This work is licensed under the terms of the GNU GPL, version 2 or later.
>  # See the COPYING file in the top-level directory.
>  
> +##
> +# @X86CPURegister32:
> +#
> +# A X86 32-bit register
> +#
> +# Since: 1.5
> +##
> +{ 'enum': 'X86CPURegister32',
> +  'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ],
> +  'if': 'defined(TARGET_I386)' }
> +
> +##
> +# @X86CPUFeatureWordInfo:
> +#
> +# Information about a X86 CPU feature word
> +#
> +# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature 
> word
> +#
> +# @cpuid-input-ecx: Input ECX value for CPUID instruction for that
> +#   feature word
> +#
> +# @cpuid-register: Output register containing the feature bits
> +#
> +# @features: value of output register, containing the feature bits
> +#
> +# Since: 1.5
> +##
> +{ 'struct': 'X86CPUFeatureWordInfo',
> +  'data': { 'cpuid-input-eax': 'int',
> +'*cpuid-input-ecx': 'int',
> +'cpuid-register': 'X86CPURegister32',
> +'features': 'int' },
> +  'if': 'defined(TARGET_I386)' }
> +
> +##
> +# @DummyForceArrays:
> +#
> +# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally
> +#
> +# Since: 2.5
> +##
> +{ 'struct': 'DummyForceArrays',
> +  'data': { 'unused': ['X86CPUFeatureWordInfo'] },
> +  'if': 'defined(TARGET_I386)' }
> +
>  ##
>  # @CpuModelInfo:
>  #
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 72f014bb5b..cb878acdac 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -544,48 +544,6 @@
> 'dst': 'uint16',
> 'val': 'uint8' }}
>  
> -##
> -# @X86CPURegister32:
> -#
> -# A X86 32-bit register
> -#
> -# Since: 1.5
> -##
> -{ 'enum': 'X86CPURegister32',
> -  'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
> -
> -##
> -# @X86CPUFeatureWordInfo:
> -#
> -# Information about a X86 CPU feature word
> -#
> -# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature 
> word
> -#
> -# @cpuid-input-ecx: Input ECX value for CPUID instruction for that
> -#   feature word
> -#
> -# @cpuid-register: Output register containing the feature bits
> -#
> -# @features: value of output register, containing the feature bits
> -#
> -# Since: 1.5
> -##
> -{ 'struct': 'X86CPUFeatureWordInfo',
> -  'data': { 'cpuid-input-eax': 'int',
> -'*cpuid-input-ecx': 'int',
> -'cpuid-register': 'X86CPURegister32',
> -'features': 'int' } }
> -
> -##
> -# @DummyForceArrays:
> -#
> -# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally
> -#
> -# Since: 2.5
> -##
> -{ 'struct': 'DummyForceArrays',
> -  'data': { 'unused': ['X86CPUFeatureWordInfo'] } }
> -
>  ##
>  # @NumaCpuOptions:
>  #
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 3ffd877dd5..d45fa217cc 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -38,7 +38,7 @@
>  #include "qemu/option.h"
>  #include "qemu/config-file.h"
>  #include "qapi/error.h"
> -#include "qapi/qapi-visit-machine.h"
> +#include "qapi/qapi-visit-machine-target.h"
>  #include "qapi/qapi-visit-run-state.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qerror.h"
> diff --git a/target/i386/feature-stub.c b/target/i386/feature-stub.c
> new file mode 100644
> index 00..787c3c7fa1
> --- /dev/null
> +++ b/target/i386/feature-stub.c
> @@ -0,0 

Re: [PATCH v3 00/11] user-mode: Prune build dependencies (part 3)

2020-09-30 Thread Eduardo Habkost
On Wed, Sep 30, 2020 at 06:49:38PM +0200, Philippe Mathieu-Daudé wrote:
> This is the third part of a series reducing user-mode
> dependencies. By stripping out unused code, the build
> and testing time is reduced (as is space used by objects).

I'm queueing patches 2-9 on machine-next.  Thanks!

Markus, Eric: I can merge the QAPI patches (1, 11) if I get an
Acked-by.

I'll send separate comments on patch 10.

> 
> Part 3:
> - Extract code not related to user-mode from hw/core/qdev-properties.c
> - Reduce user-mode QAPI generated files
> 
> Since v2:
> - Fixed UuidInfo placed in incorrect json
> - Rebased on Meson
> - Include X86CPUFeatureWord unmerged from part 2
> 
> Since v1:
> - Addressed Richard and Paolo review comments
> 
> Patches missing review: QAPI ones :)
> - #1  'qapi: Restrict query-uuid command to block code'
> - #11 'qapi: Restrict code generated for user-mode'
> 
> Green CI: https://gitlab.com/philmd/qemu/-/pipelines/196505787
> 
> v2: https://www.mail-archive.com/qemu-devel@nongnu.org/msg688879.html
> v1: https://www.mail-archive.com/qemu-devel@nongnu.org/msg688486.html
> 
> Philippe Mathieu-Daudé (11):
>   qapi: Restrict query-uuid command to block code
>   hw/core/qdev-properties: Use qemu_strtol() in set_mac() handler
>   hw/core/qdev-properties: Use qemu_strtoul() in set_pci_host_devaddr()
>   hw/core/qdev-properties: Fix code style
>   hw/core/qdev-properties: Export enum-related functions
>   hw/core/qdev-properties: Export qdev_prop_enum
>   hw/core/qdev-properties: Export some integer-related functions
>   hw/core/qdev-properties: Extract system-mode specific properties
>   hw/core: Add qdev stub for user-mode
>   target/i386: Restrict X86CPUFeatureWord to X86 targets
>   qapi: Restrict code generated for user-mode
> 
>  qapi/block.json  |  30 ++
>  qapi/machine-target.json |  45 ++
>  qapi/machine.json|  72 ---
>  hw/core/qdev-prop-internal.h |  30 ++
>  include/hw/qdev-properties.h |   1 +
>  block/iscsi.c|   2 +-
>  hw/core/qdev-properties-system.c | 687 -
>  hw/core/qdev-properties.c| 735 ++-
>  stubs/qdev-system.c  |  24 +
>  stubs/uuid.c |   2 +-
>  target/i386/cpu.c|   2 +-
>  target/i386/feature-stub.c   |  23 +
>  qapi/meson.build |  51 ++-
>  stubs/meson.build|   5 +-
>  target/i386/meson.build  |   1 +
>  15 files changed, 915 insertions(+), 795 deletions(-)
>  create mode 100644 hw/core/qdev-prop-internal.h
>  create mode 100644 stubs/qdev-system.c
>  create mode 100644 target/i386/feature-stub.c
> 
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PATCH v1 1/1] riscv: Convert interrupt logs to use qemu_log_mask()

2020-09-30 Thread Alistair Francis
On Sun, Sep 27, 2020 at 9:22 AM Philippe Mathieu-Daudé  wrote:
>
> On 9/27/20 3:47 PM, Alistair Francis wrote:
> > Currently we log interrupts and exceptions using the trace backed in
>
> s/backed/backend/
>
> > riscv_cpu_do_interrupt(). We also log execptions using the interrupt log
>
> Typo "exceptions".
>
> > mask (-d int) in riscv_raise_exception().
> >
> > This PR converts riscv_cpu_do_interrupt() to log both interrupts and
>
> s/PR/patch/

Fixed!

>
> > exceptions with the interrupt log mask, so that both are printed when a
> > user runs QEMU with -d int.
> >
> > Signed-off-by: Alistair Francis 
> > ---
> >  target/riscv/cpu_helper.c | 7 +--
> >  target/riscv/op_helper.c  | 1 -
> >  target/riscv/trace-events | 3 ---
> >  3 files changed, 5 insertions(+), 6 deletions(-)
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 904899054d..9df3238213 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -894,8 +894,11 @@ void riscv_cpu_do_interrupt(CPUState *cs)
> >  }
> >  }
> >
> > -trace_riscv_trap(env->mhartid, async, cause, env->pc, tval,
> > -riscv_cpu_get_trap_name(cause, async));
> > +qemu_log_mask(CPU_LOG_INT,
> > +  "%s: hart:"TARGET_FMT_ld", async:%d, 
> > cause:"TARGET_FMT_lx", "
> > +  "epc:0x"TARGET_FMT_lx", tval:0x"TARGET_FMT_lx", 
> > desc=%s\n",
> > +  __func__, env->mhartid, async, cause, env->pc, tval,
> > +  riscv_cpu_get_trap_name(cause, async));
>
> Maybe you want to keep the trace event, as the trace framework allow you
> to select traced events at runtime, events come with timestamp and for
> some backends the events are machine-parsable.

Good point, I have kept this in.

>
> Regardless:
> Reviewed-by: Philippe Mathieu-Daudé 

Thanks!

Alistair

>
> >
> >  if (env->priv <= PRV_S &&
> >  cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
> > diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> > index 9b9ada45a9..e987bd262f 100644
> > --- a/target/riscv/op_helper.c
> > +++ b/target/riscv/op_helper.c
> > @@ -29,7 +29,6 @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState 
> > *env,
> >uint32_t exception, uintptr_t pc)
> >  {
> >  CPUState *cs = env_cpu(env);
> > -qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
> >  cs->exception_index = exception;
> >  cpu_loop_exit_restore(cs, pc);
> >  }
> > diff --git a/target/riscv/trace-events b/target/riscv/trace-events
> > index b7e371ee97..6be2147c8f 100644
> > --- a/target/riscv/trace-events
> > +++ b/target/riscv/trace-events
> > @@ -1,6 +1,3 @@
> > -# cpu_helper.c
> > -riscv_trap(uint64_t hartid, bool async, uint64_t cause, uint64_t epc, 
> > uint64_t tval, const char *desc) "hart:%"PRId64", async:%d, 
> > cause:%"PRId64", epc:0x%"PRIx64", tval:0x%"PRIx64", desc=%s"
> > -
> >  # pmp.c
> >  pmpcfg_csr_read(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart 
> > %" PRIu64 ": read reg%" PRIu32", val: 0x%" PRIx64
> >  pmpcfg_csr_write(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart 
> > %" PRIu64 ": write reg%" PRIu32", val: 0x%" PRIx64
> >
>



[PATCH v3 07/11] hw/core/qdev-properties: Export some integer-related functions

2020-09-30 Thread Philippe Mathieu-Daudé
We are going to split this file and reuse these static functions.
Declare them in the local "qdev-prop-internal.h" header.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
v3:
Also export qdev_propinfo_get_size32 introduced in commits
914e74cda9 ("qdev-properties: add size32 property type") and
031ffd9a61 ("qdev-properties: add getter for size32 and blocksize").
---
 hw/core/qdev-prop-internal.h | 11 +
 hw/core/qdev-properties.c| 46 +++-
 2 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index 2a8c9a306a..9cf5cc1d51 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -15,5 +15,16 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const 
char *name,
 
 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
   const Property *prop);
+void qdev_propinfo_set_default_value_int(ObjectProperty *op,
+ const Property *prop);
+void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
+  const Property *prop);
+
+void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp);
+void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp);
+void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp);
 
 #endif
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 31dfe441e2..37e309077a 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -271,12 +271,14 @@ static void set_uint8(Object *obj, Visitor *v, const char 
*name, void *opaque,
 visit_type_uint8(v, name, ptr, errp);
 }
 
-static void set_default_value_int(ObjectProperty *op, const Property *prop)
+void qdev_propinfo_set_default_value_int(ObjectProperty *op,
+ const Property *prop)
 {
 object_property_set_default_int(op, prop->defval.i);
 }
 
-static void set_default_value_uint(ObjectProperty *op, const Property *prop)
+void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
+  const Property *prop)
 {
 object_property_set_default_uint(op, prop->defval.u);
 }
@@ -285,13 +287,13 @@ const PropertyInfo qdev_prop_uint8 = {
 .name  = "uint8",
 .get   = get_uint8,
 .set   = set_uint8,
-.set_default_value = set_default_value_uint,
+.set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 /* --- 16bit integer --- */
 
-static void get_uint16(Object *obj, Visitor *v, const char *name,
-   void *opaque, Error **errp)
+void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
@@ -317,9 +319,9 @@ static void set_uint16(Object *obj, Visitor *v, const char 
*name,
 
 const PropertyInfo qdev_prop_uint16 = {
 .name  = "uint16",
-.get   = get_uint16,
+.get   = qdev_propinfo_get_uint16,
 .set   = set_uint16,
-.set_default_value = set_default_value_uint,
+.set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 /* --- 32bit integer --- */
@@ -349,8 +351,8 @@ static void set_uint32(Object *obj, Visitor *v, const char 
*name,
 visit_type_uint32(v, name, ptr, errp);
 }
 
-static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
-  Error **errp)
+void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
@@ -378,14 +380,14 @@ const PropertyInfo qdev_prop_uint32 = {
 .name  = "uint32",
 .get   = get_uint32,
 .set   = set_uint32,
-.set_default_value = set_default_value_uint,
+.set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int32 = {
 .name  = "int32",
-.get   = get_int32,
+.get   = qdev_propinfo_get_int32,
 .set   = set_int32,
-.set_default_value = set_default_value_int,
+.set_default_value = qdev_propinfo_set_default_value_int,
 };
 
 /* --- 64bit integer --- */
@@ -444,14 +446,14 @@ const PropertyInfo qdev_prop_uint64 = {
 .name  = "uint64",
 .get   = get_uint64,
 .set   = set_uint64,
-.set_default_value = set_default_value_uint,
+.set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int64 = {
 .name  = "int64",
 .get   = get_int64,
 .set   = set_int64,
-.set_default_value = set_default_value_int,
+.set_default_value = qdev_propinfo_set_default_value_int,
 };
 
 /* 

[PATCH v3 05/11] hw/core/qdev-properties: Export enum-related functions

2020-09-30 Thread Philippe Mathieu-Daudé
We are going to split this file and reuse these static functions.
Add the local "qdev-prop-internal.h" header declaring them.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev-prop-internal.h | 19 
 hw/core/qdev-properties.c| 58 +++-
 2 files changed, 49 insertions(+), 28 deletions(-)
 create mode 100644 hw/core/qdev-prop-internal.h

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
new file mode 100644
index 00..2a8c9a306a
--- /dev/null
+++ b/hw/core/qdev-prop-internal.h
@@ -0,0 +1,19 @@
+/*
+ * qdev property parsing
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_CORE_QDEV_PROP_INTERNAL_H
+#define HW_CORE_QDEV_PROP_INTERNAL_H
+
+void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp);
+void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp);
+
+void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
+  const Property *prop);
+
+#endif
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 071fd5864a..76417d0936 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -18,6 +18,7 @@
 #include "qemu/uuid.h"
 #include "qemu/units.h"
 #include "qemu/cutils.h"
+#include "qdev-prop-internal.h"
 
 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
   Error **errp)
@@ -53,8 +54,8 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 return ptr;
 }
 
-static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
+void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
@@ -63,8 +64,8 @@ static void get_enum(Object *obj, Visitor *v, const char 
*name, void *opaque,
 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
 }
 
-static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
+void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
@@ -78,7 +79,8 @@ static void set_enum(Object *obj, Visitor *v, const char 
*name, void *opaque,
 visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
 }
 
-static void set_default_value_enum(ObjectProperty *op, const Property *prop)
+void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
+  const Property *prop)
 {
 object_property_set_default_str(op,
 qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
@@ -669,9 +671,9 @@ const PropertyInfo qdev_prop_on_off_auto = {
 .name = "OnOffAuto",
 .description = "on/off/auto",
 .enum_table = _lookup,
-.get = get_enum,
-.set = set_enum,
-.set_default_value = set_default_value_enum,
+.get = qdev_propinfo_get_enum,
+.set = qdev_propinfo_set_enum,
+.set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 /* --- lost tick policy --- */
@@ -681,9 +683,9 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 const PropertyInfo qdev_prop_losttickpolicy = {
 .name  = "LostTickPolicy",
 .enum_table  = _lookup,
-.get   = get_enum,
-.set   = set_enum,
-.set_default_value = set_default_value_enum,
+.get   = qdev_propinfo_get_enum,
+.set   = qdev_propinfo_set_enum,
+.set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 /* --- Block device error handling policy --- */
@@ -695,9 +697,9 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
 .description = "Error handling policy, "
"report/ignore/enospc/stop/auto",
 .enum_table = _lookup,
-.get = get_enum,
-.set = set_enum,
-.set_default_value = set_default_value_enum,
+.get = qdev_propinfo_get_enum,
+.set = qdev_propinfo_set_enum,
+.set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 /* --- BIOS CHS translation */
@@ -709,9 +711,9 @@ const PropertyInfo qdev_prop_bios_chs_trans = {
 .description = "Logical CHS translation algorithm, "
"auto/none/lba/large/rechs",
 .enum_table = _lookup,
-.get = get_enum,
-.set = set_enum,
-.set_default_value = set_default_value_enum,
+.get = qdev_propinfo_get_enum,
+.set = qdev_propinfo_set_enum,
+.set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 /* --- FDC default drive types */
@@ -721,9 +723,9 @@ const PropertyInfo qdev_prop_fdc_drive_type = {
 

[PATCH v3 02/11] hw/core/qdev-properties: Use qemu_strtol() in set_mac() handler

2020-09-30 Thread Philippe Mathieu-Daudé
The MACAddr structure contains an array of uint8_t. Previously
if a value was out of the [0..255] range, it was silently casted
and no input validation was done.
Replace strtol() by qemu_strtol() -- so checkpatch.pl won't
complain if we move this code later -- and return EINVAL if the
input is invalid.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev-properties.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 343c824da0..080ba319a1 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "net/net.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -524,7 +525,8 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 Property *prop = opaque;
 MACAddr *mac = qdev_get_prop_ptr(dev, prop);
 int i, pos;
-char *str, *p;
+char *str;
+const char *p;
 
 if (dev->realized) {
 qdev_prop_set_after_realize(dev, name, errp);
@@ -536,6 +538,8 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 }
 
 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
+long val;
+
 if (!qemu_isxdigit(str[pos])) {
 goto inval;
 }
@@ -551,7 +555,10 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 goto inval;
 }
 }
-mac->a[i] = strtol(str+pos, , 16);
+if (qemu_strtol(str + pos, , 16, ) < 0 || val > 0xff) {
+goto inval;
+}
+mac->a[i] = val;
 }
 g_free(str);
 return;
-- 
2.26.2




[PATCH v3 04/11] hw/core/qdev-properties: Fix code style

2020-09-30 Thread Philippe Mathieu-Daudé
We will soon move this code, fix its style to avoid checkpatch.pl
to complain.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/core/qdev-properties.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index a1190a5db9..071fd5864a 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -543,15 +543,15 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 if (!qemu_isxdigit(str[pos])) {
 goto inval;
 }
-if (!qemu_isxdigit(str[pos+1])) {
+if (!qemu_isxdigit(str[pos + 1])) {
 goto inval;
 }
 if (i == 5) {
-if (str[pos+2] != '\0') {
+if (str[pos + 2] != '\0') {
 goto inval;
 }
 } else {
-if (str[pos+2] != ':' && str[pos+2] != '-') {
+if (str[pos + 2] != ':' && str[pos + 2] != '-') {
 goto inval;
 }
 }
@@ -898,8 +898,8 @@ static void set_blocksize(Object *obj, Visitor *v, const 
char *name,
 /* We rely on power-of-2 blocksizes for bitmasks */
 if ((value & (value - 1)) != 0) {
 error_setg(errp,
-  "Property %s.%s doesn't take value '%" PRId64 "', it's not a 
power of 2",
-  dev->id ?: "", name, (int64_t)value);
+  "Property %s.%s doesn't take value '%" PRId64 "', "
+  "it's not a power of 2", dev->id ?: "", name, 
(int64_t)value);
 return;
 }
 
-- 
2.26.2




[PATCH v3 09/11] hw/core: Add qdev stub for user-mode

2020-09-30 Thread Philippe Mathieu-Daudé
While user-mode does not use peripherals (devices), it uses a
CPU which is a device.
In the next commit we will reduce the QAPI generated code for
user-mode. Since qdev.c calls qapi_event_send_device_deleted()
in device_finalize, let's add a stub for it.

Suggested-by: Paolo Bonzini 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Meson rebase
---
 stubs/qdev-system.c | 24 
 stubs/meson.build   |  1 +
 2 files changed, 25 insertions(+)
 create mode 100644 stubs/qdev-system.c

diff --git a/stubs/qdev-system.c b/stubs/qdev-system.c
new file mode 100644
index 00..2b4b54f621
--- /dev/null
+++ b/stubs/qdev-system.c
@@ -0,0 +1,24 @@
+/*
+ * QAPI qdev stubs
+ *
+ * Copyright (c) 2020 Red Hat, Inc.
+ *
+ * Author:
+ *   Philippe Mathieu-Daudé 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qapi-events-qdev.h"
+
+void qapi_event_send_device_deleted(bool has_device,
+const char *device, const char *path)
+{
+/*
+ * Called in user-mode in fork() when a CPUState is qdev::finalize()'d.
+ * Simply ignore the QAPI event there.
+ */
+}
diff --git a/stubs/meson.build b/stubs/meson.build
index 2e231590e1..71d42c34d6 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -25,6 +25,7 @@ stub_ss.add(files('monitor.c'))
 stub_ss.add(files('monitor-core.c'))
 stub_ss.add(files('pci-bus.c'))
 stub_ss.add(files('pci-host-piix.c'))
+stub_ss.add(files('qdev-system.c'))
 stub_ss.add(files('qemu-timer-notify-cb.c'))
 stub_ss.add(files('qmp_memory_device.c'))
 stub_ss.add(files('qtest.c'))
-- 
2.26.2




  1   2   3   4   >