Re: [Qemu-devel] Cross-posted : Odd QXL/KVM performance issue with a Windows 7 Guest

2019-09-06 Thread Brad Campbell



On 7/9/19 03:03, Dr. David Alan Gilbert wrote:

* Brad Campbell (lists2...@fnarfbargle.com) wrote:

On 2/9/19 6:23 pm, Brad Campbell wrote:


Here is the holdup :

11725@1567416625.003504:qxl_ring_command_check 0 native
11725@1567416625.102653:qxl_io_write 0 native addr=0 (QXL_IO_NOTIFY_CMD)
val=0 size=1 async=0

~100ms delay prior to each logged QXL_IO_NOTIFY_CMD on the AMD box which
explains the performance difference. Now I just need to figure out if
that lies in the guest, the guest QXL driver, QEMU or SPICE and why it
exhibits on the AMD box and not the i7.

To get to this point, I recompiled the kernel on the i7 box with both
AMD and Intel KVM modules. Once that was running I cloned the drive and
put it in the AMD box, so the OS, software stack and all dependencies
are identical.

Reacp :

I have a machine with a Windows 7 VM which is running on an i7-3770. This
works perfectly.

Clone the disk and put it in a new(ish) AMD Ryzen 1500x machine and the
display output using qxl/spice is now limited to ~5-7fps.

I originally cloned the entire machine to keep the software versions
identical.

To simplify debugging and reproduction I'm now using :
- An identical SPICE version to that on the i7.
- A fresh 64 bit Windows 7 VM.
- The D2D benchmark from Crystalmark 2004R7.

The machine is booted with :

qemu -enable-kvm \
  -m 8192\
  -rtc base=localtime\
  -vga qxl\
  -device qxl\
  -global qxl-vga.guestdebug=3\
  -global qxl-vga.cmdlog=1\
  -global qxl-vga.vram_size=65536\
  -global qxl.vram_size=65536\
  -global qxl-vga.ram_size=65536\
  -global qxl.ram_size=65536\
  -net nic,model=virtio\
  -net tap,ifname=tap0,script=/etc/qemu-ifup,vhost=on\
  -usbdevice tablet\
  -spice port=5930,disable-ticketing\
  -device virtio-serial\
  -chardev spicevmc,id=vdagent,name=vdagent\
  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0\
  -smp 3,maxcpus=3,cores=3,threads=1,sockets=1\
  -cpu qemu64,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \

-cpu qemu64 is almost always a bad idea;  does -cpu host help ?

Dave



No. I was using -cpu host. I changed it to qemu64 for testing so I could add & 
remove -enable-kvm for testing without the machine changing drivers about.

Regards,

Brad

--
An expert is a person who has found out by his own painful
experience all the mistakes that one can make in a very
narrow field. - Niels Bohr




[Qemu-devel] [PATCH v3 2/5] s390: PCI: Creation a header dedicated to PCI CLP

2019-09-06 Thread Matthew Rosato
From: Pierre Morel 

To have a clean separation between s390-pci-bus.h
and s390-pci-inst.h headers we export the PCI CLP
instructions in a dedicated header.

Signed-off-by: Pierre Morel 
Reviewed-by: Collin Walling 
---
 hw/s390x/s390-pci-bus.h  |   1 +
 hw/s390x/s390-pci-clp.h  | 211 +++
 hw/s390x/s390-pci-inst.h | 196 ---
 3 files changed, 212 insertions(+), 196 deletions(-)
 create mode 100644 hw/s390x/s390-pci-clp.h

diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 550f3cc..a5d2049 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -19,6 +19,7 @@
 #include "hw/s390x/sclp.h"
 #include "hw/s390x/s390_flic.h"
 #include "hw/s390x/css.h"
+#include "s390-pci-clp.h"
 
 #define TYPE_S390_PCI_HOST_BRIDGE "s390-pcihost"
 #define TYPE_S390_PCI_BUS "s390-pcibus"
diff --git a/hw/s390x/s390-pci-clp.h b/hw/s390x/s390-pci-clp.h
new file mode 100644
index 000..e442307
--- /dev/null
+++ b/hw/s390x/s390-pci-clp.h
@@ -0,0 +1,211 @@
+/*
+ * s390 CLPinstruction definitions
+ *
+ * Copyright 2019 IBM Corp.
+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef HW_S390_PCI_CLP
+#define HW_S390_PCI_CLP
+
+/* CLP common request & response block size */
+#define CLP_BLK_SIZE 4096
+#define PCI_BAR_COUNT 6
+#define PCI_MAX_FUNCTIONS 4096
+
+typedef struct ClpReqHdr {
+uint16_t len;
+uint16_t cmd;
+} QEMU_PACKED ClpReqHdr;
+
+typedef struct ClpRspHdr {
+uint16_t len;
+uint16_t rsp;
+} QEMU_PACKED ClpRspHdr;
+
+/* CLP Response Codes */
+#define CLP_RC_OK 0x0010  /* Command request successfully */
+#define CLP_RC_CMD0x0020  /* Command code not recognized */
+#define CLP_RC_PERM   0x0030  /* Command not authorized */
+#define CLP_RC_FMT0x0040  /* Invalid command request format */
+#define CLP_RC_LEN0x0050  /* Invalid command request length */
+#define CLP_RC_8K 0x0060  /* Command requires 8K LPCB */
+#define CLP_RC_RESNOT00x0070  /* Reserved field not zero */
+#define CLP_RC_NODATA 0x0080  /* No data available */
+#define CLP_RC_FC_UNKNOWN 0x0100  /* Function code not recognized */
+
+/*
+ * Call Logical Processor - Command Codes
+ */
+#define CLP_LIST_PCI0x0002
+#define CLP_QUERY_PCI_FN0x0003
+#define CLP_QUERY_PCI_FNGRP 0x0004
+#define CLP_SET_PCI_FN  0x0005
+
+/* PCI function handle list entry */
+typedef struct ClpFhListEntry {
+uint16_t device_id;
+uint16_t vendor_id;
+#define CLP_FHLIST_MASK_CONFIG 0x8000
+uint32_t config;
+uint32_t fid;
+uint32_t fh;
+} QEMU_PACKED ClpFhListEntry;
+
+#define CLP_RC_SETPCIFN_FH  0x0101 /* Invalid PCI fn handle */
+#define CLP_RC_SETPCIFN_FHOP0x0102 /* Fn handle not valid for op */
+#define CLP_RC_SETPCIFN_DMAAS   0x0103 /* Invalid DMA addr space */
+#define CLP_RC_SETPCIFN_RES 0x0104 /* Insufficient resources */
+#define CLP_RC_SETPCIFN_ALRDY   0x0105 /* Fn already in requested state */
+#define CLP_RC_SETPCIFN_ERR 0x0106 /* Fn in permanent error state */
+#define CLP_RC_SETPCIFN_RECPND  0x0107 /* Error recovery pending */
+#define CLP_RC_SETPCIFN_BUSY0x0108 /* Fn busy */
+#define CLP_RC_LISTPCI_BADRT0x010a /* Resume token not recognized */
+#define CLP_RC_QUERYPCIFG_PFGID 0x010b /* Unrecognized PFGID */
+
+/* request or response block header length */
+#define LIST_PCI_HDR_LEN 32
+
+/* Number of function handles fitting in response block */
+#define CLP_FH_LIST_NR_ENTRIES \
+((CLP_BLK_SIZE - 2 * LIST_PCI_HDR_LEN) \
+/ sizeof(ClpFhListEntry))
+
+#define CLP_SET_ENABLE_PCI_FN  0 /* Yes, 0 enables it */
+#define CLP_SET_DISABLE_PCI_FN 1 /* Yes, 1 disables it */
+
+#define CLP_UTIL_STR_LEN 64
+
+#define CLP_MASK_FMT 0xf000
+
+/* List PCI functions request */
+typedef struct ClpReqListPci {
+ClpReqHdr hdr;
+uint32_t fmt;
+uint64_t reserved1;
+uint64_t resume_token;
+uint64_t reserved2;
+} QEMU_PACKED ClpReqListPci;
+
+/* List PCI functions response */
+typedef struct ClpRspListPci {
+ClpRspHdr hdr;
+uint32_t fmt;
+uint64_t reserved1;
+uint64_t resume_token;
+uint32_t mdd;
+uint16_t max_fn;
+uint8_t flags;
+uint8_t entry_size;
+ClpFhListEntry fh_list[CLP_FH_LIST_NR_ENTRIES];
+} QEMU_PACKED ClpRspListPci;
+
+/* Query PCI function request */
+typedef struct ClpReqQueryPci {
+ClpReqHdr hdr;
+uint32_t fmt;
+uint64_t reserved1;
+uint32_t fh; /* function handle */
+uint32_t reserved2;
+uint64_t reserved3;
+} QEMU_PACKED ClpReqQueryPci;
+
+/* Query PCI function response */
+typedef struct ClpRspQueryPci {
+ClpRspHdr hdr;
+uint32_t fmt;
+uint64_t reserved1;
+uint16_t vfn; /* virtual fn number */
+#define CLP_RSP_QPCI_MASK_UTIL  0x100
+#define CLP_RSP_QPCI_MASK_PFGID 0xff
+ 

[Qemu-devel] [PATCH v3 5/5] s390: vfio_pci: Get zPCI function info from host

2019-09-06 Thread Matthew Rosato
From: Pierre Morel 

We use the VFIO_REGION_SUBTYPE_ZDEV_CLP subregion of
PCI_VENDOR_ID_IBM to retrieve the CLP information the
kernel exports.

To be compatible with previous kernel versions we fall back
on previous predefined values, same as the emulation values,
when the region is not found or when any problem happens
during the search for the information.

Once we retrieved the host device information, we take care to
- use the virtual UID and FID
- Disable all the IOMMU flags we do not support yet.
  Just keeping the refresh bit.

Signed-off-by: Pierre Morel 
Signed-off-by: Matthew Rosato 
---
 hw/s390x/s390-pci-bus.c | 83 +++--
 hw/s390x/s390-pci-bus.h |  2 ++
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 0d404c3..5069795 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -15,6 +15,8 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "cpu.h"
+#include "s390-pci-clp.h"
+#include 
 #include "s390-pci-bus.h"
 #include "s390-pci-inst.h"
 #include "hw/pci/pci_bus.h"
@@ -24,6 +26,9 @@
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 
+#include "hw/vfio/pci.h"
+#include 
+
 #ifndef DEBUG_S390PCI_BUS
 #define DEBUG_S390PCI_BUS  0
 #endif
@@ -781,6 +786,76 @@ static void set_pbdev_info(S390PCIBusDevice *pbdev)
 pbdev->pci_grp = s390_grp_find(ZPCI_DEFAULT_FN_GRP);
 }
 
+static int get_pbdev_info(S390PCIBusDevice *pbdev)
+{
+VFIOPCIDevice *vfio_pci;
+VFIODevice *vdev;
+struct vfio_region_info *info;
+CLPRegion *clp_region;
+int size;
+int ret;
+
+vfio_pci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
+vdev = _pci->vbasedev;
+
+if (vdev->num_regions < VFIO_PCI_NUM_REGIONS + 1) {
+/* Fall back to old handling */
+return -ENODEV;
+}
+
+ret = vfio_get_dev_region_info(vdev,
+   PCI_VENDOR_ID_IBM |
+   VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+   VFIO_REGION_SUBTYPE_ZDEV_CLP, );
+if (ret) {
+/* Fall back to old handling */
+return -EIO;
+}
+
+if (info->size != (sizeof(CLPRegion) + CLP_UTIL_STR_LEN)) {
+/* Fall back to old handling */
+g_free(info);
+return -ENOMEM;
+}
+clp_region = g_malloc0(sizeof(*clp_region) + CLP_UTIL_STR_LEN);
+size = pread(vdev->fd, clp_region, (sizeof(*clp_region) + 
CLP_UTIL_STR_LEN),
+ info->offset);
+if (size != (sizeof(*clp_region) + CLP_UTIL_STR_LEN)) {
+goto end;
+}
+
+pbdev->zpci_fn.fid = pbdev->fid;
+pbdev->zpci_fn.uid = pbdev->uid;
+pbdev->zpci_fn.sdma = clp_region->start_dma;
+pbdev->zpci_fn.edma = clp_region->end_dma;
+pbdev->zpci_fn.pchid = clp_region->pchid;
+pbdev->zpci_fn.ug = clp_region->gid;
+pbdev->pci_grp = s390_grp_find(clp_region->gid);
+
+if (!pbdev->pci_grp) {
+ClpRspQueryPciGrp *resgrp;
+
+pbdev->pci_grp = s390_grp_create(clp_region->gid);
+
+resgrp = >pci_grp->zpci_grp;
+if (clp_region->flags & VFIO_PCI_ZDEV_FLAGS_REFRESH) {
+resgrp->fr = 1;
+}
+stq_p(>dasm, clp_region->dasm);
+stq_p(>msia, clp_region->msi_addr);
+stw_p(>mui, clp_region->mui);
+stw_p(>i, clp_region->noi);
+/* These two must be queried in a next iteration */
+stw_p(>maxstbl, 128);
+resgrp->version = 0;
+}
+
+end:
+g_free(info);
+g_free(clp_region);
+return ret;
+}
+
 static void s390_pcihost_realize(DeviceState *dev, Error **errp)
 {
 PCIBus *b;
@@ -853,7 +928,8 @@ static int s390_pci_msix_init(S390PCIBusDevice *pbdev)
 name = g_strdup_printf("msix-s390-%04x", pbdev->uid);
 memory_region_init_io(>msix_notify_mr, OBJECT(pbdev),
   _msi_ctrl_ops, pbdev, name, PAGE_SIZE);
-memory_region_add_subregion(>iommu->mr, ZPCI_MSI_ADDR,
+memory_region_add_subregion(>iommu->mr,
+pbdev->pci_grp->zpci_grp.msia,
 >msix_notify_mr);
 g_free(name);
 
@@ -1003,12 +1079,15 @@ static void s390_pcihost_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
 pbdev->iommu->pbdev = pbdev;
 pbdev->state = ZPCI_FS_DISABLED;
-set_pbdev_info(pbdev);
 
 if (object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
 pbdev->fh |= FH_SHM_VFIO;
+if (get_pbdev_info(pbdev) != 0) {
+set_pbdev_info(pbdev);
+}
 } else {
 pbdev->fh |= FH_SHM_EMUL;
+set_pbdev_info(pbdev);
 }
 
 if (s390_pci_msix_init(pbdev)) {
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 8c969d1..151e2d0 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -320,6 +320,8 @@ 

[Qemu-devel] [PATCH v3 4/5] s390: vfio_pci: Use a PCI Function structure

2019-09-06 Thread Matthew Rosato
From: Pierre Morel 

We use a ClpRspQueryPci structure to hold the information
related to zPCI Function.

This allows us to be ready to support different zPCI functions
and to retrieve the zPCI function information from the host.

Signed-off-by: Pierre Morel 
---
 hw/s390x/s390-pci-bus.c  | 22 +-
 hw/s390x/s390-pci-bus.h  |  1 +
 hw/s390x/s390-pci-inst.c |  8 ++--
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index e625217..0d404c3 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -770,6 +770,17 @@ static void s390_pci_init_default_group(void)
 resgrp->version = 0;
 }
 
+static void set_pbdev_info(S390PCIBusDevice *pbdev)
+{
+pbdev->zpci_fn.sdma = ZPCI_SDMA_ADDR;
+pbdev->zpci_fn.edma = ZPCI_EDMA_ADDR;
+pbdev->zpci_fn.pchid = 0;
+pbdev->zpci_fn.ug = ZPCI_DEFAULT_FN_GRP;
+pbdev->zpci_fn.fid = pbdev->fid;
+pbdev->zpci_fn.uid = pbdev->uid;
+pbdev->pci_grp = s390_grp_find(ZPCI_DEFAULT_FN_GRP);
+}
+
 static void s390_pcihost_realize(DeviceState *dev, Error **errp)
 {
 PCIBus *b;
@@ -988,17 +999,18 @@ static void s390_pcihost_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 }
 }
 
+pbdev->pdev = pdev;
+pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
+pbdev->iommu->pbdev = pbdev;
+pbdev->state = ZPCI_FS_DISABLED;
+set_pbdev_info(pbdev);
+
 if (object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
 pbdev->fh |= FH_SHM_VFIO;
 } else {
 pbdev->fh |= FH_SHM_EMUL;
 }
 
-pbdev->pdev = pdev;
-pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
-pbdev->iommu->pbdev = pbdev;
-pbdev->state = ZPCI_FS_DISABLED;
-
 if (s390_pci_msix_init(pbdev)) {
 error_setg(errp, "MSI-X support is mandatory "
"in the S390 architecture");
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index e95a797..8c969d1 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -337,6 +337,7 @@ struct S390PCIBusDevice {
 uint16_t noi;
 uint8_t sum;
 S390PCIGroup *pci_grp;
+ClpRspQueryPci zpci_fn;
 S390MsixInfo msix;
 AdapterRoutes routes;
 S390PCIIOMMU *iommu;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 00dd176..b02c360 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -267,6 +267,8 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
 goto out;
 }
 
+memcpy(resquery, >zpci_fn, sizeof(*resquery));
+
 for (i = 0; i < PCI_BAR_COUNT; i++) {
 uint32_t data = pci_get_long(pbdev->pdev->config +
 PCI_BASE_ADDRESS_0 + (i * 4));
@@ -280,12 +282,6 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t 
ra)
 resquery->bar_size[i]);
 }
 
-stq_p(>sdma, ZPCI_SDMA_ADDR);
-stq_p(>edma, ZPCI_EDMA_ADDR);
-stl_p(>fid, pbdev->fid);
-stw_p(>pchid, 0);
-stw_p(>ug, ZPCI_DEFAULT_FN_GRP);
-stl_p(>uid, pbdev->uid);
 stw_p(>hdr.rsp, CLP_RC_OK);
 break;
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 0/5] Retrieving zPCI specific info from QEMU

2019-09-06 Thread Matthew Rosato
Note: These patches by Pierre got lost in the ether a few months back
as he has been unavailable to carry them forward.  I've made changes
based upon comments received on the kernel part of his last version.

This patch implement the QEMU part to retrieve ZPCI specific
information from the host.
The Linux part has been posted on a separate patch on the LKML.

Subject: [PATCH v4 0/4] Retrieving zPCI specific info with VFIO
  
We use the PCI VFIO interface to retrieve ZPCI specific information
from the host with a ZPCI specific device region.
 
The retrieval is done only once per function and function group
during the plugging of the device.
The guest's requests are filled with shadow values we keep for
the duration of the device remains plugged.

Still there are some values we need to virtualize, like
the UID and FID of the zPCI function, and we currently
only allow the refresh bit for the zPCI group flags.

Note that we export the CLP specific definitions in a dedicated
file for clarity.

Changes since v2:
- update vfio_zdev.h to match kernel + fix packing attribute
- update vfio.h to match kernel changes

Pierre Morel (5):
  vfio: vfio_iommu_type1: linux header place holder
  s390: PCI: Creation a header dedicated to PCI CLP
  s390: vfio_pci: Use a PCI Group structure
  s390: vfio_pci: Use a PCI Function structure
  s390: vfio_pci: Get zPCI function info from host

 hw/s390x/s390-pci-bus.c | 145 +--
 hw/s390x/s390-pci-bus.h |  15 ++-
 hw/s390x/s390-pci-clp.h | 211 
 hw/s390x/s390-pci-inst.c|  28 +++---
 hw/s390x/s390-pci-inst.h| 196 -
 linux-headers/linux/vfio.h  |   7 +-
 linux-headers/linux/vfio_zdev.h |  35 +++
 7 files changed, 417 insertions(+), 220 deletions(-)
 create mode 100644 hw/s390x/s390-pci-clp.h
 create mode 100644 linux-headers/linux/vfio_zdev.h

-- 
1.8.3.1




[Qemu-devel] [PATCH v3 3/5] s390: vfio_pci: Use a PCI Group structure

2019-09-06 Thread Matthew Rosato
From: Pierre Morel 

We use a S390PCIGroup structure to hold the information
related to zPCI Function group.

This allows us to be ready to support multiple groups and to retrieve
the group information from the host.

Signed-off-by: Pierre Morel 
---
 hw/s390x/s390-pci-bus.c  | 42 ++
 hw/s390x/s390-pci-bus.h  | 11 ++-
 hw/s390x/s390-pci-inst.c | 22 +-
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 963a41c..e625217 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -730,6 +730,46 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus 
*bus, int32_t devfn)
 object_unref(OBJECT(iommu));
 }
 
+static S390PCIGroup *s390_grp_create(int ug)
+{
+S390PCIGroup *grp;
+S390pciState *s = s390_get_phb();
+
+grp = g_new0(S390PCIGroup, 1);
+grp->ug = ug;
+QTAILQ_INSERT_TAIL(>zpci_grps, grp, link);
+return grp;
+}
+
+S390PCIGroup *s390_grp_find(int ug)
+{
+S390PCIGroup *grp;
+S390pciState *s = s390_get_phb();
+
+QTAILQ_FOREACH(grp, >zpci_grps, link) {
+if ((grp->ug & CLP_REQ_QPCIG_MASK_PFGID) == ug) {
+return grp;
+}
+}
+return NULL;
+}
+
+static void s390_pci_init_default_group(void)
+{
+S390PCIGroup *grp;
+ClpRspQueryPciGrp *resgrp;
+
+grp = s390_grp_create(ZPCI_DEFAULT_FN_GRP);
+resgrp = >zpci_grp;
+resgrp->fr = 1;
+stq_p(>dasm, 0);
+stq_p(>msia, ZPCI_MSI_ADDR);
+stw_p(>mui, DEFAULT_MUI);
+stw_p(>i, 128);
+stw_p(>maxstbl, 128);
+resgrp->version = 0;
+}
+
 static void s390_pcihost_realize(DeviceState *dev, Error **errp)
 {
 PCIBus *b;
@@ -766,7 +806,9 @@ static void s390_pcihost_realize(DeviceState *dev, Error 
**errp)
 s->bus_no = 0;
 QTAILQ_INIT(>pending_sei);
 QTAILQ_INIT(>zpci_devs);
+QTAILQ_INIT(>zpci_grps);
 
+s390_pci_init_default_group();
 css_register_io_adapters(CSS_IO_ADAPTER_PCI, true, false,
  S390_ADAPTER_SUPPRESSIBLE, _err);
 error_propagate(errp, local_err);
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index a5d2049..e95a797 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -312,6 +312,14 @@ typedef struct ZpciFmb {
 } ZpciFmb;
 QEMU_BUILD_BUG_MSG(offsetof(ZpciFmb, fmt0) != 48, "padding in ZpciFmb");
 
+#define ZPCI_DEFAULT_FN_GRP 0x20
+typedef struct S390PCIGroup {
+ClpRspQueryPciGrp zpci_grp;
+int ug;
+QTAILQ_ENTRY(S390PCIGroup) link;
+} S390PCIGroup;
+S390PCIGroup *s390_grp_find(int ug);
+
 struct S390PCIBusDevice {
 DeviceState qdev;
 PCIDevice *pdev;
@@ -327,8 +335,8 @@ struct S390PCIBusDevice {
 QEMUTimer *fmb_timer;
 uint8_t isc;
 uint16_t noi;
-uint16_t maxstbl;
 uint8_t sum;
+S390PCIGroup *pci_grp;
 S390MsixInfo msix;
 AdapterRoutes routes;
 S390PCIIOMMU *iommu;
@@ -353,6 +361,7 @@ typedef struct S390pciState {
 GHashTable *zpci_table;
 QTAILQ_HEAD(, SeiContainer) pending_sei;
 QTAILQ_HEAD(, S390PCIBusDevice) zpci_devs;
+QTAILQ_HEAD(, S390PCIGroup) zpci_grps;
 } S390pciState;
 
 S390pciState *s390_get_phb(void);
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 4b3bd4a..00dd176 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -284,21 +284,25 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t 
ra)
 stq_p(>edma, ZPCI_EDMA_ADDR);
 stl_p(>fid, pbdev->fid);
 stw_p(>pchid, 0);
-stw_p(>ug, 1);
+stw_p(>ug, ZPCI_DEFAULT_FN_GRP);
 stl_p(>uid, pbdev->uid);
 stw_p(>hdr.rsp, CLP_RC_OK);
 break;
 }
 case CLP_QUERY_PCI_FNGRP: {
 ClpRspQueryPciGrp *resgrp = (ClpRspQueryPciGrp *)resh;
-resgrp->fr = 1;
-stq_p(>dasm, 0);
-stq_p(>msia, ZPCI_MSI_ADDR);
-stw_p(>mui, DEFAULT_MUI);
-stw_p(>i, 128);
-stw_p(>maxstbl, 128);
-resgrp->version = 0;
 
+ClpReqQueryPciGrp *reqgrp = (ClpReqQueryPciGrp *)reqh;
+S390PCIGroup *grp;
+
+grp = s390_grp_find(reqgrp->g);
+if (!grp) {
+/* We do not allow access to unknown groups */
+/* The group must have been obtained with a vfio device */
+stw_p(>hdr.rsp, CLP_RC_QUERYPCIFG_PFGID);
+goto out;
+}
+memcpy(resgrp, >zpci_grp, sizeof(ClpRspQueryPciGrp));
 stw_p(>hdr.rsp, CLP_RC_OK);
 break;
 }
@@ -754,7 +758,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 }
 /* Length must be greater than 8, a multiple of 8 */
 /* and not greater than maxstbl */
-if ((len <= 8) || (len % 8) || (len > pbdev->maxstbl)) {
+if ((len <= 8) || (len % 8) || (len > pbdev->pci_grp->zpci_grp.maxstbl)) {
 goto specification_error;
 }
 /* Do not cross a 4K-byte boundary */
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 1/5] vfio: vfio_iommu_type1: linux header place holder

2019-09-06 Thread Matthew Rosato
From: Pierre Morel 

This should be copied from Linux kernel UAPI includes.
The version used here is Linux 5.3.0

We define a new device region in vfio.h to be able to
get the ZPCI CLP information by reading this region from
userland.

We create a new file, vfio_zdev.h to define the structure
of the new region we defined in vfio.h

Signed-off-by: Pierre Morel 
Signed-off-by: Matthew Rosato 
---
 linux-headers/linux/vfio.h  |  7 ---
 linux-headers/linux/vfio_zdev.h | 35 +++
 2 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 linux-headers/linux/vfio_zdev.h

diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 24f5051..8328c87 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -9,8 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifndef VFIO_H
-#define VFIO_H
+#ifndef _UAPIVFIO_H
+#define _UAPIVFIO_H
 
 #include 
 #include 
@@ -371,6 +371,7 @@ struct vfio_region_gfx_edid {
  * to do TLB invalidation on a GPU.
  */
 #define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD   (1)
+#define VFIO_REGION_SUBTYPE_ZDEV_CLP   (2)
 
 /*
  * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
@@ -914,4 +915,4 @@ struct vfio_iommu_spapr_tce_remove {
 
 /* * */
 
-#endif /* VFIO_H */
+#endif /* _UAPIVFIO_H */
diff --git a/linux-headers/linux/vfio_zdev.h b/linux-headers/linux/vfio_zdev.h
new file mode 100644
index 000..2b912a5
--- /dev/null
+++ b/linux-headers/linux/vfio_zdev.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Region definition for ZPCI devices
+ *
+ * Copyright IBM Corp. 2019
+ *
+ * Author(s): Pierre Morel 
+ */
+
+#ifndef _VFIO_ZDEV_H_
+#define _VFIO_ZDEV_H_
+
+#include 
+
+/**
+ * struct vfio_region_zpci_info - ZPCI information.
+ *
+ */
+struct vfio_region_zpci_info {
+   __u64 dasm;
+   __u64 start_dma;
+   __u64 end_dma;
+   __u64 msi_addr;
+   __u64 flags;
+   __u16 pchid;
+   __u16 mui;
+   __u16 noi;
+   __u16 maxstbl;
+   __u8 version;
+   __u8 gid;
+#define VFIO_PCI_ZDEV_FLAGS_REFRESH 1
+   __u8 util_str[];
+} __attribute__ ((__packed__));
+
+#endif
-- 
1.8.3.1




Re: [Qemu-devel] [RFC PATCH 03/20] vl: Add "sgx-epc" option to expose SGX EPC sections to guest

2019-09-06 Thread Larry Dewey
I was playing with the new objects, etc, and found if the user
specifies -sgx-epc, and a memory device, but does not specify -cpu
host, +sgx, the vm runs without any warnings, while obviously not doing
anything to the memory. Perhaps some warnings if not everything which
is required is provided?

On Tue, 2019-08-06 at 11:56 -0700, Sean Christopherson wrote:
> Because SGX EPC is enumerated through CPUID, EPC "devices" need to be
> realized prior to realizing the vCPUs themselves, i.e. long before
> generic devices are parsed and realized.  From a virtualization
> perspective, the CPUID aspect also means that EPC sections cannot be
> hotplugged without paravirtualizing the guest kernel (hardware does
> not support hotplugging as EPC sections must be locked down during
> pre-boot to provide EPC's security properties).
> 
> So even though EPC sections could be realized through the generic
> -devices command, they need to be created much earlier for them to
> actually be usable by the guest.  Place all EPC sections in a
> contiguous block, somewhat arbitrarily starting after RAM above 4g.
> Ensuring EPC is in a contiguous region simplifies calculations, e.g.
> device memory base, PCI hole, etc..., allows dynamic calculation of
> the
> total EPC size, e.g. exposing EPC to guests does not require -maxmem,
> and last but not least allows all of EPC to be enumerated in a single
> ACPI entry, which is expected by some kernels, e.g. Windows 7 and 8.
> 
> Signed-off-by: Sean Christopherson 
> ---
>  hw/i386/sgx-epc.c | 107
> +-
>  include/hw/i386/pc.h  |   3 ++
>  include/hw/i386/sgx-epc.h |  18 +++
>  qemu-options.hx   |  12 +
>  vl.c  |   9 
>  5 files changed, 148 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
> index 73221ba86b..09aba1f8ea 100644
> --- a/hw/i386/sgx-epc.c
> +++ b/hw/i386/sgx-epc.c
> @@ -53,6 +53,8 @@ static void sgx_epc_init(Object *obj)
>  static void sgx_epc_realize(DeviceState *dev, Error **errp)
>  {
>  PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> +MemoryDeviceState *md = MEMORY_DEVICE(dev);
> +SGXEPCState *sgx_epc = pcms->sgx_epc;
>  SGXEPCDevice *epc = SGX_EPC(dev);
>  
>  if (pcms->boot_cpus != 0) {
> @@ -71,7 +73,18 @@ static void sgx_epc_realize(DeviceState *dev,
> Error **errp)
>  return;
>  }
>  
> -error_setg(errp, "'" TYPE_SGX_EPC "' not supported");
> +epc->addr = sgx_epc->base + sgx_epc->size;
> +
> +memory_region_add_subregion(_epc->mr, epc->addr - sgx_epc-
> >base,
> +host_memory_backend_get_memory(epc-
> >hostmem));
> +
> +host_memory_backend_set_mapped(epc->hostmem, true);
> +
> +sgx_epc->sections = g_renew(SGXEPCDevice *, sgx_epc->sections,
> +sgx_epc->nr_sections + 1);
> +sgx_epc->sections[sgx_epc->nr_sections++] = epc;
> +
> +sgx_epc->size += memory_device_get_region_size(md, errp);
>  }
>  
>  static void sgx_epc_unrealize(DeviceState *dev, Error **errp)
> @@ -167,3 +180,95 @@ static void sgx_epc_register_types(void)
>  }
>  
>  type_init(sgx_epc_register_types)
> +
> +
> +static int sgx_epc_set_property(void *opaque, const char *name,
> +const char *value, Error **errp)
> +{
> +Object *obj = opaque;
> +Error *err = NULL;
> +
> +object_property_parse(obj, value, name, );
> +if (err != NULL) {
> +error_propagate(errp, err);
> +return -1;
> +}
> +return 0;
> +}
> +
> +static int sgx_epc_init_func(void *opaque, QemuOpts *opts, Error
> **errp)
> +{
> +Error *err = NULL;
> +Object *obj;
> +
> +obj = object_new("sgx-epc");
> +
> +qdev_set_id(DEVICE(obj), qemu_opts_id(opts));
> +
> +if (qemu_opt_foreach(opts, sgx_epc_set_property, obj, )) {
> +goto out;
> +}
> +
> +object_property_set_bool(obj, true, "realized", );
> +
> +out:
> +if (err != NULL) {
> +error_propagate(errp, err);
> +}
> +object_unref(obj);
> +return err != NULL ? -1 : 0;
> +}
> +
> +void pc_machine_init_sgx_epc(PCMachineState *pcms)
> +{
> +SGXEPCState *sgx_epc;
> +
> +if (!sgx_epc_enabled) {
> +return;
> +}
> +
> +sgx_epc = g_malloc0(sizeof(*sgx_epc));
> +pcms->sgx_epc = sgx_epc;
> +
> +sgx_epc->base = 0x1ULL + pcms->above_4g_mem_size;
> +
> +memory_region_init(_epc->mr, OBJECT(pcms), "sgx-epc",
> UINT64_MAX);
> +memory_region_add_subregion(get_system_memory(), sgx_epc->base,
> +_epc->mr);
> +
> +qemu_opts_foreach(qemu_find_opts("sgx-epc"), sgx_epc_init_func,
> NULL,
> +  _fatal);
> +
> +if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) {
> +error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC
> to wrap",
> + sgx_epc->size);
> +exit(EXIT_FAILURE);
> +}
> +
> +

[Qemu-devel] [Bug 1805256] Re: qemu-img hangs on high core count ARM system

2019-09-06 Thread Rafael David Tinoco
Alright, I couldn't reproduce this yet, I'm running same test case in a
24 cores box and causing lots of context switches and CPU migrations in
parallel (trying to exhaust the logic).

Will let this running for sometime to check.

Unfortunately this can be related QEMU AIO BH locking/primitives and
cache coherency in the HW in question (which I got specs from:
https://en.wikichip.org/wiki/hisilicon/kunpeng/hi1616):

l1$ size8 MiB
l1d$ size   4 MiB
l1i$ size   4 MiB
l2$ size32 MiB
l3$ size64 MiB

like for example when having 2 threads in different NUMA domains, or
some other situation.

I can't simulate the same since I have a SOC with:

Cortex-A53 MPCore 24cores,

L1 I/D=32KB/32KB
L2 =256KB
L3 =4MB

and I'm not even close to L1/L2/L3 cache numbers from D06 =o).

Just got a note that I'll be able to reproduce this in the real HW, will
get back soon with real gdb debugging.

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

Title:
  qemu-img hangs on high core count ARM system

Status in QEMU:
  Confirmed
Status in qemu package in Ubuntu:
  In Progress

Bug description:
  On the HiSilicon D06 system - a 96 core NUMA arm64 box - qemu-img
  frequently hangs (~50% of the time) with this command:

  qemu-img convert -f qcow2 -O qcow2 /tmp/cloudimg /tmp/cloudimg2

  Where "cloudimg" is a standard qcow2 Ubuntu cloud image. This
  qcow2->qcow2 conversion happens to be something uvtool does every time
  it fetches images.

  Once hung, attaching gdb gives the following backtrace:

  (gdb) bt
  #0  0xae4f8154 in __GI_ppoll (fds=0xe8a67dc0, 
nfds=187650274213760, 
  timeout=, timeout@entry=0x0, sigmask=0xc123b950)
  at ../sysdeps/unix/sysv/linux/ppoll.c:39
  #1  0xbbefaf00 in ppoll (__ss=0x0, __timeout=0x0, __nfds=, 
  __fds=) at /usr/include/aarch64-linux-gnu/bits/poll2.h:77
  #2  qemu_poll_ns (fds=, nfds=, 
  timeout=timeout@entry=-1) at util/qemu-timer.c:322
  #3  0xbbefbf80 in os_host_main_loop_wait (timeout=-1)
  at util/main-loop.c:233
  #4  main_loop_wait (nonblocking=) at util/main-loop.c:497
  #5  0xbbe2aa30 in convert_do_copy (s=0xc123bb58) at 
qemu-img.c:1980
  #6  img_convert (argc=, argv=) at 
qemu-img.c:2456
  #7  0xbbe2333c in main (argc=7, argv=) at 
qemu-img.c:4975

  Reproduced w/ latest QEMU git (@ 53744e0a182)

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



Re: [Qemu-devel] [PATCH v8 01/32] riscv: hw: Remove duplicated "hw/hw.h" inclusion

2019-09-06 Thread Alistair Francis
On Fri, Sep 6, 2019 at 9:20 AM Bin Meng  wrote:
>
> Commit a27bd6c779ba ("Include hw/qdev-properties.h less") wrongly
> added "hw/hw.h" to sifive_prci.c and sifive_test.c.
>
> Another inclusion of "hw/hw.h" was later added via
> commit 650d103d3ea9 ("Include hw/hw.h exactly where needed"), that
> resulted in duplicated inclusion of "hw/hw.h".
>
> Fixes: a27bd6c779ba ("Include hw/qdev-properties.h less")
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> Changes in v8:
> - newly included in v8 to ease patch inter dependencies
>
>  hw/riscv/sifive_prci.c | 1 -
>  hw/riscv/sifive_test.c | 1 -
>  2 files changed, 2 deletions(-)
>
> diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_prci.c
> index 9837b61..562bc3d 100644
> --- a/hw/riscv/sifive_prci.c
> +++ b/hw/riscv/sifive_prci.c
> @@ -19,7 +19,6 @@
>   */
>
>  #include "qemu/osdep.h"
> -#include "hw/hw.h"
>  #include "hw/sysbus.h"
>  #include "qemu/module.h"
>  #include "target/riscv/cpu.h"
> diff --git a/hw/riscv/sifive_test.c b/hw/riscv/sifive_test.c
> index afbb3aa..3a14f9f 100644
> --- a/hw/riscv/sifive_test.c
> +++ b/hw/riscv/sifive_test.c
> @@ -19,7 +19,6 @@
>   */
>
>  #include "qemu/osdep.h"
> -#include "hw/hw.h"
>  #include "hw/sysbus.h"
>  #include "qemu/module.h"
>  #include "target/riscv/cpu.h"
> --
> 2.7.4
>
>



Re: [Qemu-devel] [PATCH v6 1/4] block: Add zoned device model property

2019-09-06 Thread Dmitry Fomichev
On Fri, 2019-09-06 at 23:10 +0200, Stefano Garzarella wrote:
> On Fri, Sep 06, 2019 at 04:17:12PM +, Dmitry Fomichev wrote:
> > On Fri, 2019-09-06 at 10:11 +0200, Stefano Garzarella wrote:
> > > On Wed, Sep 04, 2019 at 05:00:57PM -0400, Dmitry Fomichev wrote:
> > > > This commit adds Zoned Device Model (as defined in T10 ZBC and
> > > > T13 ZAC standards) as a block driver property, along with some
> > > > useful access functions.
> > > > 
> > > > A new backend driver permission, BLK_PERM_SUPPORT_HM_ZONED, is also
> > > > introduced. Only the drivers having this permission will be allowed
> > > > to open host managed zoned block devices.
> > > > 
> > > > No code is added yet to initialize or check the value of this new
> > > > property, therefore this commit doesn't change any functionality.
> > > > 
> > > > Signed-off-by: Dmitry Fomichev 
> > > > ---
> > > >  block.c   | 15 +++
> > > >  include/block/block.h | 19 ++-
> > > >  include/block/block_int.h |  3 +++
> > > >  3 files changed, 36 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/block.c b/block.c
> > > > index 874a29a983..69f565e1e9 100644
> > > > --- a/block.c
> > > > +++ b/block.c
> > > > @@ -4679,6 +4679,21 @@ void bdrv_get_geometry(BlockDriverState *bs, 
> > > > uint64_t *nb_sectors_ptr)
> > > >  *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
> > > >  }
> > > >  
> > > > +BdrvZonedModel bdrv_get_zoned_model(BlockDriverState *bs)
> > > > +{
> > > > +return bs->bl.zoned_model;
> > > > +}
> > > > +
> > > > +bool bdrv_is_hm_zoned(BlockDriverState *bs)
> > > > +{
> > > > +/*
> > > > + * Host Aware zone devices are supposed to be able to work
> > > > + * just like regular block devices. Thus, we only consider
> > > > + * Host Managed devices to be zoned here.
> > > > + */
> > > > +return bdrv_get_zoned_model(bs) == BDRV_ZONED_MODEL_HM;
> > > > +}
> > > > +
> > > >  bool bdrv_is_sg(BlockDriverState *bs)
> > > >  {
> > > >  return bs->sg;
> > > > diff --git a/include/block/block.h b/include/block/block.h
> > > > index 124ad40809..28d065ed80 100644
> > > > --- a/include/block/block.h
> > > > +++ b/include/block/block.h
> > > > @@ -271,18 +271,33 @@ enum {
> > > >   */
> > > >  BLK_PERM_GRAPH_MOD  = 0x10,
> > > >  
> > > > +/**
> > > > + * This permission is required to open host-managed zoned block 
> > > > devices.
> > > > + */
> > > > +BLK_PERM_SUPPORT_HM_ZONED   = 0x20,
> > > > +
> > > >  BLK_PERM_ALL= 0x1f,
> > > 
> > > Should we update BLK_PERM_ALL to 0x3f?
> > > 
> > Stefano, good catch! Will update and resend...
> > 
> 
> Good!
> 
> Looking better, if we update it, maybe we should also change something in
> xdbg_graph_add_edge() since there is this line:
> 
> QEMU_BUILD_BUG_ON(1UL << (ARRAY_SIZE(permissions) - 1) != BLK_PERM_ALL + 
> 1);
> 
> We should extend the permissions array or change this check.
> 
Yes, I've noticed that the mask change triggers this BUG_ON.
I am adding BLK_PERM_SUPPORT_HM_ZONED permission into "permissions" array and 
this
also requires adding the permission to qapi schema. I think that would be the 
right
thing to do rather than to modify this check.

Dmitry

> Thanks,
> Stefano


Re: [Qemu-devel] [PATCH v6 1/4] block: Add zoned device model property

2019-09-06 Thread Stefano Garzarella
On Fri, Sep 06, 2019 at 04:17:12PM +, Dmitry Fomichev wrote:
> On Fri, 2019-09-06 at 10:11 +0200, Stefano Garzarella wrote:
> > On Wed, Sep 04, 2019 at 05:00:57PM -0400, Dmitry Fomichev wrote:
> > > This commit adds Zoned Device Model (as defined in T10 ZBC and
> > > T13 ZAC standards) as a block driver property, along with some
> > > useful access functions.
> > > 
> > > A new backend driver permission, BLK_PERM_SUPPORT_HM_ZONED, is also
> > > introduced. Only the drivers having this permission will be allowed
> > > to open host managed zoned block devices.
> > > 
> > > No code is added yet to initialize or check the value of this new
> > > property, therefore this commit doesn't change any functionality.
> > > 
> > > Signed-off-by: Dmitry Fomichev 
> > > ---
> > >  block.c   | 15 +++
> > >  include/block/block.h | 19 ++-
> > >  include/block/block_int.h |  3 +++
> > >  3 files changed, 36 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/block.c b/block.c
> > > index 874a29a983..69f565e1e9 100644
> > > --- a/block.c
> > > +++ b/block.c
> > > @@ -4679,6 +4679,21 @@ void bdrv_get_geometry(BlockDriverState *bs, 
> > > uint64_t *nb_sectors_ptr)
> > >  *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
> > >  }
> > >  
> > > +BdrvZonedModel bdrv_get_zoned_model(BlockDriverState *bs)
> > > +{
> > > +return bs->bl.zoned_model;
> > > +}
> > > +
> > > +bool bdrv_is_hm_zoned(BlockDriverState *bs)
> > > +{
> > > +/*
> > > + * Host Aware zone devices are supposed to be able to work
> > > + * just like regular block devices. Thus, we only consider
> > > + * Host Managed devices to be zoned here.
> > > + */
> > > +return bdrv_get_zoned_model(bs) == BDRV_ZONED_MODEL_HM;
> > > +}
> > > +
> > >  bool bdrv_is_sg(BlockDriverState *bs)
> > >  {
> > >  return bs->sg;
> > > diff --git a/include/block/block.h b/include/block/block.h
> > > index 124ad40809..28d065ed80 100644
> > > --- a/include/block/block.h
> > > +++ b/include/block/block.h
> > > @@ -271,18 +271,33 @@ enum {
> > >   */
> > >  BLK_PERM_GRAPH_MOD  = 0x10,
> > >  
> > > +/**
> > > + * This permission is required to open host-managed zoned block 
> > > devices.
> > > + */
> > > +BLK_PERM_SUPPORT_HM_ZONED   = 0x20,
> > > +
> > >  BLK_PERM_ALL= 0x1f,
> > 
> > Should we update BLK_PERM_ALL to 0x3f?
> > 
> Stefano, good catch! Will update and resend...
> 

Good!

Looking better, if we update it, maybe we should also change something in
xdbg_graph_add_edge() since there is this line:

QEMU_BUILD_BUG_ON(1UL << (ARRAY_SIZE(permissions) - 1) != BLK_PERM_ALL + 1);

We should extend the permissions array or change this check.

Thanks,
Stefano



Re: [Qemu-devel] [PATCH] linux-user: drop redundant handling of environment variables

2019-09-06 Thread Laurent Vivier
Le 06/09/2019 à 18:57, Max Filippov a écrit :
> QEMU_STRACE and QEMU_RAND_SEED are handled by the parse_args, no need to
> do it again in main.
> 
> Signed-off-by: Max Filippov 
> ---
>  linux-user/main.c | 7 ---
>  1 file changed, 7 deletions(-)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index c9d97d2b1fc6..22ae2b3e65d1 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -701,13 +701,6 @@ int main(int argc, char **argv, char **envp)
>  
>  thread_cpu = cpu;
>  
> -if (getenv("QEMU_STRACE")) {
> -do_strace = 1;
> -}
> -
> -if (seed_optarg == NULL) {
> -seed_optarg = getenv("QEMU_RAND_SEED");
> -}
>  {
>  Error *err = NULL;
>  if (seed_optarg != NULL) {
> 

Reviewed-by: Laurent Vivier 



[Qemu-devel] [PATCH v4 3/4] target/arm: remove run time semihosting checks

2019-09-06 Thread Alex Bennée
Now we do all our checking and use a common EXCP_SEMIHOST for
semihosting operations we can make helper code a lot simpler.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
---
v2
  - fix re-base conflicts
  - hoist EXCP_SEMIHOST check
  - comment cleanups
v5
  - move CONFIG_TCG ifdefs
---
 target/arm/helper.c | 96 +++--
 1 file changed, 22 insertions(+), 74 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 507026c9154..a87ae6d46a1 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8339,88 +8339,32 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
   new_el, env->pc, pstate_read(env));
 }
 
-static inline bool check_for_semihosting(CPUState *cs)
-{
+/*
+ * Do semihosting call and set the appropriate return value. All the
+ * permission and validity checks have been done at translate time.
+ *
+ * We only see semihosting exceptions in TCG only as they are not
+ * trapped to the hypervisor in KVM.
+ */
 #ifdef CONFIG_TCG
-/* Check whether this exception is a semihosting call; if so
- * then handle it and return true; otherwise return false.
- */
+static void handle_semihosting(CPUState *cs)
+{
 ARMCPU *cpu = ARM_CPU(cs);
 CPUARMState *env = >env;
 
 if (is_a64(env)) {
-if (cs->exception_index == EXCP_SEMIHOST) {
-/* This is always the 64-bit semihosting exception.
- * The "is this usermode" and "is semihosting enabled"
- * checks have been done at translate time.
- */
-qemu_log_mask(CPU_LOG_INT,
-  "...handling as semihosting call 0x%" PRIx64 "\n",
-  env->xregs[0]);
-env->xregs[0] = do_arm_semihosting(env);
-return true;
-}
-return false;
+qemu_log_mask(CPU_LOG_INT,
+  "...handling as semihosting call 0x%" PRIx64 "\n",
+  env->xregs[0]);
+env->xregs[0] = do_arm_semihosting(env);
 } else {
-uint32_t imm;
-
-/* Only intercept calls from privileged modes, to provide some
- * semblance of security.
- */
-if (cs->exception_index != EXCP_SEMIHOST &&
-(!semihosting_enabled() ||
- ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR))) {
-return false;
-}
-
-switch (cs->exception_index) {
-case EXCP_SEMIHOST:
-/* This is always a semihosting call; the "is this usermode"
- * and "is semihosting enabled" checks have been done at
- * translate time.
- */
-break;
-case EXCP_SWI:
-/* Check for semihosting interrupt.  */
-if (env->thumb) {
-imm = arm_lduw_code(env, env->regs[15] - 2, arm_sctlr_b(env))
-& 0xff;
-if (imm == 0xab) {
-break;
-}
-} else {
-imm = arm_ldl_code(env, env->regs[15] - 4, arm_sctlr_b(env))
-& 0xff;
-if (imm == 0x123456) {
-break;
-}
-}
-return false;
-case EXCP_BKPT:
-/* See if this is a semihosting syscall.  */
-if (env->thumb) {
-imm = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env))
-& 0xff;
-if (imm == 0xab) {
-env->regs[15] += 2;
-break;
-}
-}
-return false;
-default:
-return false;
-}
-
 qemu_log_mask(CPU_LOG_INT,
   "...handling as semihosting call 0x%x\n",
   env->regs[0]);
 env->regs[0] = do_arm_semihosting(env);
-return true;
 }
-#else
-return false;
-#endif
 }
+#endif
 
 /* Handle a CPU exception for A and R profile CPUs.
  * Do any appropriate logging, handle PSCI calls, and then hand off
@@ -8451,13 +8395,17 @@ void arm_cpu_do_interrupt(CPUState *cs)
 return;
 }
 
-/* Semihosting semantics depend on the register width of the
- * code that caused the exception, not the target exception level,
- * so must be handled here.
+/*
+ * Semihosting semantics depend on the register width of the code
+ * that caused the exception, not the target exception level, so
+ * must be handled here.
  */
-if (check_for_semihosting(cs)) {
+#ifdef CONFIG_TCG
+if (cs->exception_index == EXCP_SEMIHOST) {
+handle_semihosting(cs);
 return;
 }
+#endif
 
 /* Hooks may change global state so BQL should be held, also the
  * BQL needs to be held for any modification of
-- 
2.20.1




[Qemu-devel] [PATCH v4 0/4] semihosting at translate time fixes

2019-09-06 Thread Alex Bennée
Hi Peter,

Hopefully this is the final version of the semihosting at translate
time patches. I've applied Richard's IS_USER changes and gated the SVN
for !M profile.

Alex Bennée (3):
  target/arm: handle M-profile semihosting at translate time
  target/arm: handle A-profile semihosting at translate time
  target/arm: remove run time semihosting checks

Emilio G. Cota (1):
  atomic_template: fix indentation in GEN_ATOMIC_HELPER

 accel/tcg/atomic_template.h |  2 +-
 target/arm/helper.c | 96 +
 target/arm/m_helper.c   | 18 +++
 target/arm/translate.c  | 24 --
 4 files changed, 48 insertions(+), 92 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCH v4 4/4] atomic_template: fix indentation in GEN_ATOMIC_HELPER

2019-09-06 Thread Alex Bennée
From: "Emilio G. Cota" 

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
---
 accel/tcg/atomic_template.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index df9c8388178..287433d809b 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -149,7 +149,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong 
addr,
 
 #define GEN_ATOMIC_HELPER(X)\
 ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,   \
- ABI_TYPE val EXTRA_ARGS)   \
+ABI_TYPE val EXTRA_ARGS)\
 {   \
 ATOMIC_MMU_DECLS;   \
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;   \
-- 
2.20.1




[Qemu-devel] [PATCH v4 2/4] target/arm: handle A-profile semihosting at translate time

2019-09-06 Thread Alex Bennée
As for the other semihosting calls we can resolve this at translate
time.

Signed-off-by: Alex Bennée 

---
v2
  - update for change to gen_exception_internal_insn API
v3
  - update for decode tree, merge T32 & A32 commits
  - dropped r-b due to changes
v4
  - !IS_USER and !arm_dc_feature(s, ARM_FEATURE_M)
---
 target/arm/translate.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6689acc911e..d7ee4f88ace 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10219,14 +10219,22 @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
 }
 
 /*
- * Supervisor call
+ * Supervisor call - both T32 & A32 come here so we need to check
+ * which mode we are in when checking for semihosting.
  */
 
 static bool trans_SVC(DisasContext *s, arg_SVC *a)
 {
-gen_set_pc_im(s, s->base.pc_next);
-s->svc_imm = a->imm;
-s->base.is_jmp = DISAS_SWI;
+const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
+
+if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled()
+&& !IS_USER(s) && (a->imm == semihost_imm)) {
+gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+} else {
+gen_set_pc_im(s, s->base.pc_next);
+s->svc_imm = a->imm;
+s->base.is_jmp = DISAS_SWI;
+}
 return true;
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 1/4] target/arm: handle M-profile semihosting at translate time

2019-09-06 Thread Alex Bennée
We do this for other semihosting calls so we might as well do it for
M-profile as well.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 

---
v2
  - update for change to gen_exception_internal_insn API
v3
  - update for decode tree
v4
  - use !IS_USER
---
 target/arm/m_helper.c  | 18 ++
 target/arm/translate.c |  8 +++-
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 884d35d2b02..27cd2f3f964 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2114,19 +2114,13 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
 break;
 }
 break;
+case EXCP_SEMIHOST:
+qemu_log_mask(CPU_LOG_INT,
+  "...handling as semihosting call 0x%x\n",
+  env->regs[0]);
+env->regs[0] = do_arm_semihosting(env);
+return;
 case EXCP_BKPT:
-if (semihosting_enabled()) {
-int nr;
-nr = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env)) & 0xff;
-if (nr == 0xab) {
-env->regs[15] += 2;
-qemu_log_mask(CPU_LOG_INT,
-  "...handling as semihosting call 0x%x\n",
-  env->regs[0]);
-env->regs[0] = do_arm_semihosting(env);
-return;
-}
-}
 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
 break;
 case EXCP_IRQ:
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 34bb280e3da..6689acc911e 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8424,7 +8424,13 @@ static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
 if (!ENABLE_ARCH_5) {
 return false;
 }
-gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
+if (arm_dc_feature(s, ARM_FEATURE_M) &&
+semihosting_enabled() && !IS_USER(s) &&
+(a->imm == 0xab)) {
+gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+} else {
+gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
+}
 return true;
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH v2 3/3] qemu-iotests: Add test for bz #1745922

2019-09-06 Thread Maxim Levitsky
Signed-off-by: Maxim Levitsky 
---
 tests/qemu-iotests/263 | 75 ++
 tests/qemu-iotests/263.out | 19 ++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 95 insertions(+)
 create mode 100755 tests/qemu-iotests/263
 create mode 100644 tests/qemu-iotests/263.out

diff --git a/tests/qemu-iotests/263 b/tests/qemu-iotests/263
new file mode 100755
index 00..36951ff7b4
--- /dev/null
+++ b/tests/qemu-iotests/263
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+#
+# Test encrypted write that crosses cluster boundary of two unallocated 
clusters
+# Based on 188
+#
+# Copyright (C) 2019 Red Hat, Inc.
+#
+# 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 of the License, 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 .
+#
+
+# creator
+owner=mlevi...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+
+size=1M
+
+SECRET="secret,id=sec0,data=astrochicken"
+
+_make_test_img --object $SECRET -o 
"encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=64K"
 $size
+
+IMGSPEC="driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG"
+
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
+
+echo
+echo "== reading the whole image =="
+$QEMU_IO --object $SECRET -c "read -P 0 0 $size" --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+echo
+echo "== write two 512 byte sectors on a cluster boundary =="
+$QEMU_IO --object $SECRET -c "write -P 0xAA 0xFE00 0x400" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+
+echo
+echo "== verify that the rest of the image is not changed =="
+$QEMU_IO --object $SECRET -c "read -P 0x00 0x0 0xFE00" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+$QEMU_IO --object $SECRET -c "read -P 0xAA 0x0FE00 0x400" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+$QEMU_IO --object $SECRET -c "read -P 0x00 0x10200 0xEFE00" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+
+_cleanup_test_img
+
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/263.out b/tests/qemu-iotests/263.out
new file mode 100644
index 00..fa4e4e0e4a
--- /dev/null
+++ b/tests/qemu-iotests/263.out
@@ -0,0 +1,19 @@
+QA output created by 263
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks 
encrypt.key-secret=sec0 encrypt.iter-time=10
+
+== reading whole image ==
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== write two 512 byte sectors on a cluster boundary ==
+wrote 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify that the rest of the image is not changed ==
+read 65024/65024 bytes at offset 0
+63.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 982528/982528 bytes at offset 66048
+959.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index d95d556414..be1c4a3baa 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -274,3 +274,4 @@
 257 rw
 258 rw quick
 262 rw quick migration
+263 rw quick
-- 
2.17.2




[Qemu-devel] [PATCH v2 0/3] Fix qcow2+luks corruption introduced by commit 8ac0f15f335

2019-09-06 Thread Maxim Levitsky
Commit 8ac0f15f335 accidently broke the COW of non changed areas
of newly allocated clusters, when the write spans multiple clusters,
and needs COW both prior and after the write.
This results in 'after' COW area being encrypted with wrong
sector address, which render it corrupted.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922

CC: qemu-stable 

V2: grammar, spelling and code style fixes.

Best regards,
Maxim Levitsky

Maxim Levitsky (3):
  block/qcow2: refactoring of threaded encryption code
  block/qcow2: fix the corruption when rebasing luks encrypted files
  qemu-iotests: Add test for bz #1745922

 block/qcow2-cluster.c  | 30 ---
 block/qcow2-threads.c  | 61 ---
 tests/qemu-iotests/263 | 75 ++
 tests/qemu-iotests/263.out | 19 ++
 tests/qemu-iotests/group   |  1 +
 5 files changed, 160 insertions(+), 26 deletions(-)
 create mode 100755 tests/qemu-iotests/263
 create mode 100644 tests/qemu-iotests/263.out

-- 
2.17.2




[Qemu-devel] [PATCH v2 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Maxim Levitsky
This commit tries to clarify few function arguments,
and add comments describing the encrypt/decrypt interface

Signed-off-by: Maxim Levitsky 
---
 block/qcow2-cluster.c | 10 +++
 block/qcow2-threads.c | 61 ++-
 2 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f09cc992af..1989b423da 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -463,8 +463,8 @@ static int coroutine_fn 
do_perform_cow_read(BlockDriverState *bs,
 }
 
 static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
-uint64_t src_cluster_offset,
-uint64_t cluster_offset,
+uint64_t guest_cluster_offset,
+uint64_t host_cluster_offset,
 unsigned offset_in_cluster,
 uint8_t *buffer,
 unsigned bytes)
@@ -474,8 +474,8 @@ static bool coroutine_fn 
do_perform_cow_encrypt(BlockDriverState *bs,
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
 assert(s->crypto);
-if (qcow2_co_encrypt(bs, cluster_offset,
- src_cluster_offset + offset_in_cluster,
+if (qcow2_co_encrypt(bs, host_cluster_offset,
+ guest_cluster_offset + offset_in_cluster,
  buffer, bytes) < 0) {
 return false;
 }
@@ -496,7 +496,7 @@ static int coroutine_fn 
do_perform_cow_write(BlockDriverState *bs,
 }
 
 ret = qcow2_pre_write_overlap_check(bs, 0,
-cluster_offset + offset_in_cluster, qiov->size, true);
+  cluster_offset + offset_in_cluster, qiov->size, true);
 if (ret < 0) {
 return ret;
 }
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 3b1e63fe41..c3cda0c6a5 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -234,15 +234,19 @@ static int qcow2_encdec_pool_func(void *opaque)
 }
 
 static int coroutine_fn
-qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
-  uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc func)
+qcow2_co_encdec(BlockDriverState *bs, uint64_t host_cluster_offset,
+uint64_t guest_offset, void *buf, size_t len,
+Qcow2EncDecFunc func)
 {
 BDRVQcow2State *s = bs->opaque;
+
+uint64_t offset = s->crypt_physical_offset ?
+host_cluster_offset + offset_into_cluster(s, guest_offset) :
+guest_offset;
+
 Qcow2EncDecData arg = {
 .block = s->crypto,
-.offset = s->crypt_physical_offset ?
-  file_cluster_offset + offset_into_cluster(s, offset) :
-  offset,
+.offset = offset,
 .buf = buf,
 .len = len,
 .func = func,
@@ -251,18 +255,49 @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t 
file_cluster_offset,
 return qcow2_co_process(bs, qcow2_encdec_pool_func, );
 }
 
+
+/*
+ * qcow2_co_encrypt()
+ *
+ * Encrypts one or more contiguous aligned sectors
+ *
+ * @host_cluster_offset - on disk offset of the first cluster in which
+ * the encrypted data will be written
+ * Used as an initialization vector for encryption
+ *
+ * @guest_offset - guest (virtual) offset of the first sector of the
+ * data to be encrypted
+ * Used as an initialization vector for older, qcow2 native encryption
+ *
+ * @buf - buffer with the data to encrypt
+ * @len - length of the buffer (in sector size multiplies)
+ *
+ * Note that the group of the sectors, don't have to be aligned
+ * on cluster boundary and can also cross a cluster boundary.
+ *
+ *
+ */
 int coroutine_fn
-qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
- uint64_t offset, void *buf, size_t len)
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
+ uint64_t guest_offset, void *buf, size_t len)
 {
-return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
- qcrypto_block_encrypt);
+return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
+   qcrypto_block_encrypt);
 }
 
+
+/*
+ * qcow2_co_decrypt()
+ *
+ * Decrypts one or more contiguous aligned sectors
+ * Same function as qcow2_co_encrypt
+ *
+ */
+
 int coroutine_fn
-qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
- uint64_t offset, void *buf, size_t len)
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
+ uint64_t guest_offset, void *buf, size_t len)
 {
-return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
- 

[Qemu-devel] [PATCH v2 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files

2019-09-06 Thread Maxim Levitsky
This fixes subtle corruption introduced by luks threaded encryption
in commit 8ac0f15f335

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922

The corruption happens when we do a write that
   * writes to two or more unallocated clusters at once
   * doesn't fully cover the first sector
   * doesn't fully cover the last sector

In this case, when allocating the new clusters we COW both areas
prior to the write and after the write, and we encrypt them.

The above mentioned commit accidentally made it so we encrypt the
second COW area using the physical cluster offset of the first area.

Fix this by:
 * Remove the offset_in_cluster parameter of do_perform_cow_encrypt,
   since it is misleading. That offset can be larger than cluster size
   currently.

   Instead just add the start and the end COW area offsets to both host
   and guest offsets that do_perform_cow_encrypt receives.

*  in do_perform_cow_encrypt, remove the cluster offset from the host_offset,
   and thus pass correctly to the qcow2_co_encrypt, the host cluster offset
   and full guest offset

In the bugreport that was triggered by rebasing a luks image to new,
zero filled base, which lot of such writes, and causes some files
with zero areas to contain garbage there instead.
But as described above it can happen elsewhere as well


Signed-off-by: Maxim Levitsky 
---
 block/qcow2-cluster.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 1989b423da..6df17dd296 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -463,20 +463,20 @@ static int coroutine_fn 
do_perform_cow_read(BlockDriverState *bs,
 }
 
 static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
-uint64_t guest_cluster_offset,
-uint64_t host_cluster_offset,
-unsigned offset_in_cluster,
+uint64_t guest_offset,
+uint64_t host_offset,
 uint8_t *buffer,
 unsigned bytes)
 {
 if (bytes && bs->encrypted) {
 BDRVQcow2State *s = bs->opaque;
-assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
-assert((bytes & ~BDRV_SECTOR_MASK) == 0);
+
+assert(QEMU_IS_ALIGNED(guest_offset | host_offset | bytes,
+   BDRV_SECTOR_SIZE));
 assert(s->crypto);
-if (qcow2_co_encrypt(bs, host_cluster_offset,
- guest_cluster_offset + offset_in_cluster,
- buffer, bytes) < 0) {
+
+if (qcow2_co_encrypt(bs, start_of_cluster(s, host_offset),
+ guest_offset, buffer, bytes) < 0) {
 return false;
 }
 }
@@ -890,11 +890,15 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta 
*m)
 
 /* Encrypt the data if necessary before writing it */
 if (bs->encrypted) {
-if (!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
-start->offset, start_buffer,
+if (!do_perform_cow_encrypt(bs,
+m->offset + start->offset,
+m->alloc_offset + start->offset,
+start_buffer,
 start->nb_bytes) ||
-!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
-end->offset, end_buffer, end->nb_bytes)) {
+!do_perform_cow_encrypt(bs,
+m->offset + end->offset,
+m->alloc_offset + end->offset,
+end_buffer, end->nb_bytes)) {
 ret = -EIO;
 goto fail;
 }
-- 
2.17.2




Re: [Qemu-devel] [PATCH v4 00/54] plugins for TCG

2019-09-06 Thread Alex Bennée


Markus Armbruster  writes:

> Alex Bennée  writes:
>
>> Hi,
>>
>> This is the latest iteration of the plugins series. The main changes
>> from the last version are:
>>
>>   - dropped passing of haddr to plugins
>>
>> This makes the code for handling the plugins less invasive in the
>> softmmu path at the cost of offloading processing to the plugin if it
>> wants the value. We rely on the fact that the TLB is per vCPU so a
>> helper can just trigger a re-query of the TLB to get the final
>> address.
>>
>> Part of that change involved embedding the MMU index in the meminfo
>> field for tracing. I see there are some other patches on the list for
>> messing with TCGMemOp so there might be a clash coming up.
>>
>>   - translator_ld goes direct to softmmu/user functions
>>
>> I also mark the [SOFTMMU_]CODE_ACCESS helpers as deprecated. There is
>> more work to be done to clean up all the current uses of code access
>> helpers but ideally the only thing that should be peaking at code is
>> the translator loop itself. However a bunch of helpers have taken to
>> using code loading functions to peak at the instruction just executed
>> to figure out what to do. Once those have been fixed then we can
>> remove those helpers.
>>
>> Other more minor fixes can be found documented bellow the --- in the
>> individual patches.
>>
>> This series also includes the semihosting patches as they are a
>> pre-requisite for the translator_ld patches for ARM.
>>
>> Once the tree opens up for development again I hope to get the
>> semihosting and trivial clean-up patches merged quickly so the patch
>> count for the plugins patches proper can be reduced a bit.
>
> Next time, please explain briefly what TCG plugins are about right in
> your cover letter.  I had to go hunting for this.  Found "[PATCH v4
> 11/54] docs/devel: add plugins.rst design document".

I'll provide a better overview in my next cover letter.

> Please advise why TCG plugins don't undermine the GPL.  Any proposal to
> add a plugin interface needs to do that.

I'm not sure what we can say about this apart from "ask your lawyer".
I'm certainly not proposing we add any sort of language about what
should and shouldn't be allowed to use the plugin interface. I find it
hard to see how anyone could argue code written to interface with the
plugin API couldn't be considered a derived work.

There are two use cases I have in mind:

The first is FLOSS developers writing interesting tools that can take
advantage of QEMU's control of the system to do experiments that are
tricky with other setups (Valgrind is limited to same-arch, Dynamo/Pin
are user-space only). I want these experiments to be easy to do without
having to keep hacking and re-hacking QEMU's core code. I would hope
QEMU developers would up-stream theirs into the QEMU source tree but I
can imagine academics will have open source code that will only ever sit
in their paper's repository.

The other is users who currently maintain hacked up internal copies of
QEMU as a test bed for whatever piece of silicon they are brewing behind
closed doors. This code would never be distributed (hence never be a GPL
issue) and is generally kept private because it's IP sensitive
(e.g: experimenting with different cache models). If we can provide an
interface that allows them to keep their experiments private and
separate from changes to the core code then maybe apart from making
their lives a bit easier we will see some non-IP sensitive contributions
come back to the upstream. I live in hope ;-)

--
Alex Bennée



Re: [Qemu-devel] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files

2019-09-06 Thread Maxim Levitsky
On Fri, 2019-09-06 at 14:17 -0500, Eric Blake wrote:
> On 9/6/19 12:32 PM, Maxim Levitsky wrote:
> > This fixes subltle corruption introduced by luks threaded encryption
> 
> subtle

I usually put the commit messages to a spellchecker, but this time
I forgot to do this. I will try not to in the future.

> 
> > in commit 8ac0f15f335
> > 
> > Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922
> > 
> > The corruption happens when we do
> >* write to two or more unallocated clusters at once
> >* write doesn't fully cover nether first nor last cluster
> 
> s/nether/neither/
> 
> or even:
> 
> write doesn't fully cover either the first or the last cluster
I think I didn't wrote the double negative correctly here.
I meant a write that doesn't cover first sector fully and doesn't cover second 
sector.
I'll just write it like that I guess.

> 
> > 
> > In this case, when allocating the new clusters we COW both area
> 
> areas
> 
> > prior to the write and after the write, and we encrypt them.
> > 
> > The above mentioned commit accidently made it so, we encrypt the
> 
> accidentally
> 
> s/made it so, we encrypt/changed the encryption of/
> 
> > second COW are using the physical cluster offset of the first area.
> 
> s/are using/to use/
I actually meant to write 'area' here. I just haven't proofed the commit
message at all I confess. Next time I do better.

> 
> > 
> > Fix this by:
> >  * remove the offset_in_cluster parameter of do_perform_cow_encrypt
> >since it is misleading. That offset can be larger that cluster size.
> >instead just add the start and end COW are offsets to both host and 
> > guest offsets
> >that do_perform_cow_encrypt receives.
> > 
> > *  in do_perform_cow_encrypt, remove the cluster offset from the host_offset
> >And thus pass correctly to the qcow2_co_encrypt, the host cluster offset 
> > and full guest offset
> > 
> > 
> > Signed-off-by: Maxim Levitsky 
> > ---
> >  block/qcow2-cluster.c | 26 +++---
> >  1 file changed, 15 insertions(+), 11 deletions(-)
> > 
> > +++ b/block/qcow2-cluster.c
> > @@ -463,20 +463,20 @@ static int coroutine_fn 
> > do_perform_cow_read(BlockDriverState *bs,
> >  }
> >  
> >  static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
> > -uint64_t 
> > guest_cluster_offset,
> > -uint64_t 
> > host_cluster_offset,
> > -unsigned offset_in_cluster,
> > +uint64_t guest_offset,
> > +uint64_t host_offset,
> >  uint8_t *buffer,
> >  unsigned bytes)
> >  {
> >  if (bytes && bs->encrypted) {
> >  BDRVQcow2State *s = bs->opaque;
> > -assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
> > +assert((guest_offset & ~BDRV_SECTOR_MASK) == 0);
> > +assert((host_offset & ~BDRV_SECTOR_MASK) == 0);
> >  assert((bytes & ~BDRV_SECTOR_MASK) == 0);
> 
> Pre-existing, but we could use QEMU_IS_ALIGNED(x, BDRV_SECTOR_SIZE) for
> slightly more legibility than open-coding the bit operation.
> 
> Neat trick about power-of-2 alignment checks:
> 
> assert(QEMU_IS_ALIGNED(offset_in_cluster | guest_offset |
>host_offset | bytes, BDRV_SECTOR_SIZE));

In my book, a shorter code is almost always better, so why not.
> 
> gives the same result in one assertion.  (I've used it elsewhere in the
> code base, but I'm not opposed to one assert per variable if you think
> batching is too dense.)
> 
> I'll let Dan review the actual code change, but offhand it makes sense
> to me.
> 

Best regards,
Thanks for the review,
Maxim Levitsky





Re: [Qemu-devel] [PATCH v4 13/54] plugin: add user-facing API

2019-09-06 Thread Alex Bennée


Aaron Lindsay OS  writes:

> One thing I would find useful is the ability to access register values
> during an execution-time callback. I think the easiest way to do that
> generically would be to expose them via the gdb functionality (like
> Pavel's earlier patchset did [1]), though that (currently) limits you to
> the general-purpose registers. Ideally it would be nice be able to
> access other registers (i.e. floating-point, or maybe even system
> registers), though those are more difficult to do generically.

ARM already has system register support via the gdbstub XML interface so
it's certainly doable. The trick is how we do that in a probable way
without leaking the gdb remote protocol into plugins (which is just very
ugly).

> Perhaps if we added some sort of architectural-support checking for
> individual plugins like I mentioned in another response to this
> patchset, we could allow some limited architecture-specific
> functionality in this vein? I confess I haven't thought through all the
> ramifications of that yet, though.

I was wondering if exposing the Elf Type would be enough? It's portable
enough that plugins should be able to work with it without defining our
own architecture enumeration.

>
> -Aaron
>
> [1] - See qemulib_read_register() at
>   https://patchwork.ozlabs.org/patch/925393/


--
Alex Bennée



Re: [Qemu-devel] [RFC 2 PATCH 06/16] hw/core: Add core complex id in X86CPU topology

2019-09-06 Thread Moger, Babu


On 9/6/19 2:20 PM, Eric Blake wrote:
> On 9/6/19 2:12 PM, Moger, Babu wrote:
>> Introduce cpu core complex id(ccx_id) in x86CPU topology.
>> Each CCX can have upto 4 cores and share same L3 cache.
>> This information is required to build the topology in
>> new apyc mode.
>>
>> Signed-off-by: Babu Moger 
>> ---
> 
>> +++ b/qapi/machine.json
>> @@ -597,9 +597,10 @@
>>  # @node-id: NUMA node ID the CPU belongs to
>>  # @socket-id: socket number within node/board the CPU belongs to
>>  # @die-id: die number within node/board the CPU belongs to (Since 4.1)
>> +# @ccx-id: core complex number within node/board the CPU belongs to (Since 
>> 4.1)
> 
> 4.2 now
ok. Will fix.
> 
>>  # @core-id: core number within die the CPU belongs to# @thread-id: thread 
>> number within core the CPU belongs to
> 
> Pre-existing, but let's fix that missing newline while you're here.

Sure. will take care. thanks


[Qemu-devel] [RFC 2 PATCH 15/16] i386: Fix pkg_id offset for epyc mode

2019-09-06 Thread Moger, Babu
Signed-off-by: Babu Moger 
---
 target/i386/cpu.c |   24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f25491a029..f8b1fc5c07 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4094,9 +4094,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
 {
+MachineState *ms = MACHINE(qdev_get_machine());
 X86CPU *cpu = env_archcpu(env);
 CPUState *cs = env_cpu(env);
-uint32_t die_offset;
+uint32_t die_offset, pkg_offset;
 uint32_t limit;
 uint32_t signature[3];
 
@@ -4119,6 +4120,21 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 index = env->cpuid_level;
 }
 
+if (ms->epyc) {
+X86CPUTopoInfo topo_info = {
+.numa_nodes = nb_numa_nodes,
+.nr_sockets = ms->smp.sockets,
+.nr_cores = ms->smp.cores,
+.nr_threads = ms->smp.threads,
+};
+unsigned nodes = nodes_in_pkg(_info);
+pkg_offset = apicid_pkg_offset_epyc(nodes, MAX_CCX, MAX_CORES_IN_CCX,
+cs->nr_threads);
+} else {
+pkg_offset = apicid_pkg_offset(env->nr_dies, cs->nr_cores,
+   cs->nr_threads);
+}
+
 switch(index) {
 case 0:
 *eax = env->cpuid_level;
@@ -4275,8 +4291,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
 break;
 case 1:
-*eax = apicid_pkg_offset(env->nr_dies,
- cs->nr_cores, cs->nr_threads);
+*eax = pkg_offset;
 *ebx = cs->nr_cores * cs->nr_threads;
 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
 break;
@@ -4310,8 +4325,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
 break;
 case 2:
-*eax = apicid_pkg_offset(env->nr_dies, cs->nr_cores,
-   cs->nr_threads);
+*eax = pkg_offset;
 *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
 *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
 break;



[Qemu-devel] [RFC 2 PATCH 13/16] machine: Add new epyc property in PCMachineState

2019-09-06 Thread Moger, Babu
Adds new epyc property in PCMachineState and also in MachineState.
This property will be used to initialize the mode specific handlers
to generate apic ids.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c |   23 +++
 include/hw/boards.h  |2 ++
 include/hw/i386/pc.h |1 +
 3 files changed, 26 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 959bd3821b..14760523a9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2810,6 +2810,22 @@ static void pc_machine_set_pit(Object *obj, bool value, 
Error **errp)
 pcms->pit_enabled = value;
 }
 
+static bool pc_machine_get_epyc(Object *obj, Error **errp)
+{
+PCMachineState *pcms = PC_MACHINE(obj);
+
+return pcms->epyc;
+}
+
+static void pc_machine_set_epyc(Object *obj, bool value, Error **errp)
+{
+PCMachineState *pcms = PC_MACHINE(obj);
+MachineState *ms = MACHINE(pcms);
+
+pcms->epyc = value;
+ms->epyc = value;
+}
+
 static void pc_machine_initfn(Object *obj)
 {
 PCMachineState *pcms = PC_MACHINE(obj);
@@ -3015,6 +3031,13 @@ static void pc_machine_class_init(ObjectClass *oc, void 
*data)
 
 object_class_property_add_bool(oc, PC_MACHINE_PIT,
 pc_machine_get_pit, pc_machine_set_pit, _abort);
+
+object_class_property_add_bool(oc, "epyc",
+pc_machine_get_epyc, pc_machine_set_epyc, _abort);
+
+object_class_property_set_description(oc, "epyc",
+"Set on/off to use epyc mode", _abort);
+
 }
 
 static const TypeInfo pc_machine_info = {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 12eb5032a5..0001d42e50 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -299,6 +299,8 @@ struct MachineState {
 AccelState *accelerator;
 CPUArchIdList *possible_cpus;
 CpuTopology smp;
+bool epyc;
+
 struct NVDIMMState *nvdimms_state;
 };
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index d6f1189997..cf9e7b0045 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -68,6 +68,7 @@ struct PCMachineState {
 uint64_t *node_mem;
 
 /* Apic id specific handlers */
+bool epyc;
 uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info, unsigned 
cpu_index);
 void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
  X86CPUTopoIDs *topo_ids);



[Qemu-devel] [RFC 2 PATCH 14/16] hw/i386: Introduce epyc mode function handlers

2019-09-06 Thread Moger, Babu
Introduce following handlers for new epyc mode.
x86_apicid_from_cpu_idx_epyc: Generate apicid from cpu index.
x86_topo_ids_from_apicid_epyc: Generate topo ids from apic id.
x86_apicid_from_topo_ids_epyci: Generate apicid from topo ids.

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

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 14760523a9..59c7c4d8b2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2824,6 +2824,11 @@ static void pc_machine_set_epyc(Object *obj, bool value, 
Error **errp)
 
 pcms->epyc = value;
 ms->epyc = value;
+if (pcms->epyc) {
+pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc;
+pcms->topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc;
+pcms->apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc;
+}
 }
 
 static void pc_machine_initfn(Object *obj)



Re: [Qemu-devel] [RFC 2 PATCH 06/16] hw/core: Add core complex id in X86CPU topology

2019-09-06 Thread Eric Blake
On 9/6/19 2:12 PM, Moger, Babu wrote:
> Introduce cpu core complex id(ccx_id) in x86CPU topology.
> Each CCX can have upto 4 cores and share same L3 cache.
> This information is required to build the topology in
> new apyc mode.
> 
> Signed-off-by: Babu Moger 
> ---

> +++ b/qapi/machine.json
> @@ -597,9 +597,10 @@
>  # @node-id: NUMA node ID the CPU belongs to
>  # @socket-id: socket number within node/board the CPU belongs to
>  # @die-id: die number within node/board the CPU belongs to (Since 4.1)
> +# @ccx-id: core complex number within node/board the CPU belongs to (Since 
> 4.1)

4.2 now

>  # @core-id: core number within die the CPU belongs to# @thread-id: thread 
> number within core the CPU belongs to

Pre-existing, but let's fix that missing newline while you're here.

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



[Qemu-devel] [RFC 2 PATCH 16/16] hw/core: Fix up the machine_set_cpu_numa_node for epyc

2019-09-06 Thread Moger, Babu
Current topology id match will not work for epyc mode when setting
the node id. In epyc mode, ids like smt_id, thread_id, core_id,
ccx_id, socket_id can be same for more than one CPUs with across
two numa nodes.

For example, we can have two CPUs with following ids on two different node.
1. smt_id=0, thread_id=0, core_id=0, ccx_id=0, socket_id=0, node_id=0
2. smt_id=0, thread_id=0, core_id=0, ccx_id=0, socket_id=0, node_id=1

The function machine_set_cpu_numa_node will fail to find a match to assign
the node. Added new function machine_set_cpu_numa_node_epyc to set the node_id
directly in epyc mode.

Signed-off-by: Babu Moger 
---
 hw/core/machine.c   |   24 
 hw/core/numa.c  |6 +-
 include/hw/boards.h |4 
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 9a8586cf30..6bceefc6f3 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -741,6 +741,30 @@ void machine_set_cpu_numa_node(MachineState *machine,
 }
 }
 
+void machine_set_cpu_numa_node_epyc(MachineState *machine,
+const CpuInstanceProperties *props,
+unsigned index,
+Error **errp)
+{
+MachineClass *mc = MACHINE_GET_CLASS(machine);
+CPUArchId *slot;
+
+if (!mc->possible_cpu_arch_ids) {
+error_setg(errp, "mapping of CPUs to NUMA node is not supported");
+return;
+}
+
+/* disabling node mapping is not supported, forbid it */
+assert(props->has_node_id);
+
+/* force board to initialize possible_cpus if it hasn't been done yet */
+mc->possible_cpu_arch_ids(machine);
+
+slot = >possible_cpus->cpus[index];
+slot->props.node_id = props->node_id;
+slot->props.has_node_id = props->has_node_id;
+}
+
 static void smp_parse(MachineState *ms, QemuOpts *opts)
 {
 if (opts) {
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 27fa6b5e1d..a9e835aea6 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -247,7 +247,11 @@ void set_numa_node_options(MachineState *ms, NumaOptions 
*object, Error **errp)
  props = mc->cpu_index_to_instance_props(ms, cpus->value);
  props.node_id = nodenr;
  props.has_node_id = true;
- machine_set_cpu_numa_node(ms, , );
+ if (ms->epyc) {
+ machine_set_cpu_numa_node_epyc(ms, , cpus->value, );
+ } else {
+ machine_set_cpu_numa_node(ms, , );
+ }
  if (err) {
 error_propagate(errp, err);
 return;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 0001d42e50..ec1b1c5a85 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -74,6 +74,10 @@ HotpluggableCPUList 
*machine_query_hotpluggable_cpus(MachineState *machine);
 void machine_set_cpu_numa_node(MachineState *machine,
const CpuInstanceProperties *props,
Error **errp);
+void machine_set_cpu_numa_node_epyc(MachineState *machine,
+const CpuInstanceProperties *props,
+unsigned index,
+Error **errp);
 
 void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char 
*type);
 



[Qemu-devel] [RFC 2 PATCH 11/16] Introduce-topo_ids_from_apicid-handler

2019-09-06 Thread Moger, Babu
hw/i386: Introduce topo_ids_from_apicid handler PCMachineState

Add function pointer topo_ids_from_apicid in PCMachineState.
Initialize with correct handler based on mode selected.
x86_apicid_from_cpu_idx will be the default handler.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c |   13 +++--
 include/hw/i386/pc.h |2 ++
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 69a6b82186..c88de09350 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2461,7 +2461,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 if (!cpu_slot) {
 MachineState *ms = MACHINE(pcms);
 
-x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
+pcms->topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
@@ -2482,7 +2482,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
-x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
+pcms->topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
 " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, 
topo_ids.pkg_id);
@@ -2830,6 +2830,7 @@ static void pc_machine_initfn(Object *obj)
 
 /* Initialize the apic id related handlers */
 pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx;
+pcms->topo_ids_from_apicid = x86_topo_ids_from_apicid;
 
 pc_system_flash_create(pcms);
 }
@@ -2872,8 +2873,8 @@ static int64_t pc_get_default_cpu_node_id(const 
MachineState *ms, int idx)
initialize_topo_info(_info, pcms, ms);
 
assert(idx < ms->possible_cpus->len);
-   x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
-_info, _ids);
+   pcms->topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
+  _info, _ids);
return topo_ids.pkg_id % nb_numa_nodes;
 }
 
@@ -2906,8 +2907,8 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
 ms->possible_cpus->cpus[i].type = ms->cpu_type;
 ms->possible_cpus->cpus[i].vcpus_count = 1;
 ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(pcms, 
i);
-x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
- _info, _ids);
+pcms->topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
+   _info, _ids);
 ms->possible_cpus->cpus[i].props.has_socket_id = true;
 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;
 ms->possible_cpus->cpus[i].props.has_die_id = true;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6cefefdd57..9a40f123d0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -69,6 +69,8 @@ struct PCMachineState {
 
 /* Apic id specific handlers */
 uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info, unsigned 
cpu_index);
+void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
+ X86CPUTopoIDs *topo_ids);
 
 /* Address space used by IOAPIC device. All IOAPIC interrupts
  * will be translated to MSI messages in the address space. */



[Qemu-devel] [RFC 2 PATCH 10/16] hw/i386: Introduce apicid_from_cpu_idx in PCMachineState

2019-09-06 Thread Moger, Babu
Add function pointers in PCMachineState to handle apic id specific
functionalities. This will be used to initialize with correct
handlers based on mode selected.

x86_apicid_from_cpu_idx will be default handler.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c |5 -
 include/hw/i386/pc.h |4 
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 504e1ab083..69a6b82186 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -947,7 +947,7 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 
 initialize_topo_info(_info, pcms, ms);
 
-correct_id = x86_apicid_from_cpu_idx(_info, cpu_index);
+correct_id = pcms->apicid_from_cpu_idx(_info, cpu_index);
 if (pcmc->compat_apic_id_mode) {
 if (cpu_index != correct_id && !warned && !qtest_enabled()) {
 error_report("APIC IDs set in compatibility mode, "
@@ -2828,6 +2828,9 @@ static void pc_machine_initfn(Object *obj)
 pcms->pit_enabled = true;
 pcms->smp_dies = 1;
 
+/* Initialize the apic id related handlers */
+pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx;
+
 pc_system_flash_create(pcms);
 }
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 859b64c51d..6cefefdd57 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -17,6 +17,7 @@
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/acpi/acpi_dev_interface.h"
+#include "hw/i386/topology.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
@@ -66,6 +67,9 @@ struct PCMachineState {
 uint64_t numa_nodes;
 uint64_t *node_mem;
 
+/* Apic id specific handlers */
+uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info, unsigned 
cpu_index);
+
 /* Address space used by IOAPIC device. All IOAPIC interrupts
  * will be translated to MSI messages in the address space. */
 AddressSpace *ioapic_as;



Re: [Qemu-devel] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files

2019-09-06 Thread Eric Blake
On 9/6/19 12:32 PM, Maxim Levitsky wrote:
> This fixes subltle corruption introduced by luks threaded encryption

subtle

> in commit 8ac0f15f335
> 
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922
> 
> The corruption happens when we do
>* write to two or more unallocated clusters at once
>* write doesn't fully cover nether first nor last cluster

s/nether/neither/

or even:

write doesn't fully cover either the first or the last cluster

> 
> In this case, when allocating the new clusters we COW both area

areas

> prior to the write and after the write, and we encrypt them.
> 
> The above mentioned commit accidently made it so, we encrypt the

accidentally

s/made it so, we encrypt/changed the encryption of/

> second COW are using the physical cluster offset of the first area.

s/are using/to use/

> 
> Fix this by:
>  * remove the offset_in_cluster parameter of do_perform_cow_encrypt
>since it is misleading. That offset can be larger that cluster size.
>instead just add the start and end COW are offsets to both host and guest 
> offsets
>that do_perform_cow_encrypt receives.
> 
> *  in do_perform_cow_encrypt, remove the cluster offset from the host_offset
>And thus pass correctly to the qcow2_co_encrypt, the host cluster offset 
> and full guest offset
> 
> 
> Signed-off-by: Maxim Levitsky 
> ---
>  block/qcow2-cluster.c | 26 +++---
>  1 file changed, 15 insertions(+), 11 deletions(-)
> 

> +++ b/block/qcow2-cluster.c
> @@ -463,20 +463,20 @@ static int coroutine_fn 
> do_perform_cow_read(BlockDriverState *bs,
>  }
>  
>  static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
> -uint64_t 
> guest_cluster_offset,
> -uint64_t host_cluster_offset,
> -unsigned offset_in_cluster,
> +uint64_t guest_offset,
> +uint64_t host_offset,
>  uint8_t *buffer,
>  unsigned bytes)
>  {
>  if (bytes && bs->encrypted) {
>  BDRVQcow2State *s = bs->opaque;
> -assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
> +assert((guest_offset & ~BDRV_SECTOR_MASK) == 0);
> +assert((host_offset & ~BDRV_SECTOR_MASK) == 0);
>  assert((bytes & ~BDRV_SECTOR_MASK) == 0);

Pre-existing, but we could use QEMU_IS_ALIGNED(x, BDRV_SECTOR_SIZE) for
slightly more legibility than open-coding the bit operation.

Neat trick about power-of-2 alignment checks:

assert(QEMU_IS_ALIGNED(offset_in_cluster | guest_offset |
   host_offset | bytes, BDRV_SECTOR_SIZE));

gives the same result in one assertion.  (I've used it elsewhere in the
code base, but I'm not opposed to one assert per variable if you think
batching is too dense.)

I'll let Dan review the actual code change, but offhand it makes sense
to me.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [RFC 2 PATCH 09/16] hw/i386: Introduce initialize_topo_info function

2019-09-06 Thread Moger, Babu
Introduce initialize_topo_info to initialize X86CPUTopoInfo
data structure to build the topology. No functional change.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c |   29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f71389ad9f..504e1ab083 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -918,6 +918,17 @@ bool e820_get_entry(int idx, uint32_t type, uint64_t 
*address, uint64_t *length)
 return false;
 }
 
+static inline void initialize_topo_info(X86CPUTopoInfo *topo_info,
+PCMachineState *pcms,
+const MachineState *ms)
+{
+topo_info->nr_dies = pcms->smp_dies;
+topo_info->nr_cores = ms->smp.cores;
+topo_info->nr_threads = ms->smp.threads;
+topo_info->nr_sockets = ms->smp.sockets;
+topo_info->numa_nodes = nb_numa_nodes;
+}
+
 /* Calculates initial APIC ID for a specific CPU index
  *
  * Currently we need to be able to calculate the APIC ID from the CPU index
@@ -934,9 +945,7 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 uint32_t correct_id;
 static bool warned;
 
-topo_info.nr_dies = pcms->smp_dies;
-topo_info.nr_cores = ms->smp.cores;
-topo_info.nr_threads = ms->smp.threads;
+initialize_topo_info(_info, pcms, ms);
 
 correct_id = x86_apicid_from_cpu_idx(_info, cpu_index);
 if (pcmc->compat_apic_id_mode) {
@@ -2399,9 +2408,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 }
 
-topo_info.nr_dies = pcms->smp_dies;
-topo_info.nr_cores = smp_cores;
-topo_info.nr_threads = smp_threads;
+initialize_topo_info(_info, pcms, ms);
 
 env->nr_dies = pcms->smp_dies;
 
@@ -2859,9 +2866,7 @@ static int64_t pc_get_default_cpu_node_id(const 
MachineState *ms, int idx)
PCMachineState *pcms = PC_MACHINE(ms);
X86CPUTopoInfo topo_info;
 
-   topo_info.nr_dies = pcms->smp_dies;
-   topo_info.nr_cores = ms->smp.cores;
-   topo_info.nr_threads = ms->smp.threads;
+   initialize_topo_info(_info, pcms, ms);
 
assert(idx < ms->possible_cpus->len);
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
@@ -2876,9 +2881,6 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
 X86CPUTopoInfo topo_info;
 int i;
 
-topo_info.nr_dies = pcms->smp_dies;
-topo_info.nr_cores = ms->smp.cores;
-topo_info.nr_threads = ms->smp.threads;
 
 if (ms->possible_cpus) {
 /*
@@ -2891,6 +2893,9 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
 
 ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
   sizeof(CPUArchId) * max_cpus);
+
+initialize_topo_info(_info, pcms, ms);
+
 ms->possible_cpus->len = max_cpus;
 for (i = 0; i < ms->possible_cpus->len; i++) {
 X86CPUTopoIDs topo_ids;



[Qemu-devel] [RFC 2 PATCH 08/16] i386: Cleanup and use the new epyc mode topology functions

2019-09-06 Thread Moger, Babu
Use the new epyc mode functions and delete the unused code.

Signed-off-by: Babu Moger 
---
 target/i386/cpu.c |  171 +++--
 1 file changed, 48 insertions(+), 123 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ca02bc21ec..f25491a029 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -28,6 +28,7 @@
 #include "sysemu/kvm.h"
 #include "sysemu/hvf.h"
 #include "sysemu/cpus.h"
+#include "sysemu/numa.h"
 #include "kvm_i386.h"
 #include "sev_i386.h"
 
@@ -338,67 +339,19 @@ static void encode_cache_cpuid8006(CPUCacheInfo *l2,
 }
 }
 
-/*
- * Definitions used for building CPUID Leaf 0x801D and 0x801E
- * Please refer to the AMD64 Architecture Programmer’s Manual Volume 3.
- * Define the constants to build the cpu topology. Right now, TOPOEXT
- * feature is enabled only on EPYC. So, these constants are based on
- * EPYC supported configurations. We may need to handle the cases if
- * these values change in future.
- */
-/* Maximum core complexes in a node */
-#define MAX_CCX 2
-/* Maximum cores in a core complex */
-#define MAX_CORES_IN_CCX 4
-/* Maximum cores in a node */
-#define MAX_CORES_IN_NODE 8
-/* Maximum nodes in a socket */
-#define MAX_NODES_PER_SOCKET 4
-
-/*
- * Figure out the number of nodes required to build this config.
- * Max cores in a node is 8
- */
-static int nodes_in_socket(int nr_cores)
-{
-int nodes;
-
-nodes = DIV_ROUND_UP(nr_cores, MAX_CORES_IN_NODE);
-
-   /* Hardware does not support config with 3 nodes, return 4 in that case */
-return (nodes == 3) ? 4 : nodes;
-}
-
-/*
- * Decide the number of cores in a core complex with the given nr_cores using
- * following set constants MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE and
- * MAX_NODES_PER_SOCKET. Maintain symmetry as much as possible
- * L3 cache is shared across all cores in a core complex. So, this will also
- * tell us how many cores are sharing the L3 cache.
- */
-static int cores_in_core_complex(int nr_cores)
-{
-int nodes;
-
-/* Check if we can fit all the cores in one core complex */
-if (nr_cores <= MAX_CORES_IN_CCX) {
-return nr_cores;
-}
-/* Get the number of nodes required to build this config */
-nodes = nodes_in_socket(nr_cores);
-
-/*
- * Divide the cores accros all the core complexes
- * Return rounded up value
- */
-return DIV_ROUND_UP(nr_cores, nodes * MAX_CCX);
-}
-
 /* Encode cache info for CPUID[801D] */
-static void encode_cache_cpuid801d(CPUCacheInfo *cache, CPUState *cs,
-uint32_t *eax, uint32_t *ebx,
-uint32_t *ecx, uint32_t *edx)
+static void encode_cache_cpuid801d(CPUCacheInfo *cache,
+   uint32_t *eax, uint32_t *ebx,
+   uint32_t *ecx, uint32_t *edx)
 {
+MachineState *ms = MACHINE(qdev_get_machine());
+X86CPUTopoInfo topo_info = {
+.numa_nodes = nb_numa_nodes,
+.nr_sockets = ms->smp.sockets,
+.nr_cores = ms->smp.cores,
+.nr_threads = ms->smp.threads,
+};
+
 uint32_t l3_cores;
 assert(cache->size == cache->line_size * cache->associativity *
   cache->partitions * cache->sets);
@@ -408,10 +361,10 @@ static void encode_cache_cpuid801d(CPUCacheInfo 
*cache, CPUState *cs,
 
 /* L3 is shared among multiple cores */
 if (cache->level == 3) {
-l3_cores = cores_in_core_complex(cs->nr_cores);
-*eax |= ((l3_cores * cs->nr_threads) - 1) << 14;
+l3_cores = cores_in_ccx(_info);
+*eax |= ((l3_cores * topo_info.nr_threads) - 1) << 14;
 } else {
-*eax |= ((cs->nr_threads - 1) << 14);
+*eax |= ((topo_info.nr_threads - 1) << 14);
 }
 
 assert(cache->line_size > 0);
@@ -431,56 +384,28 @@ static void encode_cache_cpuid801d(CPUCacheInfo 
*cache, CPUState *cs,
(cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
 }
 
-/* Data structure to hold the configuration info for a given core index */
-struct core_topology {
-/* core complex id of the current core index */
-int ccx_id;
-/*
- * Adjusted core index for this core in the topology
- * This can be 0,1,2,3 with max 4 cores in a core complex
- */
-int core_id;
-/* Node id for this core index */
-int node_id;
-/* Number of nodes in this config */
-int num_nodes;
-};
-
-/*
- * Build the configuration closely match the EPYC hardware. Using the EPYC
- * hardware configuration values (MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_NODE)
- * right now. This could change in future.
- * nr_cores : Total number of cores in the config
- * core_id  : Core index of the current CPU
- * topo : Data structure to hold all the config info for this core index
- */
-static void build_core_topology(int nr_cores, int core_id,
-struct core_topology *topo)
-{
-int 

[Qemu-devel] [RFC 2 PATCH 06/16] hw/core: Add core complex id in X86CPU topology

2019-09-06 Thread Moger, Babu
Introduce cpu core complex id(ccx_id) in x86CPU topology.
Each CCX can have upto 4 cores and share same L3 cache.
This information is required to build the topology in
new apyc mode.

Signed-off-by: Babu Moger 
---
 hw/core/machine-hmp-cmds.c |3 +++
 hw/core/machine.c  |   13 +
 hw/i386/pc.c   |   10 ++
 include/hw/i386/topology.h |1 +
 qapi/machine.json  |4 +++-
 target/i386/cpu.c  |2 ++
 target/i386/cpu.h  |1 +
 7 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 1f66bda346..6c534779af 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -89,6 +89,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
 if (c->has_die_id) {
 monitor_printf(mon, "die-id: \"%" PRIu64 "\"\n", c->die_id);
 }
+if (c->has_ccx_id) {
+monitor_printf(mon, "ccx-id: \"%" PRIu64 "\"\n", c->ccx_id);
+}
 if (c->has_core_id) {
 monitor_printf(mon, "core-id: \"%" PRIu64 "\"\n", c->core_id);
 }
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 4034b7e903..9a8586cf30 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -694,6 +694,11 @@ void machine_set_cpu_numa_node(MachineState *machine,
 return;
 }
 
+if (props->has_ccx_id && !slot->props.has_ccx_id) {
+error_setg(errp, "ccx-id is not supported");
+return;
+}
+
 /* skip slots with explicit mismatch */
 if (props->has_thread_id && props->thread_id != slot->props.thread_id) 
{
 continue;
@@ -707,6 +712,10 @@ void machine_set_cpu_numa_node(MachineState *machine,
 continue;
 }
 
+if (props->has_ccx_id && props->ccx_id != slot->props.ccx_id) {
+continue;
+}
+
 if (props->has_socket_id && props->socket_id != slot->props.socket_id) 
{
 continue;
 }
@@ -1041,6 +1050,10 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
 if (cpu->props.has_die_id) {
 g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
 }
+
+if (cpu->props.has_ccx_id) {
+g_string_append_printf(s, "ccx-id: %"PRId64, cpu->props.ccx_id);
+}
 if (cpu->props.has_core_id) {
 if (s->len) {
 g_string_append_printf(s, ", ");
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9e1c3f9f57..f71389ad9f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2444,6 +2444,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 
 topo_ids.pkg_id = cpu->socket_id;
 topo_ids.die_id = cpu->die_id;
+topo_ids.ccx_id = cpu->ccx_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
 cpu->apic_id = apicid_from_topo_ids(_info, _ids);
@@ -2489,6 +2490,13 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 }
 cpu->die_id = topo_ids.die_id;
 
+if (cpu->ccx_id != -1 && cpu->ccx_id != topo_ids.ccx_id) {
+error_setg(errp, "property ccx-id: %u doesn't match set apic-id:"
+" 0x%x (ccx-id: %u)", cpu->ccx_id, cpu->apic_id, topo_ids.ccx_id);
+return;
+}
+cpu->ccx_id = topo_ids.ccx_id;
+
 if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) {
 error_setg(errp, "property core-id: %u doesn't match set apic-id:"
 " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, 
topo_ids.core_id);
@@ -2896,6 +2904,8 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;
 ms->possible_cpus->cpus[i].props.has_die_id = true;
 ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id;
+ms->possible_cpus->cpus[i].props.has_ccx_id = true;
+ms->possible_cpus->cpus[i].props.ccx_id = topo_ids.ccx_id;
 ms->possible_cpus->cpus[i].props.has_core_id = true;
 ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id;
 ms->possible_cpus->cpus[i].props.has_thread_id = true;
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index fb10863a66..5a61d53f05 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -170,6 +170,7 @@ static inline void x86_topo_ids_from_apicid(apic_id_t 
apicid,
 (apicid >> apicid_die_offset(nr_cores, nr_threads)) &
 ~(0xUL << apicid_die_width(nr_dies));
 topo_ids->pkg_id = apicid >> apicid_pkg_offset(nr_dies, nr_cores, 
nr_threads);
+topo_ids->ccx_id = 0;
 }
 
 /* Make APIC ID for the CPU 'cpu_index'
diff --git a/qapi/machine.json b/qapi/machine.json
index 6db8a7e2ec..bb7627e698 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -597,9 +597,10 @@
 # @node-id: NUMA node ID the CPU belongs to
 # @socket-id: socket number within node/board the CPU belongs 

[Qemu-devel] [RFC 2 PATCH 12/16] hw/i386: Introduce apic_id_from_topo_ids handler in PCMachineState

2019-09-06 Thread Moger, Babu
Add function pointer apic_id_from_topo_ids in PCMachineState.
Initialize with correct handler based on the mode selected.
Also rename the handler apicid_from_topo_ids to x86_apicid_from_topo_ids
for  consistency. x86_apicid_from_topo_ids will be the default handler.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |3 ++-
 include/hw/i386/pc.h   |2 ++
 include/hw/i386/topology.h |4 ++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c88de09350..959bd3821b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2454,7 +2454,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 topo_ids.ccx_id = cpu->ccx_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
-cpu->apic_id = apicid_from_topo_ids(_info, _ids);
+cpu->apic_id = pcms->apicid_from_topo_ids(_info, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
@@ -2831,6 +2831,7 @@ static void pc_machine_initfn(Object *obj)
 /* Initialize the apic id related handlers */
 pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx;
 pcms->topo_ids_from_apicid = x86_topo_ids_from_apicid;
+pcms->apicid_from_topo_ids = x86_apicid_from_topo_ids;
 
 pc_system_flash_create(pcms);
 }
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9a40f123d0..d6f1189997 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -71,6 +71,8 @@ struct PCMachineState {
 uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info, unsigned 
cpu_index);
 void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
  X86CPUTopoIDs *topo_ids);
+apic_id_t (*apicid_from_topo_ids)(X86CPUTopoInfo *topo_info,
+  const X86CPUTopoIDs *topo_ids);
 
 /* Address space used by IOAPIC device. All IOAPIC interrupts
  * will be translated to MSI messages in the address space. */
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 6fd4184f07..740e66970d 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -294,7 +294,7 @@ static inline apic_id_t 
x86_apicid_from_cpu_idx_epyc(X86CPUTopoInfo *topo_info,
  *
  * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
  */
-static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
+static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
  const X86CPUTopoIDs *topo_ids)
 {
 unsigned nr_dies = topo_info->nr_dies;
@@ -356,7 +356,7 @@ static inline apic_id_t 
x86_apicid_from_cpu_idx(X86CPUTopoInfo *topo_info,
 {
 X86CPUTopoIDs topo_ids;
 x86_topo_ids_from_idx(topo_info, cpu_index, _ids);
-return apicid_from_topo_ids(topo_info, _ids);
+return x86_apicid_from_topo_ids(topo_info, _ids);
 }
 
 #endif /* HW_I386_TOPOLOGY_H */



[Qemu-devel] [RFC 2 PATCH 05/16] hw/i386: Simplify topology Offset/width Calculation

2019-09-06 Thread Moger, Babu
Some parameters are unnecessarily passed for offset/width
calculation. Remove those parameters from function prototypes.
No functional change.

Signed-off-by: Babu Moger 
---
 include/hw/i386/topology.h |   45 ++--
 target/i386/cpu.c  |   12 
 2 files changed, 22 insertions(+), 35 deletions(-)

diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 906017e8e3..fb10863a66 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -73,46 +73,37 @@ static unsigned apicid_bitwidth_for_count(unsigned count)
 
 /* Bit width of the SMT_ID (thread ID) field on the APIC ID
  */
-static inline unsigned apicid_smt_width(unsigned nr_dies,
-unsigned nr_cores,
-unsigned nr_threads)
+static inline unsigned apicid_smt_width(unsigned nr_threads)
 {
 return apicid_bitwidth_for_count(nr_threads);
 }
 
 /* Bit width of the Core_ID field
  */
-static inline unsigned apicid_core_width(unsigned nr_dies,
- unsigned nr_cores,
- unsigned nr_threads)
+static inline unsigned apicid_core_width(unsigned nr_cores)
 {
 return apicid_bitwidth_for_count(nr_cores);
 }
 
 /* Bit width of the Die_ID field */
-static inline unsigned apicid_die_width(unsigned nr_dies,
-unsigned nr_cores,
-unsigned nr_threads)
+static inline unsigned apicid_die_width(unsigned nr_dies)
 {
 return apicid_bitwidth_for_count(nr_dies);
 }
 
 /* Bit offset of the Core_ID field
  */
-static inline unsigned apicid_core_offset(unsigned nr_dies,
-  unsigned nr_cores,
-  unsigned nr_threads)
+static inline unsigned apicid_core_offset(unsigned nr_threads)
 {
-return apicid_smt_width(nr_dies, nr_cores, nr_threads);
+return apicid_smt_width(nr_threads);
 }
 
 /* Bit offset of the Die_ID field */
-static inline unsigned apicid_die_offset(unsigned nr_dies,
-  unsigned nr_cores,
-   unsigned nr_threads)
+static inline unsigned apicid_die_offset(unsigned nr_cores,
+ unsigned nr_threads)
 {
-return apicid_core_offset(nr_dies, nr_cores, nr_threads) +
-   apicid_core_width(nr_dies, nr_cores, nr_threads);
+return apicid_core_offset(nr_threads) +
+   apicid_core_width(nr_cores);
 }
 
 /* Bit offset of the Pkg_ID (socket ID) field
@@ -121,8 +112,8 @@ static inline unsigned apicid_pkg_offset(unsigned nr_dies,
  unsigned nr_cores,
  unsigned nr_threads)
 {
-return apicid_die_offset(nr_dies, nr_cores, nr_threads) +
-   apicid_die_width(nr_dies, nr_cores, nr_threads);
+return apicid_die_offset(nr_cores, nr_threads) +
+   apicid_die_width(nr_dies);
 }
 
 /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
@@ -137,8 +128,8 @@ static inline apic_id_t apicid_from_topo_ids(X86CPUTopoInfo 
*topo_info,
 unsigned nr_threads = topo_info->nr_threads;
 
 return (topo_ids->pkg_id  << apicid_pkg_offset(nr_dies, nr_cores, 
nr_threads)) |
-   (topo_ids->die_id  << apicid_die_offset(nr_dies, nr_cores, 
nr_threads)) |
-   (topo_ids->core_id << apicid_core_offset(nr_dies, nr_cores, 
nr_threads)) |
+   (topo_ids->die_id  << apicid_die_offset(nr_cores, nr_threads)) |
+   (topo_ids->core_id << apicid_core_offset(nr_threads)) |
topo_ids->smt_id;
 }
 
@@ -171,13 +162,13 @@ static inline void x86_topo_ids_from_apicid(apic_id_t 
apicid,
 unsigned nr_threads = topo_info->nr_threads;
 
 topo_ids->smt_id = apicid &
-~(0xUL << apicid_smt_width(nr_dies, nr_cores, nr_threads));
+~(0xUL << apicid_smt_width(nr_threads));
 topo_ids->core_id =
-(apicid >> apicid_core_offset(nr_dies, nr_cores, nr_threads)) &
-~(0xUL << apicid_core_width(nr_dies, nr_cores, 
nr_threads));
+(apicid >> apicid_core_offset(nr_threads)) &
+~(0xUL << apicid_core_width(nr_cores));
 topo_ids->die_id =
-(apicid >> apicid_die_offset(nr_dies, nr_cores, nr_threads)) &
-~(0xUL << apicid_die_width(nr_dies, nr_cores, nr_threads));
+(apicid >> apicid_die_offset(nr_cores, nr_threads)) &
+~(0xUL << apicid_die_width(nr_dies));
 topo_ids->pkg_id = apicid >> apicid_pkg_offset(nr_dies, nr_cores, 
nr_threads);
 }
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 19751e37a7..6d7f9b6b8b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4260,8 +4260,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,

[Qemu-devel] [RFC 2 PATCH 03/16] hw/i386: Introduce X86CPUTopoInfo to contain topology info

2019-09-06 Thread Moger, Babu
This is an effort to re-arrange few data structure for better
readability. Add X86CPUTopoInfo which will have all the topology
informations required to build the cpu topology. There is no
functional changes.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |   40 +++-
 include/hw/i386/topology.h |   40 ++--
 2 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ada445f8f3..95aab8e5e7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -930,11 +930,15 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 {
 MachineState *ms = MACHINE(pcms);
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+X86CPUTopoInfo topo_info;
 uint32_t correct_id;
 static bool warned;
 
-correct_id = x86_apicid_from_cpu_idx(pcms->smp_dies, ms->smp.cores,
- ms->smp.threads, cpu_index);
+topo_info.nr_dies = pcms->smp_dies;
+topo_info.nr_cores = ms->smp.cores;
+topo_info.nr_threads = ms->smp.threads;
+
+correct_id = x86_apicid_from_cpu_idx(_info, cpu_index);
 if (pcmc->compat_apic_id_mode) {
 if (cpu_index != correct_id && !warned && !qtest_enabled()) {
 error_report("APIC IDs set in compatibility mode, "
@@ -2386,6 +2390,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 PCMachineState *pcms = PC_MACHINE(hotplug_dev);
 unsigned int smp_cores = ms->smp.cores;
 unsigned int smp_threads = ms->smp.threads;
+X86CPUTopoInfo topo_info;
 
 if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
 error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
@@ -2393,6 +2398,10 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 }
 
+topo_info.nr_dies = pcms->smp_dies;
+topo_info.nr_cores = smp_cores;
+topo_info.nr_threads = smp_threads;
+
 env->nr_dies = pcms->smp_dies;
 
 /*
@@ -2436,16 +2445,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 topo_ids.die_id = cpu->die_id;
 topo_ids.core_id = cpu->core_id;
 topo_ids.smt_id = cpu->thread_id;
-cpu->apic_id = apicid_from_topo_ids(pcms->smp_dies, smp_cores,
-smp_threads, _ids);
+cpu->apic_id = apicid_from_topo_ids(_info, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
 if (!cpu_slot) {
 MachineState *ms = MACHINE(pcms);
 
-x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
- smp_cores, smp_threads, _ids);
+x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
@@ -2466,8 +2473,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
-x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
- smp_cores, smp_threads, _ids);
+x86_topo_ids_from_apicid(cpu->apic_id, _info, _ids);
 if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
 " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, 
topo_ids.pkg_id);
@@ -2842,19 +2848,28 @@ static int64_t pc_get_default_cpu_node_id(const 
MachineState *ms, int idx)
 {
X86CPUTopoIDs topo_ids;
PCMachineState *pcms = PC_MACHINE(ms);
+   X86CPUTopoInfo topo_info;
+
+   topo_info.nr_dies = pcms->smp_dies;
+   topo_info.nr_cores = ms->smp.cores;
+   topo_info.nr_threads = ms->smp.threads;
 
assert(idx < ms->possible_cpus->len);
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
-pcms->smp_dies, ms->smp.cores,
-ms->smp.threads, _ids);
+_info, _ids);
return topo_ids.pkg_id % nb_numa_nodes;
 }
 
 static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
 {
 PCMachineState *pcms = PC_MACHINE(ms);
-int i;
 unsigned int max_cpus = ms->smp.max_cpus;
+X86CPUTopoInfo topo_info;
+int i;
+
+topo_info.nr_dies = pcms->smp_dies;
+topo_info.nr_cores = ms->smp.cores;
+topo_info.nr_threads = ms->smp.threads;
 
 if (ms->possible_cpus) {
 /*
@@ -2875,8 +2890,7 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
 ms->possible_cpus->cpus[i].vcpus_count = 1;
 ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(pcms, 
i);
 x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
- 

[Qemu-devel] [RFC 2 PATCH 07/16] hw/386: Add new epyc mode topology decoding functions

2019-09-06 Thread Moger, Babu
These functions add support for building new epyc mode topology
given smp details like numa nodes, cores, threads and sockets.
Subsequent patches will use these functions to build the topology.

The topology details are available in Processor Programming Reference (PPR)
for AMD Family 17h Model 01h, Revision B1 Processors.
It is available at https://www.amd.com/en/support/tech-docs

Signed-off-by: Babu Moger 
---
 include/hw/i386/topology.h |  174 
 1 file changed, 174 insertions(+)

diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 5a61d53f05..6fd4184f07 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -62,6 +62,22 @@ typedef struct X86CPUTopoInfo {
 unsigned nr_threads;
 } X86CPUTopoInfo;
 
+/*
+ * Definitions used for building CPUID Leaf 0x801D and 0x801E
+ * Please refer to the AMD64 Architecture Programmer’s Manual Volume 3.
+ * Define the constants to build the cpu topology. Right now, TOPOEXT
+ * feature is enabled only on EPYC. So, these constants are based on
+ * EPYC supported configurations. We may need to handle the cases if
+ * these values change in future.
+ */
+
+/* Maximum core complexes in a node */
+#define MAX_CCX  2
+/* Maximum cores in a core complex */
+#define MAX_CORES_IN_CCX 4
+/* Maximum cores in a node */
+#define MAX_CORES_IN_NODE8
+
 /* Return the bit width needed for 'count' IDs
  */
 static unsigned apicid_bitwidth_for_count(unsigned count)
@@ -116,6 +132,164 @@ static inline unsigned apicid_pkg_offset(unsigned nr_dies,
apicid_die_width(nr_dies);
 }
 
+/* Bit offset of the CCX_ID field */
+static inline unsigned apicid_ccx_offset(unsigned nr_cores,
+ unsigned nr_threads)
+{
+return apicid_core_offset(nr_threads) +
+   apicid_core_width(nr_cores);
+}
+
+/* Bit width of the Die_ID field */
+static inline unsigned apicid_ccx_width(unsigned nr_ccxs)
+{
+return apicid_bitwidth_for_count(nr_ccxs);
+}
+
+/* Bit offset of the node_id field */
+static inline unsigned apicid_node_offset(unsigned nr_ccxs,
+  unsigned nr_cores,
+  unsigned nr_threads)
+{
+return apicid_ccx_offset(nr_cores, nr_threads) +
+   apicid_ccx_width(nr_ccxs);
+}
+
+/* Bit width of the node_id field */
+static inline unsigned apicid_node_width(unsigned nr_nodes)
+{
+return apicid_bitwidth_for_count(nr_nodes);
+}
+
+/* Bit offset of the node_id field */
+static inline unsigned apicid_pkg_offset_epyc(unsigned nr_nodes,
+  unsigned nr_ccxs,
+  unsigned nr_cores,
+  unsigned nr_threads)
+{
+return apicid_node_offset(nr_ccxs, nr_cores, nr_threads) +
+   apicid_node_width(nr_nodes);
+}
+
+/*
+ * Figure out the number of nodes required to build this config.
+ * Max cores in a nodes is 8
+ */
+static inline int nodes_in_pkg(X86CPUTopoInfo *topo_info)
+{
+/*
+ * Create a config with user given (nr_nodes > 1) numa node config,
+ * else go with a standard configuration
+ */
+if (topo_info->numa_nodes > 1) {
+return DIV_ROUND_UP(topo_info->numa_nodes, topo_info->nr_sockets);
+} else {
+return DIV_ROUND_UP(topo_info->nr_cores, MAX_CORES_IN_NODE);
+}
+}
+
+/*
+ * Decide the number of cores in a core complex with the given nr_cores using
+ * following set constants MAX_CCX, MAX_CORES_IN_CCX, MAX_CORES_IN_DIE and
+ * MAX_NODES_PER_SOCKET. Maintain symmetry as much as possible
+ * L3 cache is shared across all cores in a core complex. So, this will also
+ * tell us how many cores are sharing the L3 cache.
+ */
+static inline int cores_in_ccx(X86CPUTopoInfo *topo_info)
+{
+int nodes;
+
+/* Get the number of nodes required to build this config */
+nodes = nodes_in_pkg(topo_info);
+
+/*
+ * Divide the cores accros all the core complexes
+ * Return rounded up value
+ */
+return DIV_ROUND_UP(topo_info->nr_cores, nodes * MAX_CCX);
+}
+
+/*
+ * Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
+ *
+ * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
+ */
+static inline apic_id_t x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo 
*topo_info,
+  const X86CPUTopoIDs 
*topo_ids)
+{
+unsigned nr_ccxs = MAX_CCX;
+unsigned nr_nodes = nodes_in_pkg(topo_info);
+unsigned nr_cores = MAX_CORES_IN_CCX;
+unsigned nr_threads = topo_info->nr_threads;
+
+return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(nr_nodes, nr_ccxs,
+nr_cores, nr_threads)) 
|
+   (topo_ids->node_id  << apicid_node_offset(nr_ccxs, nr_cores,
+ nr_threads)) |
+   

[Qemu-devel] [RFC 2 PATCH 04/16] machine: Add SMP Sockets in CpuTopology

2019-09-06 Thread Moger, Babu
Store the  smp Sockets in CpuTopology. Socket information
is required to build the cpu topology in new epyc mode.

Signed-off-by: Babu Moger 
---
 hw/core/machine.c   |1 +
 hw/i386/pc.c|1 +
 include/hw/boards.h |2 ++
 vl.c|1 +
 4 files changed, 5 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index c58a8e594e..4034b7e903 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -795,6 +795,7 @@ static void smp_parse(MachineState *ms, QemuOpts *opts)
 ms->smp.cpus = cpus;
 ms->smp.cores = cores;
 ms->smp.threads = threads;
+ms->smp.sockets = sockets;
 }
 
 if (ms->smp.cpus > 1) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 95aab8e5e7..9e1c3f9f57 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1609,6 +1609,7 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
 ms->smp.cpus = cpus;
 ms->smp.cores = cores;
 ms->smp.threads = threads;
+ms->smp.sockets = sockets;
 pcms->smp_dies = dies;
 }
 
diff --git a/include/hw/boards.h b/include/hw/boards.h
index a71d1a53a5..12eb5032a5 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -245,12 +245,14 @@ typedef struct DeviceMemoryState {
  * @cpus: the number of present logical processors on the machine
  * @cores: the number of cores in one package
  * @threads: the number of threads in one core
+ * @sockets: the number of sockets on the machine
  * @max_cpus: the maximum number of logical processors on the machine
  */
 typedef struct CpuTopology {
 unsigned int cpus;
 unsigned int cores;
 unsigned int threads;
+unsigned int sockets;
 unsigned int max_cpus;
 } CpuTopology;
 
diff --git a/vl.c b/vl.c
index 711d2ae5da..473a688779 100644
--- a/vl.c
+++ b/vl.c
@@ -3981,6 +3981,7 @@ int main(int argc, char **argv, char **envp)
 current_machine->smp.max_cpus = machine_class->default_cpus;
 current_machine->smp.cores = 1;
 current_machine->smp.threads = 1;
+current_machine->smp.sockets = 1;
 
 machine_class->smp_parse(current_machine,
 qemu_opts_find(qemu_find_opts("smp-opts"), NULL));



[Qemu-devel] [RFC 2 PATCH 02/16] hw/i386: Rename X86CPUTopoInfo structure to X86CPUTopoIDs

2019-09-06 Thread Moger, Babu
Rename few data structures related to X86 topology.
X86CPUTopoIDs will have individual arch ids. Next
patch introduces X86CPUTopoInfo which will have all
topology information(like cores, threads etc..).

Adds node_id and ccx_id. This will be required to support
new epyc mode mode. There is no functional change.

Signed-off-by: Babu Moger 
---
 hw/i386/pc.c   |   60 ++--
 include/hw/i386/topology.h |   42 ---
 2 files changed, 52 insertions(+), 50 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 549c437050..ada445f8f3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2379,7 +2379,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 int idx;
 CPUState *cs;
 CPUArchId *cpu_slot;
-X86CPUTopoInfo topo;
+X86CPUTopoIDs topo_ids;
 X86CPU *cpu = X86_CPU(dev);
 CPUX86State *env = >env;
 MachineState *ms = MACHINE(hotplug_dev);
@@ -2432,12 +2432,12 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 }
 
-topo.pkg_id = cpu->socket_id;
-topo.die_id = cpu->die_id;
-topo.core_id = cpu->core_id;
-topo.smt_id = cpu->thread_id;
+topo_ids.pkg_id = cpu->socket_id;
+topo_ids.die_id = cpu->die_id;
+topo_ids.core_id = cpu->core_id;
+topo_ids.smt_id = cpu->thread_id;
 cpu->apic_id = apicid_from_topo_ids(pcms->smp_dies, smp_cores,
-smp_threads, );
+smp_threads, _ids);
 }
 
 cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, );
@@ -2445,11 +2445,11 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 MachineState *ms = MACHINE(pcms);
 
 x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
- smp_cores, smp_threads, );
+ smp_cores, smp_threads, _ids);
 error_setg(errp,
 "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
 " APIC ID %" PRIu32 ", valid index range 0:%d",
-topo.pkg_id, topo.die_id, topo.core_id, topo.smt_id,
+topo_ids.pkg_id, topo_ids.die_id, topo_ids.core_id, 
topo_ids.smt_id,
 cpu->apic_id, ms->possible_cpus->len - 1);
 return;
 }
@@ -2467,34 +2467,34 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
  * once -smp refactoring is complete and there will be CPU private
  * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
 x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
- smp_cores, smp_threads, );
-if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
+ smp_cores, smp_threads, _ids);
+if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
 error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
-" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, 
topo.pkg_id);
+" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, 
topo_ids.pkg_id);
 return;
 }
-cpu->socket_id = topo.pkg_id;
+cpu->socket_id = topo_ids.pkg_id;
 
-if (cpu->die_id != -1 && cpu->die_id != topo.die_id) {
+if (cpu->die_id != -1 && cpu->die_id != topo_ids.die_id) {
 error_setg(errp, "property die-id: %u doesn't match set apic-id:"
-" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo.die_id);
+" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo_ids.die_id);
 return;
 }
-cpu->die_id = topo.die_id;
+cpu->die_id = topo_ids.die_id;
 
-if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
+if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) {
 error_setg(errp, "property core-id: %u doesn't match set apic-id:"
-" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);
+" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, 
topo_ids.core_id);
 return;
 }
-cpu->core_id = topo.core_id;
+cpu->core_id = topo_ids.core_id;
 
-if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
+if (cpu->thread_id != -1 && cpu->thread_id != topo_ids.smt_id) {
 error_setg(errp, "property thread-id: %u doesn't match set apic-id:"
-" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, 
topo.smt_id);
+" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, 
topo_ids.smt_id);
 return;
 }
-cpu->thread_id = topo.smt_id;
+cpu->thread_id = topo_ids.smt_id;
 
 if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) &&
 !kvm_hv_vpindex_settable()) {
@@ -2840,14 +2840,14 @@ pc_cpu_index_to_props(MachineState *ms, unsigned 
cpu_index)
 
 static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx)
 {
-   X86CPUTopoInfo topo;
+   X86CPUTopoIDs topo_ids;

[Qemu-devel] [RFC 2 PATCH 01/16] numa: Split the numa functionality

2019-09-06 Thread Moger, Babu
To support new epyc mode, we need to know the number of numa nodes
in advance to generate apic id correctly. So, split the numa
initialization into two. The function parse_numa initializes numa_info
and updates nb_numa_nodes. And then parse_numa_node does the numa node
initialization.

Signed-off-by: Babu Moger 
---
 hw/core/numa.c|  106 +++--
 include/sysemu/numa.h |2 +
 vl.c  |2 +
 3 files changed, 80 insertions(+), 30 deletions(-)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index a11431483c..27fa6b5e1d 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -55,14 +55,10 @@ bool have_numa_distance;
 NodeInfo numa_info[MAX_NODES];
 
 
-static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
+static void parse_numa_info(MachineState *ms, NumaNodeOptions *node,
 Error **errp)
 {
-Error *err = NULL;
 uint16_t nodenr;
-uint16List *cpus = NULL;
-MachineClass *mc = MACHINE_GET_CLASS(ms);
-unsigned int max_cpus = ms->smp.max_cpus;
 
 if (node->has_nodeid) {
 nodenr = node->nodeid;
@@ -81,29 +77,6 @@ static void parse_numa_node(MachineState *ms, 
NumaNodeOptions *node,
 return;
 }
 
-if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
-error_setg(errp, "NUMA is not supported by this machine-type");
-return;
-}
-for (cpus = node->cpus; cpus; cpus = cpus->next) {
-CpuInstanceProperties props;
-if (cpus->value >= max_cpus) {
-error_setg(errp,
-   "CPU index (%" PRIu16 ")"
-   " should be smaller than maxcpus (%d)",
-   cpus->value, max_cpus);
-return;
-}
-props = mc->cpu_index_to_instance_props(ms, cpus->value);
-props.node_id = nodenr;
-props.has_node_id = true;
-machine_set_cpu_numa_node(ms, , );
-if (err) {
-error_propagate(errp, err);
-return;
-}
-}
-
 have_memdevs = have_memdevs ? : node->has_memdev;
 have_mem = have_mem ? : node->has_mem;
 if ((node->has_mem && have_memdevs) || (node->has_memdev && have_mem)) {
@@ -177,7 +150,7 @@ void set_numa_options(MachineState *ms, NumaOptions 
*object, Error **errp)
 
 switch (object->type) {
 case NUMA_OPTIONS_TYPE_NODE:
-parse_numa_node(ms, >u.node, );
+parse_numa_info(ms, >u.node, );
 if (err) {
 goto end;
 }
@@ -242,6 +215,73 @@ end:
 return 0;
 }
 
+void set_numa_node_options(MachineState *ms, NumaOptions *object, Error **errp)
+{
+MachineClass *mc = MACHINE_GET_CLASS(ms);
+NumaNodeOptions *node = >u.node;
+unsigned int max_cpus = ms->smp.max_cpus;
+uint16List *cpus = NULL;
+Error *err = NULL;
+uint16_t nodenr;
+
+if (node->has_nodeid) {
+nodenr = node->nodeid;
+} else {
+error_setg(errp, "NUMA node information is not available");
+}
+
+if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
+error_setg(errp, "NUMA is not supported by this machine-type");
+return;
+}
+
+for (cpus = node->cpus; cpus; cpus = cpus->next) {
+CpuInstanceProperties props;
+if (cpus->value >= max_cpus) {
+error_setg(errp,
+   "CPU index (%" PRIu16 ")"
+   " should be smaller than maxcpus (%d)",
+   cpus->value, max_cpus);
+return;
+ }
+ props = mc->cpu_index_to_instance_props(ms, cpus->value);
+ props.node_id = nodenr;
+ props.has_node_id = true;
+ machine_set_cpu_numa_node(ms, , );
+ if (err) {
+error_propagate(errp, err);
+return;
+ }
+}
+}
+
+static int parse_numa_node(void *opaque, QemuOpts *opts, Error **errp)
+{
+NumaOptions *object = NULL;
+MachineState *ms = MACHINE(opaque);
+Error *err = NULL;
+Visitor *v = opts_visitor_new(opts);
+
+visit_type_NumaOptions(v, NULL, , );
+visit_free(v);
+if (err) {
+goto end;
+}
+
+if (object->type == NUMA_OPTIONS_TYPE_NODE) {
+set_numa_node_options(ms, object, );
+}
+
+end:
+qapi_free_NumaOptions(object);
+if (err) {
+error_propagate(errp, err);
+return -1;
+}
+
+return 0;
+}
+
 /* If all node pair distances are symmetric, then only distances
  * in one direction are enough. If there is even one asymmetric
  * pair, though, then all distances must be provided. The
@@ -368,7 +408,7 @@ void numa_complete_configuration(MachineState *ms)
 if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
 mc->auto_enable_numa_with_memhp) {
 NumaNodeOptions node = { };
-parse_numa_node(ms, , _abort);
+parse_numa_info(ms, , _abort);
 }
 
 assert(max_numa_nodeid <= MAX_NODES);
@@ -448,6 +488,12 @@ void 

[Qemu-devel] [RFC 2 PATCH 00/16] APIC ID fixes for AMD EPYC CPU models

2019-09-06 Thread Moger, Babu
These series fixes the problems encoding APIC ID for AMD EPYC cpu models.
https://bugzilla.redhat.com/show_bug.cgi?id=1728166

This is the second pass to give an idea of the changes required to address
the issue. First pass is availabe at 
https://patchwork.kernel.org/cover/11069785/

Currently, apic id is decoded based on sockets/dies/cores/threads. This appears
to work for most standard configurations for AMD and other vendors. But this
decoding does not follow AMD's APIC ID enumeration. In some cases this
causes CPU topology inconstancy. While booting guest Kernel is trying to
validate topology. It finds the topology not aligning to EPYC models.

To fix the problem we need to build the topology as per the
Processor Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1
Processors. It is available at https://www.amd.com/en/support/tech-docs

Here is the text from the PPR.
2.1.10.2.1.3
ApicId Enumeration Requirements
Operating systems are expected to use
Core::X86::Cpuid::SizeId[ApicIdCoreIdSize], the number of least
significant bits in the Initial APIC ID that indicate core ID within a
processor, in constructing per-core CPUID
masks. Core::X86::Cpuid::SizeId[ApicIdCoreIdSize] determines the maximum number
of cores (MNC) that the
processor could theoretically support, not the actual number of cores that are
actually implemented or enabled on
the processor, as indicated by Core::X86::Cpuid::SizeId[NC].
Each Core::X86::Apic::ApicId[ApicId] register is preset as follows:
• ApicId[6] = Socket ID.
• ApicId[5:4] = Node ID.
• ApicId[3] = Logical CCX L3 complex ID
• ApicId[2:0]= (SMT) ? {LogicalCoreID[1:0],ThreadId} :
{1'b0,LogicalCoreID[1:0]}.
"""

v2:
  1. Introduced the new property epyc to enable new epyc mode.
  2. Separated the epyc mode and non epyc mode function.
  3. Introduced function pointers in PCMachineState to handle the
 differences.
  4. Mildly tested different combinations to make things are working as 
expected.
  5. TODO : Setting the epyc feature bit needs to be worked out. This feature is
 supported only on AMD EPYC models. I may need some guidance on that.

v1:
  https://patchwork.kernel.org/cover/11069785/

---

Babu Moger (16):
  numa: Split the numa functionality
  hw/i386: Rename X86CPUTopoInfo structure to X86CPUTopoIDs
  hw/i386: Introduce X86CPUTopoInfo to contain topology info
  machine: Add SMP Sockets in CpuTopology
  hw/i386: Simplify topology Offset/width Calculation
  hw/core: Add core complex id in X86CPU topology
  hw/386: Add new epyc mode topology decoding functions
  i386: Cleanup and use the new epyc mode topology functions
  hw/i386: Introduce initialize_topo_info function
  hw/i386: Introduce apicid_from_cpu_idx in PCMachineState
  Introduce-topo_ids_from_apicid-handler
  hw/i386: Introduce apic_id_from_topo_ids handler in PCMachineState
  machine: Add new epyc property in PCMachineState
  hw/i386: Introduce epyc mode function handlers
  i386: Fix pkg_id offset for epyc mode
  hw/core: Fix up the machine_set_cpu_numa_node for epyc


 hw/core/machine-hmp-cmds.c |3 
 hw/core/machine.c  |   38 ++
 hw/core/numa.c |  110 
 hw/i386/pc.c   |  143 +++--
 include/hw/boards.h|8 +
 include/hw/i386/pc.h   |9 +
 include/hw/i386/topology.h |  294 +++-
 include/sysemu/numa.h  |2 
 qapi/machine.json  |4 -
 target/i386/cpu.c  |  209 +++
 target/i386/cpu.h  |1 
 vl.c   |3 
 12 files changed, 560 insertions(+), 264 deletions(-)

--
Signature


Re: [Qemu-devel] [PATCH v1 18/42] tests/docker: move our mips64 cross compile to Buster

2019-09-06 Thread Aleksandar Markovic
04.09.2019. 23.59, "Alex Bennée"  је написао/ла:
>
> Now Buster is released we can stop relying on the movable feast that
> is Sid for our cross-compiler for building tests.
>
> Signed-off-by: Alex Bennée 
> ---

Reviewed-by: Aleksandar Markovic 

>  tests/docker/Makefile.include   | 2 +-
>  tests/docker/dockerfiles/debian-mips64-cross.docker | 5 ++---
>  2 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
> index e946aae14fa..896c1c5a601 100644
> --- a/tests/docker/Makefile.include
> +++ b/tests/docker/Makefile.include
> @@ -102,11 +102,11 @@ docker-image-debian-alpha-cross:
docker-image-debian10
>  docker-image-debian-arm64-cross: docker-image-debian10
>  docker-image-debian-hppa-cross: docker-image-debian10
>  docker-image-debian-m68k-cross: docker-image-debian10
> +docker-image-debian-mips64-cross: docker-image-debian10
>  docker-image-debian-powerpc-cross: docker-image-debian10
>  docker-image-debian-sh4-cross: docker-image-debian10
>  docker-image-debian-sparc64-cross: docker-image-debian10
>
> -docker-image-debian-mips64-cross: docker-image-debian-sid
>  docker-image-debian-riscv64-cross: docker-image-debian-sid
>  docker-image-debian-ppc64-cross: docker-image-debian-sid
>  docker-image-travis: NOUSER=1
> diff --git a/tests/docker/dockerfiles/debian-mips64-cross.docker
b/tests/docker/dockerfiles/debian-mips64-cross.docker
> index bf0073a4662..1a79505d696 100644
> --- a/tests/docker/dockerfiles/debian-mips64-cross.docker
> +++ b/tests/docker/dockerfiles/debian-mips64-cross.docker
> @@ -1,10 +1,9 @@
>  #
>  # Docker cross-compiler target
>  #
> -# This docker target builds on the debian sid base image which
> -# contains cross compilers for Debian "ports" targets.
> +# This docker target builds on the debian Buster base image.
>  #
> -FROM qemu:debian-sid
> +FROM qemu:debian10
>
>  RUN apt update && \
>  DEBIAN_FRONTEND=noninteractive eatmydata \
> --
> 2.20.1
>
>


Re: [Qemu-devel] Cross-posted : Odd QXL/KVM performance issue with a Windows 7 Guest

2019-09-06 Thread Dr. David Alan Gilbert
* Brad Campbell (lists2...@fnarfbargle.com) wrote:
> On 2/9/19 6:23 pm, Brad Campbell wrote:
> 
> > 
> > Here is the holdup :
> > 
> > 11725@1567416625.003504:qxl_ring_command_check 0 native
> > 11725@1567416625.102653:qxl_io_write 0 native addr=0 (QXL_IO_NOTIFY_CMD)
> > val=0 size=1 async=0
> > 
> > ~100ms delay prior to each logged QXL_IO_NOTIFY_CMD on the AMD box which
> > explains the performance difference. Now I just need to figure out if
> > that lies in the guest, the guest QXL driver, QEMU or SPICE and why it
> > exhibits on the AMD box and not the i7.
> > 
> > To get to this point, I recompiled the kernel on the i7 box with both
> > AMD and Intel KVM modules. Once that was running I cloned the drive and
> > put it in the AMD box, so the OS, software stack and all dependencies
> > are identical.
> 
> Reacp :
> 
> I have a machine with a Windows 7 VM which is running on an i7-3770. This
> works perfectly.
> 
> Clone the disk and put it in a new(ish) AMD Ryzen 1500x machine and the
> display output using qxl/spice is now limited to ~5-7fps.
> 
> I originally cloned the entire machine to keep the software versions
> identical.
> 
> To simplify debugging and reproduction I'm now using :
> - An identical SPICE version to that on the i7.
> - A fresh 64 bit Windows 7 VM.
> - The D2D benchmark from Crystalmark 2004R7.
> 
> The machine is booted with :
> 
> qemu -enable-kvm \
>  -m 8192\
>  -rtc base=localtime\
>  -vga qxl\
>  -device qxl\
>  -global qxl-vga.guestdebug=3\
>  -global qxl-vga.cmdlog=1\
>  -global qxl-vga.vram_size=65536\
>  -global qxl.vram_size=65536\
>  -global qxl-vga.ram_size=65536\
>  -global qxl.ram_size=65536\
>  -net nic,model=virtio\
>  -net tap,ifname=tap0,script=/etc/qemu-ifup,vhost=on\
>  -usbdevice tablet\
>  -spice port=5930,disable-ticketing\
>  -device virtio-serial\
>  -chardev spicevmc,id=vdagent,name=vdagent\
>  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0\
>  -smp 3,maxcpus=3,cores=3,threads=1,sockets=1\
>  -cpu qemu64,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \

-cpu qemu64 is almost always a bad idea;  does -cpu host help ?

Dave

>  -drive
> file=/server/VM/Cadbox.raw,if=virtio,aio=threads,format=raw,cache=unsafe
> -boot c \
>  -drive
> file=/server/VM/Cadbox_swap.raw,if=virtio,aio=threads,format=raw,cache=unsafe
> \
> 
> 
> The D2D benchmark runs through a series of Sprites (stars) and it just
> shuffles them around the screen.
> 
> With KVM enabled I get :
> 
> Sprite10 - 8.66fps
> Sprite   100 - 8.47fps
> Sprite   500 - 8.45fps
> Sprite  1000 - 8.18fps
> Sprite  5000 - 7.64fps
> Sprite 1 - 7.26fps
> 
> With the identical system, with KVM disabled I get :
> 
> Sprite10 - 28.97fps
> Sprite   100 - 27.24fps
> Sprite   500 - 23.85fps
> Sprite  1000 - 22.00fps
> Sprite  5000 - 11.11fps
> Sprite 1 -  4.50fps
> 
> On the i7 with the same software version and kvm enabled  :
> 
> Sprite10 - 88.58fps
> Sprite   100 - 88.35fps
> Sprite   500 - 85.64fps
> Sprite  1000 - 83.33fps
> Sprite  5000 - 58.08fps
> Sprite 1 - 45.29fps
> 
> 
> cpuinfo from the host :
> processor : 7
> vendor_id : AuthenticAMD
> cpu family: 23
> model : 1
> model name: AMD Ryzen 5 1500X Quad-Core Processor
> stepping  : 1
> microcode : 0x8001138
> cpu MHz   : 2877.596
> cache size: 512 KB
> physical id   : 0
> siblings  : 8
> core id   : 5
> cpu cores : 4
> apicid: 11
> initial apicid: 11
> fpu   : yes
> fpu_exception : yes
> cpuid level   : 13
> wp: yes
> flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov 
> pat
> pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp
> lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf pni
> pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx
> f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse
> 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext
> perfctr_llc mwaitx cpb hw_pstate sme ssbd sev ibpb vmmcall fsgsbase bmi1
> avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1
> xsaves clzero irperf xsaveerptr arat npt lbrv svm_lock nrip_save tsc_scale
> vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic
> v_vmsave_vmload vgif overflow_recov succor smca
> bugs  : sysret_ss_attrs null_seg spectre_v1 spectre_v2 
> spec_store_bypass
> bogomips  : 6985.80
> TLB size  : 2560 4K pages
> clflush size  : 64
> cache_alignment   : 64
> address sizes : 43 bits physical, 48 bits virtual
> power management: ts ttp tm hwpstate eff_freq_ro [13] [14]
> 
> qemu configured with : 
> PKG_CONFIG_PATH=/usr/local/libvirt/lib/pkgconfig:/usr/local/libvirt/share/pkgconfig/
> ./configure --target-list=x86_64-softmmu --disable-gtk && make -j6
> test:~# uname -a
> 
> Linux test 5.2.9 #42 SMP Tue Aug 20 16:41:13 AWST 2019 x86_64 GNU/Linux
> 
> test:~# 

Re: [Qemu-devel] [PATCH 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Maxim Levitsky
On Fri, 2019-09-06 at 14:00 -0500, Eric Blake wrote:
> On 9/6/19 1:55 PM, Maxim Levitsky wrote:
> 
> > > > +/*
> > > > + * qcow2_co_encrypt()
> > > > + *
> > > > + * Encrypts a sector size aligned contiguous area
> > > > + *
> > > > + * @host_cluster_offset - on disk offset of the cluster in which
> > > > + *the buffer resides
> > > > + *
> > > > + * @guest_offset - guest (virtual) offset of the buffer
> > > > + * @buf - buffer with the data to encrypt
> > > > + * @len - length of the buffer
> > > > + *
> > > > + * Note that the area is not cluster aligned and might cross a cluster
> > > > + * boundary
> > > 
> > > Umm, how is it possible for a sector to cross a cluster boundary?  All
> > > clusters are sector-aligned, and encryption only works on aligned
> > > sectors.  Oh, I see - if @len is a multiple larger than sector size,
> > > then we have multiple sectors, and then indeed we may cross clusters.
> > > But then the docs about being 'a sector size aligned contiguous area' is
> > > not quite right.
> > 
> > Why? the written area is always both aligned on _sector_ boundary
> > and multiple of the sector size. At least that what I see from
> > the existing asserts.
> 
> I'm thinking it should read something like:
> 
> Encrypts one or more contiguous aligned sectors
> 
> to make it obvious that because there can be multiple sectors, there may
> indeed be a cluster boundary mid-length.  My complaint was that the
> original text made it sound like there was exactly one sector (at which
> point @len is redundant, unless sectors are variably-sized)
> 
I agree with you completely, I will change that.

Best regards,
Maxim Levitsky






Re: [Qemu-devel] [PATCH 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Eric Blake
On 9/6/19 1:55 PM, Maxim Levitsky wrote:

>>> +/*
>>> + * qcow2_co_encrypt()
>>> + *
>>> + * Encrypts a sector size aligned contiguous area
>>> + *
>>> + * @host_cluster_offset - on disk offset of the cluster in which
>>> + *the buffer resides
>>> + *
>>> + * @guest_offset - guest (virtual) offset of the buffer
>>> + * @buf - buffer with the data to encrypt
>>> + * @len - length of the buffer
>>> + *
>>> + * Note that the area is not cluster aligned and might cross a cluster
>>> + * boundary
>>
>> Umm, how is it possible for a sector to cross a cluster boundary?  All
>> clusters are sector-aligned, and encryption only works on aligned
>> sectors.  Oh, I see - if @len is a multiple larger than sector size,
>> then we have multiple sectors, and then indeed we may cross clusters.
>> But then the docs about being 'a sector size aligned contiguous area' is
>> not quite right.
> 
> Why? the written area is always both aligned on _sector_ boundary
> and multiple of the sector size. At least that what I see from
> the existing asserts.

I'm thinking it should read something like:

Encrypts one or more contiguous aligned sectors

to make it obvious that because there can be multiple sectors, there may
indeed be a cluster boundary mid-length.  My complaint was that the
original text made it sound like there was exactly one sector (at which
point @len is redundant, unless sectors are variably-sized)

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] linux-user: hijack open() for thread directories

2019-09-06 Thread mailer
Hi Shu-Chun Weng via Qemu-devel!

We received your email, but were unable to deliver it because it
contains content which has been blacklisted by the list admin. Please
remove your application/pkcs7-signature attachments and send again.

You are also advised to configure your email client to send emails in
plain text to avoid additional errors in the future:

https://useplaintext.email

If you have any questions, please reply to this email to reach the mail
admin. We apologise for the inconvenience.



Re: [Qemu-devel] [PATCH 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Maxim Levitsky
On Fri, 2019-09-06 at 13:00 -0500, Eric Blake wrote:
> On 9/6/19 12:31 PM, Maxim Levitsky wrote:
> > This commit tries to clarify few function arguments,
> > and add comments describing the encrypt/decrypt interface
> > 
> > Signed-off-by: Maxim Levitsky 
> > ---
> >  block/qcow2-cluster.c |  8 +++
> >  block/qcow2-threads.c | 53 ++-
> >  2 files changed, 46 insertions(+), 15 deletions(-)
> > 
> > +++ b/block/qcow2-threads.c
> > @@ -234,15 +234,19 @@ static int qcow2_encdec_pool_func(void *opaque)
> >  }
> >  
> >  static int coroutine_fn
> > -qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
> > -  uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc 
> > func)
> 
> Pre-existing bug in alignment...
No problem will fix.

> 
> > +qcow2_co_encdec(BlockDriverState *bs, uint64_t host_cluster_offset,
> > +  uint64_t guest_offset, void *buf, size_t len,
> > +  Qcow2EncDecFunc func)
> 
> ...so this would be a great time to fix it.
> 
> >  {
> >  BDRVQcow2State *s = bs->opaque;
> > +
> > +uint64_t offset = s->crypt_physical_offset ?
> > +host_cluster_offset + offset_into_cluster(s, guest_offset) :
> > +guest_offset;
> > +
> >  Qcow2EncDecData arg = {
> >  .block = s->crypto,
> > -.offset = s->crypt_physical_offset ?
> > -  file_cluster_offset + offset_into_cluster(s, offset) 
> > :
> > -  offset,
> > +.offset = offset,
> 
> I'm ambivalent on whether the new 'offset' variable gains us anything.
> But it doesn't hurt.
I added it, so that I won't need to wrap the lines even more that 
they are wrapped already since I increased the length of
the parameter names a bit.

> 
> 
> >  .buf = buf,
> >  .len = len,
> >  .func = func,
> > @@ -251,18 +255,45 @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t 
> > file_cluster_offset,
> >  return qcow2_co_process(bs, qcow2_encdec_pool_func, );
> >  }
> >  
> > +
> > +/*
> > + * qcow2_co_encrypt()
> > + *
> > + * Encrypts a sector size aligned contiguous area
> > + *
> > + * @host_cluster_offset - on disk offset of the cluster in which
> > + *the buffer resides
> > + *
> > + * @guest_offset - guest (virtual) offset of the buffer
> > + * @buf - buffer with the data to encrypt
> > + * @len - length of the buffer
> > + *
> > + * Note that the area is not cluster aligned and might cross a cluster
> > + * boundary
> 
> Umm, how is it possible for a sector to cross a cluster boundary?  All
> clusters are sector-aligned, and encryption only works on aligned
> sectors.  Oh, I see - if @len is a multiple larger than sector size,
> then we have multiple sectors, and then indeed we may cross clusters.
> But then the docs about being 'a sector size aligned contiguous area' is
> not quite right.

Why? the written area is always both aligned on _sector_ boundary
and multiple of the sector size. At least that what I see from
the existing asserts.


> 
> > + *
> > + *
> > + */
> >  int coroutine_fn
> > -qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
> > - uint64_t offset, void *buf, size_t len)
> > +qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
> > + uint64_t guest_offset, void *buf, size_t len)
> >  {
> > -return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
> > +return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
> >   qcrypto_block_encrypt);
> 
> 
> Another alignment worth fixing up while in the area.
> 
> >  }
> >  
> > +
> > +/*
> > + * qcow2_co_decrypt()
> > + *
> > + * Decrypts a sector size aligned contiguous area
> > + * Same function as qcow2_co_encrypt
> > + *
> > + */
> > +
> >  int coroutine_fn
> > -qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
> > - uint64_t offset, void *buf, size_t len)
> > +qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
> > + uint64_t guest_offset, void *buf, size_t len)
> >  {
> > -return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
> > +return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
> >   qcrypto_block_decrypt);
> 
> and again.
> 
> >  }
> > 
> 
> 


Best regards,
Thanks for the review,
Maxim Levitsky





Re: [Qemu-devel] [PATCH 0/2] Adding some setsockopt() options

2019-09-06 Thread mailer
Hi Shu-Chun Weng via Qemu-devel!

We received your email, but were unable to deliver it because it
contains content which has been blacklisted by the list admin. Please
remove your application/pkcs7-signature attachments and send again.

You are also advised to configure your email client to send emails in
plain text to avoid additional errors in the future:

https://useplaintext.email

If you have any questions, please reply to this email to reach the mail
admin. We apologise for the inconvenience.



Re: [Qemu-devel] [PATCH 0/2] Adding some setsockopt() options

2019-09-06 Thread Shu-Chun Weng via Qemu-devel
Ping. Patchwork links:

http://patchwork.ozlabs.org/patch/1151884/
http://patchwork.ozlabs.org/patch/1151883/

On Thu, Aug 22, 2019 at 4:14 PM Shu-Chun Weng  wrote:

> Shu-Chun Weng (2):
>   linux-user: add missing UDP and IPv6 setsockopt options
>   linux-user: time stamping options for setsockopt()
>
>  linux-user/generic/sockbits.h |  4 
>  linux-user/mips/sockbits.h|  4 
>  linux-user/syscall.c  | 16 +---
>  3 files changed, 21 insertions(+), 3 deletions(-)
>
> --
> 2.23.0.187.g17f5b7556c-goog
>
>


smime.p7s
Description: S/MIME Cryptographic Signature


Re: [Qemu-devel] [PATCH] linux-user: hijack open() for thread directories

2019-09-06 Thread Shu-Chun Weng via Qemu-devel
Ping. Any comments on this? Patchwork:
http://patchwork.ozlabs.org/patch/1151167/

On Wed, Aug 21, 2019 at 1:19 PM Shu-Chun Weng  wrote:

> Besides /proc/self|, files under /proc/thread-self and
> /proc/self|/task/ also expose host information to the guest
> program. This patch adds them to the hijack infrastracture. Note that
> is_proc_myself() does not check if the  matches the current thread
> and is thus only suitable for procfs files that are identical for all
> threads in the same process.
>
> Behavior verified with guest program:
>
> long main_thread_tid;
>
> long gettid() {
>   return syscall(SYS_gettid);
> }
>
> void print_info(const char* cxt, const char* dir) {
>   char buf[1024];
>   FILE* fp;
>
>   snprintf(buf, sizeof(buf), "%s/cmdline", dir);
>   fp = fopen(buf, "r");
>
>   if (fp == NULL) {
> printf("%s: can't open %s\n", cxt, buf);
>   } else {
> fgets(buf, sizeof(buf), fp);
> printf("%s %s cmd: %s\n", cxt, dir, buf);
> fclose(fp);
>   }
>
>   snprintf(buf, sizeof(buf), "%s/maps", dir);
>   fp = fopen(buf, "r");
>
>   if (fp == NULL) {
> printf("%s: can't open %s\n", cxt, buf);
>   } else {
> char seen[128][128];
> int n = 0, is_new = 0;
> while(fgets(buf, sizeof(buf), fp) != NULL) {
>   const char* p = strrchr(buf, ' ');
>   if (p == NULL || *(p + 1) == '\n') {
> continue;
>   }
>   ++p;
>   is_new = 1;
>   for (int i = 0; i < n; ++i) {
> if (strncmp(p, seen[i], sizeof(seen[i])) == 0) {
>   is_new = 0;
>   break;
> }
>   }
>   if (is_new) {
> printf("%s %s map: %s", cxt, dir, p);
> if (n < 128) {
>   strncpy(seen[n], p, sizeof(seen[n]));
>   seen[n][sizeof(seen[n]) - 1] = '\0';
>   ++n;
> }
>   }
> }
> fclose(fp);
>   }
> }
>
> void* thread_main(void* _) {
>   char buf[1024];
>
>   print_info("Child", "/proc/thread-self");
>
>   snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(),
> main_thread_tid);
>   print_info("Child", buf);
>
>   snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(), (long)
> gettid());
>   print_info("Child", buf);
>
>   return NULL;
> }
>
> int main() {
>   char buf[1024];
>   pthread_t thread;
>   int ret;
>
>   print_info("Main", "/proc/thread-self");
>   print_info("Main", "/proc/self");
>
>   snprintf(buf, sizeof(buf), "/proc/%ld", (long) getpid());
>   print_info("Main", buf);
>
>   main_thread_tid = gettid();
>   snprintf(buf, sizeof(buf), "/proc/self/task/%ld", main_thread_tid);
>   print_info("Main", buf);
>
>   snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(),
> main_thread_tid);
>   print_info("Main", buf);
>
>   if ((ret = pthread_create(, NULL, _main, NULL)) < 0) {
> printf("ptherad_create failed: %s (%d)\n", strerror(ret), ret);
>   }
>
>   pthread_join(thread, NULL);
>   return 0;
> }
>
> Signed-off-by: Shu-Chun Weng 
> ---
>  linux-user/syscall.c | 40 
>  1 file changed, 40 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 8367cb138d..73fe82bcc7 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6968,17 +6968,57 @@ static int open_self_auxv(void *cpu_env, int fd)
>  return 0;
>  }
>
> +static int consume_task_directories(const char **filename)
> +{
> +if (!strncmp(*filename, "task/", strlen("task/"))) {
> +*filename += strlen("task/");
> +if (**filename < '1' || **filename > '9') {
> +return 0;
> +}
> +/*
> + * Don't care about the exact tid.
> + * XXX: this allows opening files under /proc/self|/task/
> where
> + *   is not a valid thread id. Consider checking if the
> file
> + *  actually exists.
> + */
> +const char *p = *filename + 1;
> +while (*p >= '0' && *p <= '9') {
> +++p;
> +}
> +if (*p == '/') {
> +*filename = p + 1;
> +return 1;
> +} else {
> +return 0;
> +}
> +}
> +return 1;
> +}
> +
> +/*
> + * Determines if filename refer to a procfs file for the current process
> or any
> + * thread within the current process. This function should only be used
> to check
> + * for files that have identical contents in all threads, e.g. exec,
> maps, etc.
> + */
>  static int is_proc_myself(const char *filename, const char *entry)
>  {
>  if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
>  filename += strlen("/proc/");
>  if (!strncmp(filename, "self/", strlen("self/"))) {
>  filename += strlen("self/");
> +if (!consume_task_directories()) {
> +return 0;
> +}
> +} else if (!strncmp(filename, "thread-self/",
> strlen("thread-self/"))) {
> +filename += strlen("thread-self/");
>  } else if (*filename >= '1' && *filename <= '9') {
>  char 

Re: [Qemu-devel] [PATCH 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Eric Blake
On 9/6/19 12:31 PM, Maxim Levitsky wrote:
> This commit tries to clarify few function arguments,
> and add comments describing the encrypt/decrypt interface
> 
> Signed-off-by: Maxim Levitsky 
> ---
>  block/qcow2-cluster.c |  8 +++
>  block/qcow2-threads.c | 53 ++-
>  2 files changed, 46 insertions(+), 15 deletions(-)
> 

> +++ b/block/qcow2-threads.c
> @@ -234,15 +234,19 @@ static int qcow2_encdec_pool_func(void *opaque)
>  }
>  
>  static int coroutine_fn
> -qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
> -  uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc 
> func)

Pre-existing bug in alignment...

> +qcow2_co_encdec(BlockDriverState *bs, uint64_t host_cluster_offset,
> +  uint64_t guest_offset, void *buf, size_t len,
> +  Qcow2EncDecFunc func)

...so this would be a great time to fix it.

>  {
>  BDRVQcow2State *s = bs->opaque;
> +
> +uint64_t offset = s->crypt_physical_offset ?
> +host_cluster_offset + offset_into_cluster(s, guest_offset) :
> +guest_offset;
> +
>  Qcow2EncDecData arg = {
>  .block = s->crypto,
> -.offset = s->crypt_physical_offset ?
> -  file_cluster_offset + offset_into_cluster(s, offset) :
> -  offset,
> +.offset = offset,

I'm ambivalent on whether the new 'offset' variable gains us anything.
But it doesn't hurt.


>  .buf = buf,
>  .len = len,
>  .func = func,
> @@ -251,18 +255,45 @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t 
> file_cluster_offset,
>  return qcow2_co_process(bs, qcow2_encdec_pool_func, );
>  }
>  
> +
> +/*
> + * qcow2_co_encrypt()
> + *
> + * Encrypts a sector size aligned contiguous area
> + *
> + * @host_cluster_offset - on disk offset of the cluster in which
> + *the buffer resides
> + *
> + * @guest_offset - guest (virtual) offset of the buffer
> + * @buf - buffer with the data to encrypt
> + * @len - length of the buffer
> + *
> + * Note that the area is not cluster aligned and might cross a cluster
> + * boundary

Umm, how is it possible for a sector to cross a cluster boundary?  All
clusters are sector-aligned, and encryption only works on aligned
sectors.  Oh, I see - if @len is a multiple larger than sector size,
then we have multiple sectors, and then indeed we may cross clusters.
But then the docs about being 'a sector size aligned contiguous area' is
not quite right.

> + *
> + *
> + */
>  int coroutine_fn
> -qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
> - uint64_t offset, void *buf, size_t len)
> +qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
> + uint64_t guest_offset, void *buf, size_t len)
>  {
> -return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
> +return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
>   qcrypto_block_encrypt);


Another alignment worth fixing up while in the area.

>  }
>  
> +
> +/*
> + * qcow2_co_decrypt()
> + *
> + * Decrypts a sector size aligned contiguous area
> + * Same function as qcow2_co_encrypt
> + *
> + */
> +
>  int coroutine_fn
> -qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
> - uint64_t offset, void *buf, size_t len)
> +qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
> + uint64_t guest_offset, void *buf, size_t len)
>  {
> -return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
> +return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
>   qcrypto_block_decrypt);

and again.

>  }
> 

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 0/3] Fix qcow2+luks corruption introduced by commit 8ac0f15f335

2019-09-06 Thread Maxim Levitsky
On Fri, 2019-09-06 at 20:31 +0300, Maxim Levitsky wrote:
> Commit 8ac0f15f335 accidently broke the COW of non changed areas
> of newly allocated clusters, when the write spans multiple clusters,
> and needs COW both prior and after the write.
> This results in 'after' COW area beeing encrypted with wrong
> sector address, which render it corrupted.
> 
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922
> 
> CC: qemu-stable 

I forgot to mention, huge thanks to Kevin Wolf,
for helping me to define the proper fix for this bug.

Best regards,
Maxim Levitsky




[Qemu-devel] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files

2019-09-06 Thread Maxim Levitsky
This fixes subltle corruption introduced by luks threaded encryption
in commit 8ac0f15f335

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922

The corruption happens when we do
   * write to two or more unallocated clusters at once
   * write doesn't fully cover nether first nor last cluster

In this case, when allocating the new clusters we COW both area
prior to the write and after the write, and we encrypt them.

The above mentioned commit accidently made it so, we encrypt the
second COW are using the physical cluster offset of the first area.

Fix this by:
 * remove the offset_in_cluster parameter of do_perform_cow_encrypt
   since it is misleading. That offset can be larger that cluster size.
   instead just add the start and end COW are offsets to both host and guest 
offsets
   that do_perform_cow_encrypt receives.

*  in do_perform_cow_encrypt, remove the cluster offset from the host_offset
   And thus pass correctly to the qcow2_co_encrypt, the host cluster offset and 
full guest offset


Signed-off-by: Maxim Levitsky 
---
 block/qcow2-cluster.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index b95e64c237..32477f0156 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -463,20 +463,20 @@ static int coroutine_fn 
do_perform_cow_read(BlockDriverState *bs,
 }
 
 static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
-uint64_t guest_cluster_offset,
-uint64_t host_cluster_offset,
-unsigned offset_in_cluster,
+uint64_t guest_offset,
+uint64_t host_offset,
 uint8_t *buffer,
 unsigned bytes)
 {
 if (bytes && bs->encrypted) {
 BDRVQcow2State *s = bs->opaque;
-assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
+assert((guest_offset & ~BDRV_SECTOR_MASK) == 0);
+assert((host_offset & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
 assert(s->crypto);
-if (qcow2_co_encrypt(bs, host_cluster_offset,
- guest_cluster_offset + offset_in_cluster,
- buffer, bytes) < 0) {
+
+if (qcow2_co_encrypt(bs, start_of_cluster(s, host_offset),
+ guest_offset, buffer, bytes) < 0) {
 return false;
 }
 }
@@ -890,11 +890,15 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta 
*m)
 
 /* Encrypt the data if necessary before writing it */
 if (bs->encrypted) {
-if (!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
-start->offset, start_buffer,
+if (!do_perform_cow_encrypt(bs,
+m->offset + start->offset,
+m->alloc_offset + start->offset,
+start_buffer,
 start->nb_bytes) ||
-!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
-end->offset, end_buffer, end->nb_bytes)) {
+!do_perform_cow_encrypt(bs,
+m->offset + end->offset,
+m->alloc_offset + end->offset,
+end_buffer, end->nb_bytes)) {
 ret = -EIO;
 goto fail;
 }
-- 
2.17.2




[Qemu-devel] [PATCH 1/3] block/qcow2: refactoring of threaded encryption code

2019-09-06 Thread Maxim Levitsky
This commit tries to clarify few function arguments,
and add comments describing the encrypt/decrypt interface

Signed-off-by: Maxim Levitsky 
---
 block/qcow2-cluster.c |  8 +++
 block/qcow2-threads.c | 53 ++-
 2 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f09cc992af..b95e64c237 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -463,8 +463,8 @@ static int coroutine_fn 
do_perform_cow_read(BlockDriverState *bs,
 }
 
 static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
-uint64_t src_cluster_offset,
-uint64_t cluster_offset,
+uint64_t guest_cluster_offset,
+uint64_t host_cluster_offset,
 unsigned offset_in_cluster,
 uint8_t *buffer,
 unsigned bytes)
@@ -474,8 +474,8 @@ static bool coroutine_fn 
do_perform_cow_encrypt(BlockDriverState *bs,
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
 assert(s->crypto);
-if (qcow2_co_encrypt(bs, cluster_offset,
- src_cluster_offset + offset_in_cluster,
+if (qcow2_co_encrypt(bs, host_cluster_offset,
+ guest_cluster_offset + offset_in_cluster,
  buffer, bytes) < 0) {
 return false;
 }
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 3b1e63fe41..8bc339690f 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -234,15 +234,19 @@ static int qcow2_encdec_pool_func(void *opaque)
 }
 
 static int coroutine_fn
-qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
-  uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc func)
+qcow2_co_encdec(BlockDriverState *bs, uint64_t host_cluster_offset,
+  uint64_t guest_offset, void *buf, size_t len,
+  Qcow2EncDecFunc func)
 {
 BDRVQcow2State *s = bs->opaque;
+
+uint64_t offset = s->crypt_physical_offset ?
+host_cluster_offset + offset_into_cluster(s, guest_offset) :
+guest_offset;
+
 Qcow2EncDecData arg = {
 .block = s->crypto,
-.offset = s->crypt_physical_offset ?
-  file_cluster_offset + offset_into_cluster(s, offset) :
-  offset,
+.offset = offset,
 .buf = buf,
 .len = len,
 .func = func,
@@ -251,18 +255,45 @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t 
file_cluster_offset,
 return qcow2_co_process(bs, qcow2_encdec_pool_func, );
 }
 
+
+/*
+ * qcow2_co_encrypt()
+ *
+ * Encrypts a sector size aligned contiguous area
+ *
+ * @host_cluster_offset - on disk offset of the cluster in which
+ *the buffer resides
+ *
+ * @guest_offset - guest (virtual) offset of the buffer
+ * @buf - buffer with the data to encrypt
+ * @len - length of the buffer
+ *
+ * Note that the area is not cluster aligned and might cross a cluster
+ * boundary
+ *
+ *
+ */
 int coroutine_fn
-qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
- uint64_t offset, void *buf, size_t len)
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
+ uint64_t guest_offset, void *buf, size_t len)
 {
-return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
  qcrypto_block_encrypt);
 }
 
+
+/*
+ * qcow2_co_decrypt()
+ *
+ * Decrypts a sector size aligned contiguous area
+ * Same function as qcow2_co_encrypt
+ *
+ */
+
 int coroutine_fn
-qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
- uint64_t offset, void *buf, size_t len)
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_cluster_offset,
+ uint64_t guest_offset, void *buf, size_t len)
 {
-return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+return qcow2_co_encdec(bs, host_cluster_offset, guest_offset, buf, len,
  qcrypto_block_decrypt);
 }
-- 
2.17.2




[Qemu-devel] [PATCH 0/3] Fix qcow2+luks corruption introduced by commit 8ac0f15f335

2019-09-06 Thread Maxim Levitsky
Commit 8ac0f15f335 accidently broke the COW of non changed areas
of newly allocated clusters, when the write spans multiple clusters,
and needs COW both prior and after the write.
This results in 'after' COW area beeing encrypted with wrong
sector address, which render it corrupted.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922

CC: qemu-stable 

Best regards,
Maxim Levitsky

Maxim Levitsky (3):
  block/qcow2: refactoring of threaded encryption code
  block/qcow2: fix the corruption when rebasing luks encrypted files
  qemu-iotests: test for bz #1745922

 block/qcow2-cluster.c  | 26 +++--
 block/qcow2-threads.c  | 53 --
 tests/qemu-iotests/263 | 76 ++
 tests/qemu-iotests/263.out | 19 ++
 tests/qemu-iotests/group   |  1 +
 5 files changed, 153 insertions(+), 22 deletions(-)
 create mode 100755 tests/qemu-iotests/263
 create mode 100644 tests/qemu-iotests/263.out

-- 
2.17.2




[Qemu-devel] [PATCH 3/3] qemu-iotests: test for bz #1745922

2019-09-06 Thread Maxim Levitsky
Signed-off-by: Maxim Levitsky 
---
 tests/qemu-iotests/263 | 76 ++
 tests/qemu-iotests/263.out | 19 ++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 96 insertions(+)
 create mode 100755 tests/qemu-iotests/263
 create mode 100644 tests/qemu-iotests/263.out

diff --git a/tests/qemu-iotests/263 b/tests/qemu-iotests/263
new file mode 100755
index 00..9cb23aa81e
--- /dev/null
+++ b/tests/qemu-iotests/263
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+#
+# Test encrypted write that crosses cluster boundary of two unallocated 
clusters
+# Based on 188
+#
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# 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 of the License, 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 .
+#
+
+# creator
+owner=mlevi...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+
+size=1M
+
+SECRET="secret,id=sec0,data=astrochicken"
+SECRETALT="secret,id=sec0,data=platypus"
+
+_make_test_img --object $SECRET -o 
"encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=64K"
 $size
+
+IMGSPEC="driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG"
+
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
+
+echo
+echo "== reading whole image =="
+$QEMU_IO --object $SECRET -c "read -P 0 0 $size" --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+echo
+echo "== write two 512 byte sectors on a cluster boundary =="
+$QEMU_IO --object $SECRET -c "write -P 0xAA 0xFE00 0x400" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+
+echo
+echo "== verify that the rest of the image is not changed =="
+$QEMU_IO --object $SECRET -c "read -P 0x00 0x0 0xFE00" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+$QEMU_IO --object $SECRET -c "read -P 0xAA 0x0FE00 0x400" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+$QEMU_IO --object $SECRET -c "read -P 0x00 0x10200 0xEFE00" --image-opts 
$IMGSPEC | _filter_qemu_io | _filter_testdir
+
+_cleanup_test_img
+
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/263.out b/tests/qemu-iotests/263.out
new file mode 100644
index 00..fa4e4e0e4a
--- /dev/null
+++ b/tests/qemu-iotests/263.out
@@ -0,0 +1,19 @@
+QA output created by 263
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks 
encrypt.key-secret=sec0 encrypt.iter-time=10
+
+== reading whole image ==
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== write two 512 byte sectors on a cluster boundary ==
+wrote 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify that the rest of the image is not changed ==
+read 65024/65024 bytes at offset 0
+63.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 65024
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 982528/982528 bytes at offset 66048
+959.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index d95d556414..be1c4a3baa 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -274,3 +274,4 @@
 257 rw
 258 rw quick
 262 rw quick migration
+263 rw quick
-- 
2.17.2




[Qemu-devel] IOTEST 162

2019-09-06 Thread Maxim Levitsky
Hi!

I just had a very fun rabbit hole dive, and I want to share it with you.

I notice for some time that iotest 162 fails with that:

-qemu-img: Could not open 'json:{"driver": "nbd", "host": 42}': Failed to 
connect socket: Invalid argument
+qemu-img: Could not open 'json:{"driver": "nbd", "host": 42}': Failed to 
connect socket:
Connection timed out


I didn't bother to report it yet as it started failing more or less when qemu 
4.2 merge window opened,
so I thought that maybe something got broken, or maybe something broken in my 
environment 
(ahem, AF_UNIX path is too long, ahem)

I just didn't had enough time to pay attention to this. Until today.

So I asked Kevin Wolf today, just by the way why I see for some time that
iotest 162 fails. for me.


He told me that it works for him.
So I look at the test and I see that it just does

qemu-img info 'json:{"driver": "nbd", "host": 42}'

Supposedly it should fail because 42 is not quoted, and it 
doesn't look like a valid host name.

I try with disto's qemu-img (2.11) and I still see that I get the 'Connection 
timed out'

Then I ask him to try on his system with '42' quoted and it still passes.

All right - this means that this 42 is parsed. He also mentions that he uses 
fedora 29 and I still
use fedora 28. So I start a VM with fedora 30, and yep, there it does work 
correctly.

All right, that 42 must be parsed as a host name. Yep. 'ping 42' on my machine 
tries to ping 0.0.0.42,
and in VM exits immediately with 'Invalid argument'
All right, lets ping 0.0.0.42. Maybe something in hostname parsing changed, 
maybe something parses this on DNS level?
Nope, ping 0.0.0.42 works on my machine, fails with invalid argument in VM...

All right lets strace it

connect(5, {sa_family=AF_INET, sin_port=htons(1025), 
sin_addr=inet_addr("0.0.0.42")}, 16) = -1 EINVAL (Invalid argument)

Same thing passes on my machine

Hmm... this is something in the kernel. Maybe something in iptables/etc. I 
don't yet know that
area that well to be honest.

So I googled a bit and look what I found:

https://lwn.net/Articles/791086/

And yes, while my machine runs fedora 28, it as usual runs vanilla git master
kernel, which I compile from time to time. Currently I am on 5.3.0-rc4+.

So I must say that nothing less but kernel 5.3.0, breaks iotest 162.

I''l prepare a patch soon to fix this.

Best regards,
Maxim Levitsky







Re: [Qemu-devel] [PATCH v3] target/xtensa: linux-user: add call0 ABI support

2019-09-06 Thread Laurent Vivier
Le 06/09/2019 à 18:55, Max Filippov a écrit :
> On Fri, Sep 6, 2019 at 2:33 AM Laurent Vivier  wrote:
>> Le 26/08/2019 à 21:58, Max Filippov a écrit :
>>> +#if defined(TARGET_XTENSA)
>>> +if (getenv("QEMU_XTENSA_ABI_CALL0")) {
>>> +xtensa_set_abi_call0();
>>> +}
>>
>> Not needed, this is done by parse_args() that checks
>> getenv(arginfo->env) and calls arginfo->handle_opt()
>> (handle_arg_abi_call0()).
> 
> Thank you, I'll fix that. I got confused by the similar handling of
> QEMU_STRACE, I'll post a cleanup that removes that as well.

Good point.

It seems getenv("QEMU_STRACE") and getenv("QEMU_RAND_SEED") could be
removed.

Thanks,
Laurent




[Qemu-devel] [PATCH] linux-user: drop redundant handling of environment variables

2019-09-06 Thread Max Filippov
QEMU_STRACE and QEMU_RAND_SEED are handled by the parse_args, no need to
do it again in main.

Signed-off-by: Max Filippov 
---
 linux-user/main.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c9d97d2b1fc6..22ae2b3e65d1 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -701,13 +701,6 @@ int main(int argc, char **argv, char **envp)
 
 thread_cpu = cpu;
 
-if (getenv("QEMU_STRACE")) {
-do_strace = 1;
-}
-
-if (seed_optarg == NULL) {
-seed_optarg = getenv("QEMU_RAND_SEED");
-}
 {
 Error *err = NULL;
 if (seed_optarg != NULL) {
-- 
2.11.0




[Qemu-devel] [PATCH v4] target/xtensa: linux-user: add call0 ABI support

2019-09-06 Thread Max Filippov
Xtensa binaries built for call0 ABI don't rotate register window on
function calls and returns. Invocation of signal handlers from the
kernel is therefore different in windowed and call0 ABIs.
There's currently no way to determine xtensa ELF binary ABI from the
binary itself. Add handler for the -xtensa-abi-call0 command line
parameter/QEMU_XTENSA_ABI_CALL0 envitonment variable to the qemu-user
and record ABI choice. Use it to initialize PS.WOE in xtensa_cpu_reset.
Check PS.WOE in setup_rt_frame to determine how a signal should be
delivered.

Reviewed-by: Laurent Vivier 
Signed-off-by: Max Filippov 
---
 linux-user/main.c  | 11 +++
 linux-user/xtensa/signal.c | 25 +
 target/xtensa/cpu.c| 24 
 target/xtensa/cpu.h|  3 +++
 4 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 47917bbb20fc..c9d97d2b1fc6 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -393,6 +393,13 @@ static void handle_arg_trace(const char *arg)
 trace_file = trace_opt_parse(arg);
 }
 
+#if defined(TARGET_XTENSA)
+static void handle_arg_abi_call0(const char *arg)
+{
+xtensa_set_abi_call0();
+}
+#endif
+
 struct qemu_argument {
 const char *argv;
 const char *env;
@@ -446,6 +453,10 @@ static const struct qemu_argument arg_table[] = {
  "",   "[[enable=]][,events=][,file=]"},
 {"version","QEMU_VERSION", false, handle_arg_version,
  "",   "display version information and exit"},
+#if defined(TARGET_XTENSA)
+{"xtensa-abi-call0", "QEMU_XTENSA_ABI_CALL0", false, handle_arg_abi_call0,
+ "",   "assume CALL0 Xtensa ABI"},
+#endif
 {NULL, NULL, false, NULL, NULL, NULL}
 };
 
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index 8d54ef3ae34b..590f0313ffe9 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -134,6 +134,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 abi_ulong frame_addr;
 struct target_rt_sigframe *frame;
 uint32_t ra;
+bool abi_call0;
+unsigned base;
 int i;
 
 frame_addr = get_sigframe(ka, env, sizeof(*frame));
@@ -182,20 +184,27 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 __put_user(0x00, >retcode[5]);
 #endif
 }
-env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
-if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) {
-env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
-}
 memset(env->regs, 0, sizeof(env->regs));
 env->pc = ka->_sa_handler;
 env->regs[1] = frame_addr;
 env->sregs[WINDOW_BASE] = 0;
 env->sregs[WINDOW_START] = 1;
 
-env->regs[4] = (ra & 0x3fff) | 0x4000;
-env->regs[6] = sig;
-env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info);
-env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc);
+abi_call0 = (env->sregs[PS] & PS_WOE) == 0;
+env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
+
+if (abi_call0) {
+base = 0;
+env->regs[base] = ra;
+} else {
+env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
+base = 4;
+env->regs[base] = (ra & 0x3fff) | 0x4000;
+}
+env->regs[base + 2] = sig;
+env->regs[base + 3] = frame_addr + offsetof(struct target_rt_sigframe,
+info);
+env->regs[base + 4] = frame_addr + offsetof(struct target_rt_sigframe, uc);
 unlock_user_struct(frame, frame_addr, 1);
 return;
 
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 76db1741a796..c65dcf9dd782 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -53,6 +53,20 @@ static bool xtensa_cpu_has_work(CPUState *cs)
 #endif
 }
 
+#ifdef CONFIG_USER_ONLY
+static bool abi_call0;
+
+void xtensa_set_abi_call0(void)
+{
+abi_call0 = true;
+}
+
+bool xtensa_abi_call0(void)
+{
+return abi_call0;
+}
+#endif
+
 /* CPUClass::reset() */
 static void xtensa_cpu_reset(CPUState *s)
 {
@@ -70,10 +84,12 @@ static void xtensa_cpu_reset(CPUState *s)
 XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
 env->pending_irq_level = 0;
 #else
-env->sregs[PS] =
-(xtensa_option_enabled(env->config,
-   XTENSA_OPTION_WINDOWED_REGISTER) ? PS_WOE : 0) |
-PS_UM | (3 << PS_RING_SHIFT);
+env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
+if (xtensa_option_enabled(env->config,
+  XTENSA_OPTION_WINDOWED_REGISTER) &&
+!xtensa_abi_call0()) {
+env->sregs[PS] |= PS_WOE;
+}
 #endif
 env->sregs[VECBASE] = env->config->vecbase;
 env->sregs[IBREAKENABLE] = 0;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 0459243e6bb1..b363ffcf1066 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -673,6 +673,9 @@ static inline MemoryRegion 
*xtensa_get_er_region(CPUXtensaState *env)
 {
 

Re: [Qemu-devel] [PATCH v3] target/xtensa: linux-user: add call0 ABI support

2019-09-06 Thread Max Filippov
On Fri, Sep 6, 2019 at 2:33 AM Laurent Vivier  wrote:
> Le 26/08/2019 à 21:58, Max Filippov a écrit :
> > +#if defined(TARGET_XTENSA)
> > +if (getenv("QEMU_XTENSA_ABI_CALL0")) {
> > +xtensa_set_abi_call0();
> > +}
>
> Not needed, this is done by parse_args() that checks
> getenv(arginfo->env) and calls arginfo->handle_opt()
> (handle_arg_abi_call0()).

Thank you, I'll fix that. I got confused by the similar handling of
QEMU_STRACE, I'll post a cleanup that removes that as well.

-- 
Thanks.
-- Max



[Qemu-devel] [PATCH v8 27/32] riscv: roms: Update default bios for sifive_u machine

2019-09-06 Thread Bin Meng
With the support of heterogeneous harts and PRCI model, it's now
possible to use the OpenSBI image (PLATFORM=sifive/fu540) built
for the real hardware.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 40968 -> 45064 bytes
 roms/Makefile|   4 ++--
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin 
b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
index 
5d7a1ef6818994bac4a36818ad36043b592ce309..eb22aefdfb468cfe2804cb4b0bc422d8ebcae93b
 100644
GIT binary patch
delta 10830
zcmcI~eOOf0_WwTTaAp|5zy=s$G)G2;B$Y8xQwsqZMktj?Fen8a(7-p07sHnZ7-n!l
zMBCydW6I@gkn_7)_3KlO(VPJ-_F<-9NtbxZHEj
z{_M5aUTf{O*51R;dU|IYeF9VCYY-ChyTdf=_$;$t$%-!FBh)PF2YiLnP#RtlO4
zf`7%(Y^=BI*)uVqWvTi1HA8ri}M#lXXVj799nsK;XrsM6yhpfDIJrX~XyC
z2!|6CowN*ZcY7WO@m?9<2q^Y_gGC}=pjE1PeV*?)24lA+F1Veyny!q&5qy)IT**
z9rPutBL0(>5I47X9AAARDRjwiGOa}(Juz}vMdK*G692<-3vK0Nnc&)lwu}o}=nauO
zcZ?TY@G#q+qP_71r*$d=x5^cU{Rm;*npek1)(iPIr(~VJW~mN-36_!SG&$4uS~~N
zonLU~df7CKT(SnQcb*l>JuB8)tVcB(J|0hh;{4>3FrF7NUbBFQV#_`kT`g;OzrM@A#ALL{
zFTU_?J|jALA1rVijEu5Z$42A<$HLllzdOpW)s4KC2e>p^Za^`^qUJBC{Py4!EA
zutuzHbf2QIpb(0@8y_(H6QcRl+ZIXQ6a)AlE~>f3d6UUogxm|
z*kzH_OU(7-Ptx?B#rQ4vb~<{#`E`#i4*hXk`_T9gC`6$aZcQh)
zV{dOMfP%ff7aUy+I6J_`D7soZ)`!j_sahQuzb>@g*xD?yR~LRZ00n1kc|r)?_U(B6Tyr^792v7v?!|R
zf-X*H>-Ak>>vO=8IlS+h~Y>Fke_l-#wN!wf;{Zxr>5mD#b1Oqq6nuJjfiZDAe
z9+1=DnQRAk$Jl_kV#a`T?ZBk~oPtk`As5?`i^q`D?Z`!d^u$S$QJ%qeWbhbriXHhJ
zAf2(>lu=}m9T_x+^t2;q021N)F{Hm8=|6^awj+HkZq{s^;WNrpVn<5GkjRb{0Wuv+
zq@zerJJNFu*=I+(05TC@97DR;kuGD%yLKc6$mKY1>L^dzj-IBGR@o5jR~9$w0|D(-07zoZw)HjrO(kIKH(9^=JO?UhKu_4FYHvMB-U9Ol5;Tb}yi`Px~pI?{-$hQJQaxrTZ@pusP*TeGUMh6zDgaSIhCttB64
zLcHG{g7y88>$M?kY`UHRT@UV5Dc67>GK61lF|?rnXMP
zS~hy~8X=D-nafgcAga@-Ahnk(7C>)hYpvH!N>PxPz1im`ud8~frT;?jCF_-*Yqx*y
zY;RjLl-|Fw7YY9Dhk}?!5ydp~DNUo=k7AnUQko_u<-=+kR#5S!pR-K!TIzi1Y97f
zbiRV)XkFOKPU~<>8)TZo5!1XJX_~T-ra1+PJ#~~=#HZqSt7CT?4Mk|>ZZVJNR!#Ci
zv_z~@uslOHNT_8Khyd34{(2ES3t4SEOns6}*`hUY{yKdr*CHy{B-^+yxVgj4h;RA
zzZQn^o5RdQp^GV6jd8@HIQn=cKD1~TeWMId4}ZyFVcu__;F;mU_*A$Hy=)MF8Gesm
z)`S14*h)`s#nrKMaC(F%?Rpv)L`(ex{FqhxaI3XiF1*eQ_LJ_67cU@tgFr
z&+yZc-2rK^X8qAGM9>NaM|XljU<~BJfrF~O%|0o?<{Em*3VS4gI6(N~BEJVXXIY
zOWUTyB6tr4?;UrQR%tdE(B(3lr=;G-3DJ|L+01*((zeWKLw0wLB60JBkv=<`?ZlPQ
zVljvAx@l>1HQ45>X|r*AzYSlBe(+*0$e@q>#*hVVVfZ)Tac#@Anpy#pY0ce!6q!Lf
z|H0Rmwr{kVDBA7c{vkmG?=N`1+2{9kKa{L7KBG`>WXXiTek1?JU9ngub
zuN)A{qbI8-v2J)E7l~GoH7X_e;PTf%XEX7`<-K%31GdIy^PvlzmBs7h-k`tv#C#>L
zfTqhzaYFngkGTj18@lPWlD*J3eaQ
zjKSXH*Nxp@*96+1);^NTk37_W5+B=l2BIV}2e>FMDv}*sqbZh3v0
zhwZx$^bQR;7*dG33MJTarAo#1bbJ4KT=Rs3D%vAAKe#+!Iq{s%A(vd$;Gi
zs!3mofQOJ@<2hjwDI_U{>QOf*f$hDYJHD`TN<3hsAJ#lc#z{Y|apT&5)Vlq_rEIc{
z+o^I){_~9LkI4vJ#2xTIu0aB_s7PV^*1P^9tvre%YcXr3
z!JX?}AK;LT8H{Alvp6HegOMX=yfb4KQ|~$SU>c1Jr_cHvL`m&$!gw4|c_ZAM{
zEQK}~r*D3bsSmh~o!-2|)E_@X%g-;b0}?Hw=p)
zga~=n?c5o`s%{_O$oMr3?^UYk2M!``MCwhzzxPMHtPM}h-oZ#N?@0~txi9DFHz
z79a3ftGI-na$*@t(kpm%|1#u7I_MF9Z;vk;BWjd|y#|c|rU?gn|amAKb
zKzMg--4a8qhjI8@DtJ8;o8DT$NZeR_`>h-BJQ26#PMIR9%rX_KUSrXnx@s*IK@M_x
znWn;y2zF?x)^Z}T6}xQpp>K3y`PM0nB*Yyr-wM*TrQ_nQbAm?B83k~fEcQaGi$M(g
z0gOJ8cq35Y8#)|xx^QZ!SF2FqfmB}yQBa-fAPb*3d=>X@okJ&{#?!YwOW!z!leWb?
zb>kzuE(T?gmVt?NS>KHFrb0;9CnkT0FK+XZ9R84`Q0dIhhvuSAq}nt@w9Rsm^tR2NC}O@*eSju7_Ij)Ym2P$bU7RXY@n+lh7f?v9nh
zd0-yBAWFy!AH2pL36q34;q5on{zV$42gN8@idhV`QiLBR_RvyB1D`ryX71)w#{D{o
z`}uxCHiK5}=%Y0eMTl8!K$^w1h*8ua=%>UJ94YfH9vO+uw>+uyyYppd-h)%nYXbWPLYZ0I+ak(QAlH;+>EZQc13jNSmr(f0^WnJ16b33jx5A2~)!ZuUDcKb32~r1!`PH=
z+iFA$SIds+ak-jL=kKj97i#si*hxp9EVi6*{RxgvPfI@-026{an~6EWjLk>Dn_!p1
zHo97Rxzx6O3Ow@n#_6id1GSNq<;12RjYUpKc%=v|Rg7Zv;>+NDuNG5cVr|c2idc!*
z=A1^D;Kc1?*p)05Stj=6QNpbcUGakluC2RYE)#nflO2Zw??zBp%cMslDQVRJt!ZpP
z4DqTa2QZPl%{1Ututr+bJeB6w2;v#{^Wfk`PA9RPy+?QZ)zZK5AA`0IpD}T9+;0XWNGC-@r4${g2x;-N-t164m
zZBGkJuS%Z+R*m0WWv%YH(0QpXZfLbt*V}SCp?_8Hnx6FA8$0tRm>H|za(4M^zL7tzz1*mqhpNke
ztB{^Jg+7!~Bxw
zVhOhmx?U|4i%U@8FKa2`4|-US9@MI*q(|0pczjjx7#tgPuMk3r}-MxLR<@6P16Lf2ChYH%QW^v
zpyPqfJCX6=F3Q~VHRL0(H)ze=viW;V`!4O%Mu38~z9j>~AN3H3^ho%f
zp24r`8KD8_ih#l*c#acrsY6X-63Mq=6G(>r+=Ij?vQtT}_3;#cr>BHJ3h36dDo^99
zdJ4x1=$FebmkF=vX(7o!1rtWOtajwaUllNfTRTfQ!ERy*w=f=Y%GR>adBWTQ
z*O$wx1eeQv)B2zCk_vt5*oi`-wCDA>hEf4wYkLfkx
zETxHp2p{E3F)z-hAOqj@I{(KwLa!r{1kBTRyhnBQC~WdV%2)xRw<{JXl@fcai;=lY
zK^1tsBgo%-0S+K+L`ylb=Sbelx*f4g>Q-*9YLg8`^)Ky>vFbYGdh#6o^)rj1e6-%U
zW-9bLU!BB*+nTW4_N=O0dTV=nGE8_$E95l{l4%2a{EH`@hoZT%?j|E^7(}=(mdT
zvdtBy;(Qq;yQJny+mRwup<-C9^F|kl^(qhlYeTJOYQtb`?WE0Bx2rps4#o7x^(I(X
z_2_z9+Vb2?`eVh!jB#Lp
zs35?G5ZAdt1h#`fSd*DuI1~j(0!w9L+n@U$H&$Fv!fjnAF*oZ?f%Os`YV`;cK~0YEaT3
zk&;;KhEDqYk%zMzK}mx|D^c17f;kjXl}%GbOBU<#9#f&1FF=Zc-$Rq03e^Y)?z=+3
z_JYj?S|hh9woJ&(EgS^B3@+8Z{sri4@RIgJesH;^^2T>(YK3Zk;ot>MO~mmQ?ll!o
z8-`T^_>y)O3*PYUQKBllrg%f7zTr+V*25oBk9j=N4(2rsErok;a$ytj&;xAUFl5r^
zM~nlPlWAvx=<^-y@tpebo&^e|$Bn#u#f{kFIlRZ^G?7M{dgEIpA=K|Ig<2?O9>D
zHlGh$mrT4Kemk;H+@gwOoxskM`i96(;NH6BJ+F;qrZo(bH!^JtX_Wvad

[Qemu-devel] [PATCH v8 26/32] riscv: sifive_u: Change UART node name in device tree

2019-09-06 Thread Bin Meng
OpenSBI for fu540 does DT fix up (see fu540_modify_dt()) by updating
chosen "stdout-path" to point to "/soc/serial@...", and U-Boot will
use this information to locate the serial node and probe its driver.
However currently we generate the UART node name as "/soc/uart@...",
causing U-Boot fail to find the serial node in DT.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index a3ee1ec..5ca3793 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -286,7 +286,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
-nodename = g_strdup_printf("/soc/uart@%lx",
+nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
-- 
2.7.4




[Qemu-devel] [PATCH v8 22/32] riscv: sifive_u: Generate hfclk and rtcclk nodes

2019-09-06 Thread Bin Meng
To keep in sync with Linux kernel device tree, generate hfclk and
rtcclk nodes in the device tree, to be referenced by PRCI node.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 23 +++
 include/hw/riscv/sifive_u.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 713c451..3ee6fcb 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -79,6 +79,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
 uint32_t plic_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
+uint32_t hfclk_phandle, rtcclk_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
 if (!fdt) {
@@ -97,6 +98,28 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
 
+hfclk_phandle = phandle++;
+nodename = g_strdup_printf("/hfclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", hfclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "hfclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_HFCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
+rtcclk_phandle = phandle++;
+nodename = g_strdup_printf("/rtcclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", rtcclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "rtcclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_RTCCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/memory@%lx",
 (long)memmap[SIFIVE_U_DRAM].base);
 qemu_fdt_add_subnode(fdt, nodename);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 6b2b5b6..2441814 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -69,6 +69,8 @@ enum {
 
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
+SIFIVE_U_HFCLK_FREQ = ,
+SIFIVE_U_RTCCLK_FREQ = 100,
 SIFIVE_U_GEM_CLOCK_FREQ = 12500
 };
 
-- 
2.7.4




[Qemu-devel] [Bug 1843073] Re: Network loose connection for long time under light load guest winxp64 with virtio on i5-8350U

2019-09-06 Thread uvi
Ping at the load moment:
 ping 192.168.152.25
PING 192.168.152.25 (192.168.152.25) 56(84) bytes of data.
64 bytes from 192.168.152.25: icmp_seq=1 ttl=128 time=0.300 ms
64 bytes from 192.168.152.25: icmp_seq=2 ttl=128 time=0.495 ms
64 bytes from 192.168.152.25: icmp_seq=3 ttl=128 time=0.442 ms
64 bytes from 192.168.152.25: icmp_seq=4 ttl=128 time=0.520 ms
64 bytes from 192.168.152.25: icmp_seq=5 ttl=128 time=0.558 ms
64 bytes from 192.168.152.25: icmp_seq=6 ttl=128 time=0.623 ms
64 bytes from 192.168.152.25: icmp_seq=7 ttl=128 time=0.668 ms
64 bytes from 192.168.152.25: icmp_seq=8 ttl=128 time=0.574 ms
64 bytes from 192.168.152.25: icmp_seq=9 ttl=128 time=0.390 ms
64 bytes from 192.168.152.25: icmp_seq=10 ttl=128 time=363 ms
>From 192.168.152.1 icmp_seq=29 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=30 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=31 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=32 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=33 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=34 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=36 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=39 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=40 Destination Host Unreachable
64 bytes from 192.168.152.25: icmp_seq=11 ttl=128 time=33151 ms
64 bytes from 192.168.152.25: icmp_seq=12 ttl=128 time=32137 ms
>From 192.168.152.1 icmp_seq=41 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=42 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=43 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=44 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=45 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=46 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=47 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=48 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=49 Destination Host Unreachable
>From 192.168.152.1 icmp_seq=50 Destination Host Unreachable
64 bytes from 192.168.152.25: icmp_seq=13 ttl=128 time=39259 ms
64 bytes from 192.168.152.25: icmp_seq=14 ttl=128 time=38235 ms
64 bytes from 192.168.152.25: icmp_seq=15 ttl=128 time=37211 ms
64 bytes from 192.168.152.25: icmp_seq=16 ttl=128 time=36187 ms
64 bytes from 192.168.152.25: icmp_seq=17 ttl=128 time=35163 ms
64 bytes from 192.168.152.25: icmp_seq=18 ttl=128 time=34139 ms
64 bytes from 192.168.152.25: icmp_seq=19 ttl=128 time=33115 ms
64 bytes from 192.168.152.25: icmp_seq=20 ttl=128 time=32091 ms
64 bytes from 192.168.152.25: icmp_seq=21 ttl=128 time=31068 ms
64 bytes from 192.168.152.25: icmp_seq=22 ttl=128 time=30044 ms
64 bytes from 192.168.152.25: icmp_seq=23 ttl=128 time=29020 ms
64 bytes from 192.168.152.25: icmp_seq=24 ttl=128 time=27996 ms
64 bytes from 192.168.152.25: icmp_seq=25 ttl=128 time=26968 ms
64 bytes from 192.168.152.25: icmp_seq=26 ttl=128 time=25948 ms
64 bytes from 192.168.152.25: icmp_seq=27 ttl=128 time=24924 ms
64 bytes from 192.168.152.25: icmp_seq=28 ttl=128 time=23900 ms
64 bytes from 192.168.152.25: icmp_seq=51 ttl=128 time=412 ms
64 bytes from 192.168.152.25: icmp_seq=52 ttl=128 time=0.167 ms
64 bytes from 192.168.152.25: icmp_seq=53 ttl=128 time=0.559 ms
64 bytes from 192.168.152.25: icmp_seq=54 ttl=128 time=0.656 ms

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

Title:
  Network loose connection for long time under light load guest winxp64
  with virtio on i5-8350U

Status in QEMU:
  New

Bug description:
  I have issue with qemu and winxp guest on i5-8350U.

  First of all, if i run same vm with same config on i5 9660k i do not see such 
issue.
  Both pc have ubuntu 19.04 x86_64.

  Guest is winxp64, tried:
  1) stable guest drivers, latest drivers
  2) all virtio, only network r18169, bridge to host eth0, just default virbr0.
  3) qemu from ubuntu 19.04, and tried latest libvirt and qeumu compiled from 
sources.
  4) tried zram as block device

  I need really lightweight win to run only one app, so win7 and win10
  is not an option.

  
  

  
winxp
93921ab3-222a-4e5f-89c4-36703fc65cb4

  http://libosinfo.org/xmlns/libvirt/domain/1.0;>
http://microsoft.com/win/xp"/>
  

8388608
8388608
4

  
  
  
  


  hvm


  
  
  






  
  


  


  
  
  
  

destroy
restart
destroy

  
  


  /usr/local/bin/qemu-system-x86_64
  






  
  





  
  

  
  


  
  


  
  


  
  
  

  
  

  
  



   

[Qemu-devel] [PATCH v8 20/32] riscv: sifive_u: Update PLIC hart topology configuration string

2019-09-06 Thread Bin Meng
With heterogeneous harts config, the PLIC hart topology configuration
string are "M,MS,.." because of the monitor hart #0.

Suggested-by: Fabien Chouteau 
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6c4634d..713c451 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -424,10 +424,11 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 plic_hart_config = g_malloc0(plic_hart_config_len);
 for (i = 0; i < ms->smp.cpus; i++) {
 if (i != 0) {
-strncat(plic_hart_config, ",", plic_hart_config_len);
+strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG,
+plic_hart_config_len);
+} else {
+strncat(plic_hart_config, "M", plic_hart_config_len);
 }
-strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
-plic_hart_config_len);
 plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH v8 30/32] riscv: sifive_u: Fix broken GEM support

2019-09-06 Thread Bin Meng
At present the GEM support in sifive_u machine is seriously broken.
The GEM block register base was set to a weird number (0x100900FC),
which for no way could work with the cadence_gem model in QEMU.

Not like other GEM variants, the FU540-specific GEM has a management
block to control 10/100/1000Mbps link speed changes, that is mapped
to 0x100a. We can simply map it into MMIO space without special
handling using create_unimplemented_device().

Update the GEM node compatible string to use the official name used
by the upstream Linux kernel, and add the management block reg base
& size to the  property encoding.

Tested with upstream U-Boot and Linux kernel MACB drivers.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8:
- select UNIMP in sifive_u Kconfig due to applied commit
  "hw/misc: Add a config switch for the "unimplemented" device"
  in latest qemu/master

Changes in v7: None
Changes in v6: None
Changes in v5:
- add the missing "local-mac-address" property in the ethernet node

Changes in v4: None
Changes in v3: None
Changes in v2:
- use create_unimplemented_device() to create the GEM management
  block instead of sifive_mmio_emulate()
- add "phy-handle" property to the ethernet node

 hw/riscv/Kconfig|  1 +
 hw/riscv/sifive_u.c | 24 
 include/hw/riscv/sifive_u.h |  3 ++-
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 33e54b0..fb19b2d 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -19,6 +19,7 @@ config SIFIVE_U
 select CADENCE
 select HART
 select SIFIVE
+select UNIMP
 
 config SPIKE
 bool
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 4803e47..3b61fab 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
  * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
  *
  * Provides a board compatible with the SiFive Freedom U SDK:
  *
@@ -11,6 +12,7 @@
  * 2) PLIC (Platform Level Interrupt Controller)
  * 3) PRCI (Power, Reset, Clock, Interrupt)
  * 4) OTP (One-Time Programmable) memory with stored serial number
+ * 5) GEM (Gigabit Ethernet Controller) and management block
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -37,6 +39,7 @@
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
 #include "hw/cpu/cluster.h"
+#include "hw/misc/unimp.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
@@ -45,6 +48,7 @@
 #include "hw/riscv/sifive_u.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
+#include "net/eth.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
@@ -67,7 +71,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
-[SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
+[SIFIVE_U_GEM] =  { 0x1009, 0x2000 },
+[SIFIVE_U_GEM_MGMT] = { 0x100a, 0x1000 },
 };
 
 #define OTP_SERIAL  1
@@ -84,7 +89,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char ethclk_names[] = "pclk\0hclk";
 uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
-uint32_t hfclk_phandle, rtcclk_phandle;
+uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
 if (!fdt) {
@@ -254,21 +259,28 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
+phy_phandle = phandle++;
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "cdns,macb");
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-gem");
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_GEM].base,
-0x0, memmap[SIFIVE_U_GEM].size);
+0x0, memmap[SIFIVE_U_GEM].size,
+0x0, memmap[SIFIVE_U_GEM_MGMT].base,
+0x0, memmap[SIFIVE_U_GEM_MGMT].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
+qemu_fdt_setprop_cell(fdt, nodename, "phy-handle", phy_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
 prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
 qemu_fdt_setprop(fdt, 

Re: [Qemu-devel] [PATCH] riscv: hw: Remove duplicated "hw/hw.h" inclusion

2019-09-06 Thread Bin Meng
Hello,

On Fri, Sep 6, 2019 at 11:22 PM Bin Meng  wrote:
>
> On Fri, Sep 6, 2019 at 11:09 PM Bin Meng  wrote:
> >
> > Commit a27bd6c779ba ("Include hw/qdev-properties.h less") wrongly
> > added "hw/hw.h" to sifive_prci.c and sifive_test.c.
> >
> > Another inclusion of "hw/hw.h" was later added via
> > commit 650d103d3ea9 ("Include hw/hw.h exactly where needed"), that
> > resulted in duplicated inclusion of "hw/hw.h".
> >
> > Fixes: a27bd6c779ba ("Include hw/qdev-properties.h less")
> > Signed-off-by: Bin Meng 
> > ---
> >
> >  hw/riscv/sifive_prci.c | 1 -
> >  hw/riscv/sifive_test.c | 1 -
> >  2 files changed, 2 deletions(-)
> >
>
> Sigh, I just realized that this patch has inter-dependencies with the
> following patch series:
>
> riscv: sifive_test: Add reset functionality
> http://patchwork.ozlabs.org/patch/1158526/
>
> and
>
> riscv: sifive_u: Improve the emulation fidelity of sifive_u machine
> http://patchwork.ozlabs.org/project/qemu-devel/list/?series=128443
>
> Thus cannot be applied cleanly on top of qemu/master.
>
> If I create this patch on qemu/master, that means the other 2 series
> needs to be rebased again.
>

I've included this single patch to my v8 version of "riscv: sifive_u:
Improve the emulation fidelity of sifive_u machine", to ease patch
inter-dependencies, so that the whole v8 series can be applied on
Palmer's RISC-V queue.

See http://patchwork.ozlabs.org/patch/1159111/

So, please ignore this single patch.

Regards,
Bin



[Qemu-devel] [PATCH v8 17/32] riscv: hart: Add a "hartid-base" property to RISC-V hart array

2019-09-06 Thread Bin Meng
At present each hart's hartid in a RISC-V hart array is assigned
the same value of its index in the hart array. But for a system
that has multiple hart arrays, this is not the case any more.

Add a new "hartid-base" property so that hartid number can be
assigned based on the property value.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7:
- use `s->hartid_base + idx` directly

Changes in v6:
- use s->hartid_base directly, instead of an extra variable

Changes in v5: None
Changes in v4:
- new patch to add a "hartid-base" property to RISC-V hart array

Changes in v3: None
Changes in v2: None

 hw/riscv/riscv_hart.c | 3 ++-
 include/hw/riscv/riscv_hart.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 6620e41..5b98227 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -29,6 +29,7 @@
 
 static Property riscv_harts_props[] = {
 DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
+DEFINE_PROP_UINT32("hartid-base", RISCVHartArrayState, hartid_base, 0),
 DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -47,7 +48,7 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
idx,
 object_initialize_child(OBJECT(s), "harts[*]", >harts[idx],
 sizeof(RISCVCPU), cpu_type,
 _abort, NULL);
-s->harts[idx].env.mhartid = idx;
+s->harts[idx].env.mhartid = s->hartid_base + idx;
 qemu_register_reset(riscv_harts_cpu_reset, >harts[idx]);
 object_property_set_bool(OBJECT(>harts[idx]), true,
  "realized", );
diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
index 3b52b50..c75856f 100644
--- a/include/hw/riscv/riscv_hart.h
+++ b/include/hw/riscv/riscv_hart.h
@@ -35,6 +35,7 @@ typedef struct RISCVHartArrayState {
 
 /*< public >*/
 uint32_t num_harts;
+uint32_t hartid_base;
 char *cpu_type;
 RISCVCPU *harts;
 } RISCVHartArrayState;
-- 
2.7.4




[Qemu-devel] [Bug 1843073] [NEW] Network loose connection for long time under light load guest winxp64 with virtio on i5-8350U

2019-09-06 Thread uvi
Public bug reported:

I have issue with qemu and winxp guest on i5-8350U.

First of all, if i run same vm with same config on i5 9660k i do not see such 
issue.
Both pc have ubuntu 19.04 x86_64.

Guest is winxp64, tried:
1) stable guest drivers, latest drivers
2) all virtio, only network r18169, bridge to host eth0, just default virbr0.
3) qemu from ubuntu 19.04, and tried latest libvirt and qeumu compiled from 
sources.
4) tried zram as block device

I need really lightweight win to run only one app, so win7 and win10 is
not an option.





  winxp
  93921ab3-222a-4e5f-89c4-36703fc65cb4
  
http://libosinfo.org/xmlns/libvirt/domain/1.0;>
  http://microsoft.com/win/xp"/>

  
  8388608
  8388608
  4
  




  
  
hvm
  
  



  
  
  
  
  
  


  
  

  
  




  
  destroy
  restart
  destroy
  


  
  
/usr/local/bin/qemu-system-x86_64

  
  
  
  
  
  


  
  
  
  
  


  


  
  


  
  


  
  



  


  


  
  
  
  


  

  


  


  




  
  
  
  
  
  


  


  
  


  

  


** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Network loose connection for long time under light load guest winxp64
  with virtio on i5-8350U

Status in QEMU:
  New

Bug description:
  I have issue with qemu and winxp guest on i5-8350U.

  First of all, if i run same vm with same config on i5 9660k i do not see such 
issue.
  Both pc have ubuntu 19.04 x86_64.

  Guest is winxp64, tried:
  1) stable guest drivers, latest drivers
  2) all virtio, only network r18169, bridge to host eth0, just default virbr0.
  3) qemu from ubuntu 19.04, and tried latest libvirt and qeumu compiled from 
sources.
  4) tried zram as block device

  I need really lightweight win to run only one app, so win7 and win10
  is not an option.

  
  

  
winxp
93921ab3-222a-4e5f-89c4-36703fc65cb4

  http://libosinfo.org/xmlns/libvirt/domain/1.0;>
http://microsoft.com/win/xp"/>
  

8388608
8388608
4

  
  
  
  


  hvm


  
  
  






  
  


  


  
  
  
  

destroy
restart
destroy

  
  


  /usr/local/bin/qemu-system-x86_64
  






  
  





  
  

  
  


  
  


  
  


  
  
  

  
  

  
  




  
  

  

  
  

  
  

  
  
  
  






  
  

  
  


  
  

  

  

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



[Qemu-devel] [PATCH v8 31/32] riscv: sifive_u: Remove handcrafted clock nodes for UART and ethernet

2019-09-06 Thread Bin Meng
In the past we did not have a model for PRCI, hence two handcrafted
clock nodes ("/soc/ethclk" and "/soc/uartclk") were created for the
purpose of supplying hard-coded clock frequencies. But now since we
have added the PRCI support in QEMU, we don't need them any more.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch to remove handcrafted clock nodes for UART and ethernet

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 24 +---
 include/hw/riscv/sifive_u.h |  3 +--
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 3b61fab..507a6e2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -87,8 +87,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uint32_t *cells;
 char *nodename;
 char ethclk_names[] = "pclk\0hclk";
-uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
-uint32_t uartclk_phandle;
+uint32_t plic_phandle, prci_phandle, phandle = 1;
 uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
@@ -248,17 +247,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
-ethclk_phandle = phandle++;
-nodename = g_strdup_printf("/soc/ethclk");
-qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
-qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-SIFIVE_U_GEM_CLOCK_FREQ);
-qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
-g_free(nodename);
-
 phy_phandle = phandle++;
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
@@ -292,16 +280,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
-uartclk_phandle = phandle++;
-nodename = g_strdup_printf("/soc/uartclk");
-qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
-qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
-qemu_fdt_setprop_cell(fdt, nodename, "phandle", uartclk_phandle);
-uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
-g_free(nodename);
-
 nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 5270851..e4df298 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -77,8 +77,7 @@ enum {
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
 SIFIVE_U_HFCLK_FREQ = ,
-SIFIVE_U_RTCCLK_FREQ = 100,
-SIFIVE_U_GEM_CLOCK_FREQ = 12500
+SIFIVE_U_RTCCLK_FREQ = 100
 };
 
 #define SIFIVE_U_MANAGEMENT_CPU_COUNT   1
-- 
2.7.4




[Qemu-devel] [PATCH v8 11/32] riscv: sifive: Rename sifive_prci.{c, h} to sifive_e_prci.{c, h}

2019-09-06 Thread Bin Meng
Current SiFive PRCI model only works with sifive_e machine, as it
only emulates registers or PRCI block in the FE310 SoC.

Rename the file name to make it clear that it is for sifive_e.
This also prefix "sifive_e"/"SIFIVE_E" for all macros, variables
and functions.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- prefix all macros/variables/functions with SIFIVE_E/sifive_e
  in the sifive_e_prci driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs  |  2 +-
 hw/riscv/sifive_e.c |  4 +-
 hw/riscv/{sifive_prci.c => sifive_e_prci.c} | 79 ++---
 include/hw/riscv/sifive_e_prci.h| 69 +
 include/hw/riscv/sifive_prci.h  | 71 --
 5 files changed, 111 insertions(+), 114 deletions(-)
 rename hw/riscv/{sifive_prci.c => sifive_e_prci.c} (51%)
 create mode 100644 include/hw/riscv/sifive_e_prci.h
 delete mode 100644 include/hw/riscv/sifive_prci.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index eb9d4f9..c859697 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -2,9 +2,9 @@ obj-y += boot.o
 obj-$(CONFIG_SPIKE) += riscv_htif.o
 obj-$(CONFIG_HART) += riscv_hart.o
 obj-$(CONFIG_SIFIVE_E) += sifive_e.o
+obj-$(CONFIG_SIFIVE_E) += sifive_e_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_clint.o
 obj-$(CONFIG_SIFIVE) += sifive_gpio.o
-obj-$(CONFIG_SIFIVE) += sifive_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 792d75a..1428a99 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -40,9 +40,9 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_e.h"
+#include "hw/riscv/sifive_e_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
@@ -174,7 +174,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
 memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
-sifive_prci_create(memmap[SIFIVE_E_PRCI].base);
+sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
 
 /* GPIO */
 
diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_e_prci.c
similarity index 51%
rename from hw/riscv/sifive_prci.c
rename to hw/riscv/sifive_e_prci.c
index c413f0c..b6d32db 100644
--- a/hw/riscv/sifive_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -1,5 +1,5 @@
 /*
- * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt)
+ * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt)
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
@@ -23,19 +23,19 @@
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "hw/hw.h"
-#include "hw/riscv/sifive_prci.h"
+#include "hw/riscv/sifive_e_prci.h"
 
-static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
+static uint64_t sifive_e_prci_read(void *opaque, hwaddr addr, unsigned int 
size)
 {
-SiFivePRCIState *s = opaque;
+SiFiveEPRCIState *s = opaque;
 switch (addr) {
-case SIFIVE_PRCI_HFROSCCFG:
+case SIFIVE_E_PRCI_HFROSCCFG:
 return s->hfrosccfg;
-case SIFIVE_PRCI_HFXOSCCFG:
+case SIFIVE_E_PRCI_HFXOSCCFG:
 return s->hfxosccfg;
-case SIFIVE_PRCI_PLLCFG:
+case SIFIVE_E_PRCI_PLLCFG:
 return s->pllcfg;
-case SIFIVE_PRCI_PLLOUTDIV:
+case SIFIVE_E_PRCI_PLLOUTDIV:
 return s->plloutdiv;
 }
 qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n",
@@ -43,27 +43,27 @@ static uint64_t sifive_prci_read(void *opaque, hwaddr addr, 
unsigned int size)
 return 0;
 }
 
-static void sifive_prci_write(void *opaque, hwaddr addr,
-   uint64_t val64, unsigned int size)
+static void sifive_e_prci_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
 {
-SiFivePRCIState *s = opaque;
+SiFiveEPRCIState *s = opaque;
 switch (addr) {
-case SIFIVE_PRCI_HFROSCCFG:
+case SIFIVE_E_PRCI_HFROSCCFG:
 s->hfrosccfg = (uint32_t) val64;
 /* OSC stays ready */
-s->hfrosccfg |= SIFIVE_PRCI_HFROSCCFG_RDY;
+s->hfrosccfg |= SIFIVE_E_PRCI_HFROSCCFG_RDY;
 break;
-case SIFIVE_PRCI_HFXOSCCFG:
+case SIFIVE_E_PRCI_HFXOSCCFG:
 s->hfxosccfg = (uint32_t) val64;
 /* OSC stays ready */
-s->hfxosccfg |= SIFIVE_PRCI_HFXOSCCFG_RDY;
+s->hfxosccfg |= SIFIVE_E_PRCI_HFXOSCCFG_RDY;
 break;
-case SIFIVE_PRCI_PLLCFG:
+case SIFIVE_E_PRCI_PLLCFG:
 s->pllcfg = (uint32_t) val64;
 /* PLL stays locked */
-  

[Qemu-devel] [PATCH v8 28/32] riscv: sifive: Implement a model for SiFive FU540 OTP

2019-09-06 Thread Bin Meng
This implements a simple model for SiFive FU540 OTP (One-Time
Programmable) Memory interface, primarily for reading out the
stored serial number from the first 1 KiB of the 16 KiB OTP
memory reserved by SiFive for internal use.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8:
- Don't cast addr to an int, use the correct macros in
  sifive_u_otp_read() and sifive_u_otp_write()
- Include "hw/qdev-properties.h" in sifive_u_otp.c

Changes in v7: None
Changes in v6: None
Changes in v5:
- change to use defines instead of enums
- change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_otp
- creating a 32-bit val variable and using that instead of casting
  everywhere in sifive_u_otp_write()
- move all register initialization to sifive_u_otp_reset() function
- drop sifive_u_otp_create()

Changes in v4:
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_otp driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs  |   1 +
 hw/riscv/sifive_u_otp.c | 191 
 include/hw/riscv/sifive_u_otp.h |  80 +
 3 files changed, 272 insertions(+)
 create mode 100644 hw/riscv/sifive_u_otp.c
 create mode 100644 include/hw/riscv/sifive_u_otp.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index b95bbd5..fc3c6dd 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_otp.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
diff --git a/hw/riscv/sifive_u_otp.c b/hw/riscv/sifive_u_otp.c
new file mode 100644
index 000..ea0eee5
--- /dev/null
+++ b/hw/riscv/sifive_u_otp.c
@@ -0,0 +1,191 @@
+/*
+ * QEMU SiFive U OTP (One-Time Programmable) Memory interface
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the OTP to emulate register reads made by the SDK BSP
+ *
+ * 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/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/riscv/sifive_u_otp.h"
+
+static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, unsigned int size)
+{
+SiFiveUOTPState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_OTP_PA:
+return s->pa;
+case SIFIVE_U_OTP_PAIO:
+return s->paio;
+case SIFIVE_U_OTP_PAS:
+return s->pas;
+case SIFIVE_U_OTP_PCE:
+return s->pce;
+case SIFIVE_U_OTP_PCLK:
+return s->pclk;
+case SIFIVE_U_OTP_PDIN:
+return s->pdin;
+case SIFIVE_U_OTP_PDOUT:
+if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
+(s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
+(s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
+return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
+} else {
+return 0xff;
+}
+case SIFIVE_U_OTP_PDSTB:
+return s->pdstb;
+case SIFIVE_U_OTP_PPROG:
+return s->pprog;
+case SIFIVE_U_OTP_PTC:
+return s->ptc;
+case SIFIVE_U_OTP_PTM:
+return s->ptm;
+case SIFIVE_U_OTP_PTM_REP:
+return s->ptm_rep;
+case SIFIVE_U_OTP_PTR:
+return s->ptr;
+case SIFIVE_U_OTP_PTRIM:
+return s->ptrim;
+case SIFIVE_U_OTP_PWE:
+return s->pwe;
+}
+
+qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+static void sifive_u_otp_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+SiFiveUOTPState *s = opaque;
+uint32_t val32 = (uint32_t)val64;
+
+switch (addr) {
+case SIFIVE_U_OTP_PA:
+s->pa = val32 & SIFIVE_U_OTP_PA_MASK;
+break;
+case SIFIVE_U_OTP_PAIO:
+s->paio = val32;
+break;
+case SIFIVE_U_OTP_PAS:
+s->pas = val32;
+break;
+case SIFIVE_U_OTP_PCE:
+s->pce = val32;
+break;
+case SIFIVE_U_OTP_PCLK:
+s->pclk = val32;
+break;
+case SIFIVE_U_OTP_PDIN:
+s->pdin = val32;
+break;
+case SIFIVE_U_OTP_PDOUT:
+/* read-only */
+break;
+case SIFIVE_U_OTP_PDSTB:
+ 

[Qemu-devel] [PATCH v8 32/32] riscv: sifive_u: Update model and compatible strings in device tree

2019-09-06 Thread Bin Meng
This updates model and compatible strings to use the same strings
as used in the Linux kernel device tree (hifive-unleashed-a00.dts).

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 507a6e2..ca9f7fe 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -96,8 +96,9 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 exit(1);
 }
 
-qemu_fdt_setprop_string(fdt, "/", "model", "ucbbar,spike-bare,qemu");
-qemu_fdt_setprop_string(fdt, "/", "compatible", "ucbbar,spike-bare-dev");
+qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
+qemu_fdt_setprop_string(fdt, "/", "compatible",
+"sifive,hifive-unleashed-a00");
 qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
 
-- 
2.7.4




Re: [Qemu-devel] [PATCH v8 09/32] riscv: roms: Remove executable attribute of opensbi images

2019-09-06 Thread Philippe Mathieu-Daudé
On 9/6/19 6:19 PM, Bin Meng wrote:
> Like other binary files, the executable attribute of opensbi images
> should not be set.

Ideally we'd have checkpatch warning for incorrect permissions when
adding blobs under pc-bios/.

> 
> Signed-off-by: Bin Meng 
> Reviewed-by: Alistair Francis 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
> 
> Changes in v8: None
> Changes in v7: None
> Changes in v6: None
> Changes in v5: None
> Changes in v4:
> - new patch to remove executable attribute of opensbi images
> 
> Changes in v3: None
> Changes in v2: None
> 
>  pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin
>  pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin
>  pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin
>  3 files changed, 0 insertions(+), 0 deletions(-)
>  mode change 100755 => 100644 pc-bios/opensbi-riscv32-virt-fw_jump.bin
>  mode change 100755 => 100644 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
>  mode change 100755 => 100644 pc-bios/opensbi-riscv64-virt-fw_jump.bin
> 
> diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin 
> b/pc-bios/opensbi-riscv32-virt-fw_jump.bin
> old mode 100755
> new mode 100644
> diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin 
> b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
> old mode 100755
> new mode 100644
> diff --git a/pc-bios/opensbi-riscv64-virt-fw_jump.bin 
> b/pc-bios/opensbi-riscv64-virt-fw_jump.bin
> old mode 100755
> new mode 100644
> 



[Qemu-devel] [PATCH v8 12/32] riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming

2019-09-06 Thread Bin Meng
For hfxosccfg register programming, SIFIVE_E_PRCI_HFXOSCCFG_RDY and
SIFIVE_E_PRCI_HFXOSCCFG_EN should be used.

Signed-off-by: Bin Meng 
Acked-by: Alistair Francis 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Philippe Mathieu-Daudé 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_e_prci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_e_prci.c b/hw/riscv/sifive_e_prci.c
index b6d32db..bfe9b13 100644
--- a/hw/riscv/sifive_e_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -91,7 +91,7 @@ static void sifive_e_prci_init(Object *obj)
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
-s->hfxosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
+s->hfxosccfg = (SIFIVE_E_PRCI_HFXOSCCFG_RDY | SIFIVE_E_PRCI_HFXOSCCFG_EN);
 s->pllcfg = (SIFIVE_E_PRCI_PLLCFG_REFSEL | SIFIVE_E_PRCI_PLLCFG_BYPASS |
  SIFIVE_E_PRCI_PLLCFG_LOCK);
 s->plloutdiv = SIFIVE_E_PRCI_PLLOUTDIV_DIV1;
-- 
2.7.4




[Qemu-devel] [PATCH v8 29/32] riscv: sifive_u: Instantiate OTP memory with a serial number

2019-09-06 Thread Bin Meng
This adds an OTP memory with a given serial number to the sifive_u
machine. With such support, the upstream U-Boot for sifive_fu540
boots out of the box on the sifive_u machine.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
- create sifive_u_otp block directly in the machine codes, instead
  of calling sifive_u_otp_create()

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 9 +
 include/hw/riscv/sifive_u.h | 3 +++
 2 files changed, 12 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5ca3793..4803e47 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,6 +10,7 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  * 3) PRCI (Power, Reset, Clock, Interrupt)
+ * 4) OTP (One-Time Programmable) memory with stored serial number
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -64,10 +65,12 @@ static const struct MemmapEntry {
 [SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
+[SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
 };
 
+#define OTP_SERIAL  1
 #define GEM_REVISION0x10070109
 
 static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
@@ -422,6 +425,9 @@ static void riscv_sifive_u_soc_init(Object *obj)
 
 sysbus_init_child_obj(obj, "prci", >prci, sizeof(s->prci),
   TYPE_SIFIVE_U_PRCI);
+sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
+  TYPE_SIFIVE_U_OTP);
+qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
 sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
   TYPE_CADENCE_GEM);
 }
@@ -498,6 +504,9 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 object_property_set_bool(OBJECT(>prci), true, "realized", );
 sysbus_mmio_map(SYS_BUS_DEVICE(>prci), 0, memmap[SIFIVE_U_PRCI].base);
 
+object_property_set_bool(OBJECT(>otp), true, "realized", );
+sysbus_mmio_map(SYS_BUS_DEVICE(>otp), 0, memmap[SIFIVE_U_OTP].base);
+
 for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
 plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
 }
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 7dfd1cb..4d4733c 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -23,6 +23,7 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_cpu.h"
 #include "hw/riscv/sifive_u_prci.h"
+#include "hw/riscv/sifive_u_otp.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -39,6 +40,7 @@ typedef struct SiFiveUSoCState {
 RISCVHartArrayState u_cpus;
 DeviceState *plic;
 SiFiveUPRCIState prci;
+SiFiveUOTPState otp;
 CadenceGEMState gem;
 } SiFiveUSoCState;
 
@@ -60,6 +62,7 @@ enum {
 SIFIVE_U_PRCI,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
+SIFIVE_U_OTP,
 SIFIVE_U_DRAM,
 SIFIVE_U_GEM
 };
-- 
2.7.4




[Qemu-devel] [PATCH v8 25/32] riscv: sifive_u: Update UART base addresses and IRQs

2019-09-06 Thread Bin Meng
This updates the UART base address and IRQs to match the hardware.

Signed-off-by: Bin Meng 
Reviewed-by: Jonathan Behrens 
Acked-by: Alistair Francis 
Reviewed-by: Chih-Min Chao 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- update IRQ numbers of both UARTs to match hardware as well

Changes in v2: None

 hw/riscv/sifive_u.c | 4 ++--
 include/hw/riscv/sifive_u.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ea21095..a3ee1ec 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -62,8 +62,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
 [SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
-[SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
-[SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
+[SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
+[SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
 };
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index bb46745..7dfd1cb 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -65,8 +65,8 @@ enum {
 };
 
 enum {
-SIFIVE_U_UART0_IRQ = 3,
-SIFIVE_U_UART1_IRQ = 4,
+SIFIVE_U_UART0_IRQ = 4,
+SIFIVE_U_UART1_IRQ = 5,
 SIFIVE_U_GEM_IRQ = 0x35
 };
 
-- 
2.7.4




[Qemu-devel] [PATCH v8 21/32] riscv: sifive: Implement PRCI model for FU540

2019-09-06 Thread Bin Meng
This adds a simple PRCI model for FU540 (sifive_u). It has different
register layout from the existing PRCI model for FE310 (sifive_e).

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6:
- fix incorrectly indented comment lines
- remove unneeded brackets around assignment

Changes in v5:
- change to use defines instead of enums
- change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci
- creating a 32-bit val variable and using that instead of casting
  everywhere in sifive_u_prci_write()
- move all register initialization to sifive_u_prci_reset() function
- drop sifive_u_prci_create()
- s/codes that worked/code that works/g

Changes in v4:
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_prci driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs   |   1 +
 hw/riscv/sifive_u_prci.c | 169 +++
 include/hw/riscv/sifive_u_prci.h |  81 +++
 3 files changed, 251 insertions(+)
 create mode 100644 hw/riscv/sifive_u_prci.c
 create mode 100644 include/hw/riscv/sifive_u_prci.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index c859697..b95bbd5 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
 obj-$(CONFIG_RISCV_VIRT) += virt.o
diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c
new file mode 100644
index 000..4fa590c
--- /dev/null
+++ b/hw/riscv/sifive_u_prci.c
@@ -0,0 +1,169 @@
+/*
+ * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt)
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the PRCI to emulate register reads made by the SDK BSP
+ *
+ * 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/sysbus.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/riscv/sifive_u_prci.h"
+
+static uint64_t sifive_u_prci_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+SiFiveUPRCIState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_PRCI_HFXOSCCFG:
+return s->hfxosccfg;
+case SIFIVE_U_PRCI_COREPLLCFG0:
+return s->corepllcfg0;
+case SIFIVE_U_PRCI_DDRPLLCFG0:
+return s->ddrpllcfg0;
+case SIFIVE_U_PRCI_DDRPLLCFG1:
+return s->ddrpllcfg1;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
+return s->gemgxlpllcfg0;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG1:
+return s->gemgxlpllcfg1;
+case SIFIVE_U_PRCI_CORECLKSEL:
+return s->coreclksel;
+case SIFIVE_U_PRCI_DEVICESRESET:
+return s->devicesreset;
+case SIFIVE_U_PRCI_CLKMUXSTATUS:
+return s->clkmuxstatus;
+}
+
+qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+
+return 0;
+}
+
+static void sifive_u_prci_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
+{
+SiFiveUPRCIState *s = opaque;
+uint32_t val32 = (uint32_t)val64;
+
+switch (addr) {
+case SIFIVE_U_PRCI_HFXOSCCFG:
+s->hfxosccfg = val32;
+/* OSC stays ready */
+s->hfxosccfg |= SIFIVE_U_PRCI_HFXOSCCFG_RDY;
+break;
+case SIFIVE_U_PRCI_COREPLLCFG0:
+s->corepllcfg0 = val32;
+/* internal feedback */
+s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_DDRPLLCFG0:
+s->ddrpllcfg0 = val32;
+/* internal feedback */
+s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_DDRPLLCFG1:
+s->ddrpllcfg1 = val32;
+break;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
+s->gemgxlpllcfg0 = val32;
+/* internal feedback */
+s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG1:
+s->gemgxlpllcfg1 = 

[Qemu-devel] [PATCH v8 24/32] riscv: sifive_u: Reference PRCI clocks in UART and ethernet nodes

2019-09-06 Thread Bin Meng
Now that we have added a PRCI node, update existing UART and ethernet
nodes to reference PRCI as their clock sources, to keep in sync with
the Linux kernel device tree.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c  |  7 ---
 include/hw/riscv/sifive_u_prci.h | 10 ++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ff2e28e..ea21095 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -78,7 +78,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 int cpu;
 uint32_t *cells;
 char *nodename;
-char ethclk_names[] = "pclk\0hclk\0tx_clk";
+char ethclk_names[] = "pclk\0hclk";
 uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
 uint32_t hfclk_phandle, rtcclk_phandle;
@@ -263,7 +263,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
-ethclk_phandle, ethclk_phandle, ethclk_phandle);
+prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
 qemu_fdt_setprop(fdt, nodename, "clock-names", ethclk_names,
 sizeof(ethclk_names));
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
@@ -293,7 +293,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_UART0].base,
 0x0, memmap[SIFIVE_U_UART0].size);
-qemu_fdt_setprop_cell(fdt, nodename, "clocks", uartclk_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+prci_phandle, PRCI_CLK_TLCLK);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
diff --git a/include/hw/riscv/sifive_u_prci.h b/include/hw/riscv/sifive_u_prci.h
index 60a2eab..0a531fd 100644
--- a/include/hw/riscv/sifive_u_prci.h
+++ b/include/hw/riscv/sifive_u_prci.h
@@ -78,4 +78,14 @@ typedef struct SiFiveUPRCIState {
 uint32_t clkmuxstatus;
 } SiFiveUPRCIState;
 
+/*
+ * Clock indexes for use by Device Tree data and the PRCI driver.
+ *
+ * These values are from sifive-fu540-prci.h in the Linux kernel.
+ */
+#define PRCI_CLK_COREPLL0
+#define PRCI_CLK_DDRPLL 1
+#define PRCI_CLK_GEMGXLPLL  2
+#define PRCI_CLK_TLCLK  3
+
 #endif /* HW_SIFIVE_U_PRCI_H */
-- 
2.7.4




[Qemu-devel] [PATCH v8 19/32] riscv: sifive_u: Update hart configuration to reflect the real FU540 SoC

2019-09-06 Thread Bin Meng
The FU540-C000 includes a 64-bit E51 RISC-V core and four 64-bit U54
RISC-V cores. Currently the sifive_u machine only populates 4 U54
cores. Update the max cpu number to 5 to reflect the real hardware,
by creating 2 CPU clusters as containers for RISC-V hart arrays to
populate heterogeneous harts.

The cpu nodes in the generated DTS have been updated as well.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6:
- generate u cpus unconditionally (not test ms->smp.cpus > 1)
  since the minimal required number of cpu is now 2, due to
  this patch is reordered

Changes in v5: None
Changes in v4:
- changed to create clusters for each cpu type

Changes in v3:
- changed to use macros for management and compute cpu count

Changes in v2:
- fixed the "interrupts-extended" property size

 hw/riscv/sifive_u.c | 92 +
 include/hw/riscv/sifive_u.h |  6 ++-
 2 files changed, 72 insertions(+), 26 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 2023b71..6c4634d 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -11,7 +11,7 @@
  * 2) PLIC (Platform Level Interrupt Controller)
  *
  * This board currently generates devicetree dynamically that indicates at 
least
- * two harts.
+ * two harts and up to five harts.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -34,6 +34,7 @@
 #include "hw/loader.h"
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
+#include "hw/cpu/cluster.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
@@ -70,6 +71,7 @@ static const struct MemmapEntry {
 static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
+MachineState *ms = MACHINE(qdev_get_machine());
 void *fdt;
 int cpu;
 uint32_t *cells;
@@ -110,15 +112,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
-for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
+for (cpu = ms->smp.cpus - 1; cpu >= 0; cpu--) {
 int cpu_phandle = phandle++;
 nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
-char *isa = riscv_isa_string(>soc.cpus.harts[cpu]);
+char *isa;
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
   SIFIVE_U_CLOCK_FREQ);
-qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+/* cpu 0 is the management hart that does not have mmu */
+if (cpu != 0) {
+qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+isa = riscv_isa_string(>soc.u_cpus.harts[cpu - 1]);
+} else {
+isa = riscv_isa_string(>soc.e_cpus.harts[0]);
+}
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
 qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
@@ -134,8 +142,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 }
 
-cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
-for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
+cells =  g_new0(uint32_t, ms->smp.cpus * 4);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
@@ -153,20 +161,26 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_CLINT].base,
 0x0, memmap[SIFIVE_U_CLINT].size);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
-cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
+cells, ms->smp.cpus * sizeof(uint32_t) * 4);
 g_free(cells);
 g_free(nodename);
 
 plic_phandle = phandle++;
-cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
-for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
+cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
-cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
-cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
+/* cpu 0 is the management hart that does not have 

[Qemu-devel] [PATCH v8 08/32] riscv: hw: Remove the unnecessary include of target/riscv/cpu.h

2019-09-06 Thread Bin Meng
The inclusion of "target/riscv/cpu.h" is unnecessary in various
sifive model drivers.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
- new patch to remove the unnecessary include of target/riscv/cpu.h

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_prci.c | 1 -
 hw/riscv/sifive_test.c | 1 -
 hw/riscv/sifive_uart.c | 1 -
 3 files changed, 3 deletions(-)

diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_prci.c
index 982fbb2..c413f0c 100644
--- a/hw/riscv/sifive_prci.c
+++ b/hw/riscv/sifive_prci.c
@@ -22,7 +22,6 @@
 #include "hw/sysbus.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
-#include "target/riscv/cpu.h"
 #include "hw/hw.h"
 #include "hw/riscv/sifive_prci.h"
 
diff --git a/hw/riscv/sifive_test.c b/hw/riscv/sifive_test.c
index aa544e7..339195c 100644
--- a/hw/riscv/sifive_test.c
+++ b/hw/riscv/sifive_test.c
@@ -23,7 +23,6 @@
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "sysemu/runstate.h"
-#include "target/riscv/cpu.h"
 #include "hw/hw.h"
 #include "hw/riscv/sifive_test.h"
 
diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c
index 215990b..a403ae9 100644
--- a/hw/riscv/sifive_uart.c
+++ b/hw/riscv/sifive_uart.c
@@ -22,7 +22,6 @@
 #include "hw/sysbus.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
-#include "target/riscv/cpu.h"
 #include "hw/hw.h"
 #include "hw/irq.h"
 #include "hw/riscv/sifive_uart.h"
-- 
2.7.4




[Qemu-devel] [PATCH v8 16/32] riscv: hart: Extract hart realize to a separate routine

2019-09-06 Thread Bin Meng
Currently riscv_harts_realize() creates all harts based on the
same cpu type given in the hart array property. With current
implementation it can only create homogeneous harts. Exact the
hart realize to a separate routine in preparation for supporting
multiple hart arrays.

Note the file header says the RISC-V hart array holds the state
of a heterogeneous array of RISC-V harts, which is not true.
Update the comment to mention homogeneous array of RISC-V harts.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/riscv_hart.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index d0f3199..6620e41 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
- * Holds the state of a heterogenous array of RISC-V harts
+ * Holds the state of a homogeneous array of RISC-V harts
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -39,26 +39,33 @@ static void riscv_harts_cpu_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
+static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
+   char *cpu_type, Error **errp)
+{
+Error *err = NULL;
+
+object_initialize_child(OBJECT(s), "harts[*]", >harts[idx],
+sizeof(RISCVCPU), cpu_type,
+_abort, NULL);
+s->harts[idx].env.mhartid = idx;
+qemu_register_reset(riscv_harts_cpu_reset, >harts[idx]);
+object_property_set_bool(OBJECT(>harts[idx]), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+}
+
 static void riscv_harts_realize(DeviceState *dev, Error **errp)
 {
 RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
-Error *err = NULL;
 int n;
 
 s->harts = g_new0(RISCVCPU, s->num_harts);
 
 for (n = 0; n < s->num_harts; n++) {
-object_initialize_child(OBJECT(s), "harts[*]", >harts[n],
-sizeof(RISCVCPU), s->cpu_type,
-_abort, NULL);
-s->harts[n].env.mhartid = n;
-qemu_register_reset(riscv_harts_cpu_reset, >harts[n]);
-object_property_set_bool(OBJECT(>harts[n]), true,
- "realized", );
-if (err) {
-error_propagate(errp, err);
-return;
-}
+riscv_hart_realize(s, n, s->cpu_type, errp);
 }
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH v8 18/32] riscv: sifive_u: Set the minimum number of cpus to 2

2019-09-06 Thread Bin Meng
It is not useful if we only have one management CPU.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- use management cpu count + 1 for the min_cpus

Changes in v2:
- update the file header to indicate at least 2 harts are created

 hw/riscv/sifive_u.c | 4 +++-
 include/hw/riscv/sifive_u.h | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 2947e06..2023b71 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,7 +10,8 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  *
- * This board currently uses a hardcoded devicetree that indicates one hart.
+ * This board currently generates devicetree dynamically that indicates at 
least
+ * two harts.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -433,6 +434,7 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
  * management CPU.
  */
 mc->max_cpus = 4;
+mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
 }
 
 DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index f25bad8..6d22741 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -69,6 +69,8 @@ enum {
 SIFIVE_U_GEM_CLOCK_FREQ = 12500
 };
 
+#define SIFIVE_U_MANAGEMENT_CPU_COUNT   1
+
 #define SIFIVE_U_PLIC_HART_CONFIG "MS"
 #define SIFIVE_U_PLIC_NUM_SOURCES 54
 #define SIFIVE_U_PLIC_NUM_PRIORITIES 7
-- 
2.7.4




[Qemu-devel] [PATCH v8 23/32] riscv: sifive_u: Add PRCI block to the SoC

2019-09-06 Thread Bin Meng
Add PRCI mmio base address and size mappings to sifive_u machine,
and generate the corresponding device tree node.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
- create sifive_u_prci block directly in the machine codes, instead
  of calling sifive_u_prci_create()

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 24 +++-
 include/hw/riscv/sifive_u.h |  3 +++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 3ee6fcb..ff2e28e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -9,6 +9,7 @@
  * 0) UART
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
+ * 3) PRCI (Power, Reset, Clock, Interrupt)
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -60,6 +61,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_MROM] = { 0x1000,0x11000 },
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
+[SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
@@ -77,7 +79,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uint32_t *cells;
 char *nodename;
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
-uint32_t plic_phandle, ethclk_phandle, phandle = 1;
+uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
 uint32_t hfclk_phandle, rtcclk_phandle;
 
@@ -188,6 +190,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
+prci_phandle = phandle++;
+nodename = g_strdup_printf("/soc/clock-controller@%lx",
+(long)memmap[SIFIVE_U_PRCI].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", prci_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x1);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+hfclk_phandle, rtcclk_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_PRCI].base,
+0x0, memmap[SIFIVE_U_PRCI].size);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-prci");
+g_free(nodename);
+
 plic_phandle = phandle++;
 cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
 for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
@@ -402,6 +419,8 @@ static void riscv_sifive_u_soc_init(Object *obj)
 qdev_prop_set_uint32(DEVICE(>u_cpus), "hartid-base", 1);
 qdev_prop_set_string(DEVICE(>u_cpus), "cpu-type", SIFIVE_U_CPU);
 
+sysbus_init_child_obj(obj, "prci", >prci, sizeof(s->prci),
+  TYPE_SIFIVE_U_PRCI);
 sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
   TYPE_CADENCE_GEM);
 }
@@ -475,6 +494,9 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 
+object_property_set_bool(OBJECT(>prci), true, "realized", );
+sysbus_mmio_map(SYS_BUS_DEVICE(>prci), 0, memmap[SIFIVE_U_PRCI].base);
+
 for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
 plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
 }
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 2441814..bb46745 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -22,6 +22,7 @@
 #include "hw/net/cadence_gem.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_cpu.h"
+#include "hw/riscv/sifive_u_prci.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -37,6 +38,7 @@ typedef struct SiFiveUSoCState {
 RISCVHartArrayState e_cpus;
 RISCVHartArrayState u_cpus;
 DeviceState *plic;
+SiFiveUPRCIState prci;
 CadenceGEMState gem;
 } SiFiveUSoCState;
 
@@ -55,6 +57,7 @@ enum {
 SIFIVE_U_MROM,
 SIFIVE_U_CLINT,
 SIFIVE_U_PLIC,
+SIFIVE_U_PRCI,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
 SIFIVE_U_DRAM,
-- 
2.7.4




[Qemu-devel] [PATCH v8 07/32] riscv: hw: Change to use qemu_log_mask(LOG_GUEST_ERROR, ...) instead

2019-09-06 Thread Bin Meng
Replace the call to hw_error() with qemu_log_mask(LOG_GUEST_ERROR,...)
in various sifive models.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5:
- new patch to change to use qemu_log_mask(LOG_GUEST_ERROR,...) instead
  in various sifive models

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_prci.c | 8 +---
 hw/riscv/sifive_test.c | 5 +++--
 hw/riscv/sifive_uart.c | 9 +
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_prci.c
index 562bc3d..982fbb2 100644
--- a/hw/riscv/sifive_prci.c
+++ b/hw/riscv/sifive_prci.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
+#include "qemu/log.h"
 #include "qemu/module.h"
 #include "target/riscv/cpu.h"
 #include "hw/hw.h"
@@ -38,7 +39,8 @@ static uint64_t sifive_prci_read(void *opaque, hwaddr addr, 
unsigned int size)
 case SIFIVE_PRCI_PLLOUTDIV:
 return s->plloutdiv;
 }
-hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n",
+  __func__, (int)addr);
 return 0;
 }
 
@@ -66,8 +68,8 @@ static void sifive_prci_write(void *opaque, hwaddr addr,
 s->plloutdiv = (uint32_t) val64;
 break;
 default:
-hw_error("%s: bad write: addr=0x%x v=0x%x\n",
- __func__, (int)addr, (int)val64);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n",
+  __func__, (int)addr, (int)val64);
 }
 }
 
diff --git a/hw/riscv/sifive_test.c b/hw/riscv/sifive_test.c
index 7117409..aa544e7 100644
--- a/hw/riscv/sifive_test.c
+++ b/hw/riscv/sifive_test.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
+#include "qemu/log.h"
 #include "qemu/module.h"
 #include "sysemu/runstate.h"
 #include "target/riscv/cpu.h"
@@ -49,8 +50,8 @@ static void sifive_test_write(void *opaque, hwaddr addr,
 break;
 }
 }
-hw_error("%s: write: addr=0x%x val=0x%016" PRIx64 "\n",
-__func__, (int)addr, val64);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: write: addr=0x%x val=0x%016" PRIx64 
"\n",
+  __func__, (int)addr, val64);
 }
 
 static const MemoryRegionOps sifive_test_ops = {
diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c
index 9de42b1..215990b 100644
--- a/hw/riscv/sifive_uart.c
+++ b/hw/riscv/sifive_uart.c
@@ -18,6 +18,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qemu/log.h"
 #include "hw/sysbus.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
@@ -95,8 +96,8 @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
 return s->div;
 }
 
-hw_error("%s: bad read: addr=0x%x\n",
-__func__, (int)addr);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read: addr=0x%x\n",
+  __func__, (int)addr);
 return 0;
 }
 
@@ -127,8 +128,8 @@ uart_write(void *opaque, hwaddr addr,
 s->div = val64;
 return;
 }
-hw_error("%s: bad write: addr=0x%x v=0x%x\n",
-__func__, (int)addr, (int)value);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n",
+  __func__, (int)addr, (int)value);
 }
 
 static const MemoryRegionOps uart_ops = {
-- 
2.7.4




[Qemu-devel] [PATCH v8 14/32] riscv: sifive_e: Drop sifive_mmio_emulate()

2019-09-06 Thread Bin Meng
Use create_unimplemented_device() instead.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8:
- select UNIMP in sifive_e Kconfig due to applied commit
  "hw/misc: Add a config switch for the "unimplemented" device"
  in latest qemu/master

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- drop patch "riscv: sifive: Move sifive_mmio_emulate() to a common place"
- new patch "riscv: sifive_e: Drop sifive_mmio_emulate()"

 hw/riscv/Kconfig|  1 +
 hw/riscv/sifive_e.c | 23 ---
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 8674211..33e54b0 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -12,6 +12,7 @@ config SIFIVE_E
 bool
 select HART
 select SIFIVE
+select UNIMP
 
 config SIFIVE_U
 bool
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 1428a99..0f9d641 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -36,6 +36,7 @@
 #include "hw/loader.h"
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
+#include "hw/misc/unimp.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
@@ -74,14 +75,6 @@ static const struct MemmapEntry {
 [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
 };
 
-static void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
- uintptr_t offset, uintptr_t length)
-{
-MemoryRegion *mock_mmio = g_new(MemoryRegion, 1);
-memory_region_init_ram(mock_mmio, NULL, name, length, _fatal);
-memory_region_add_subregion(parent, offset, mock_mmio);
-}
-
 static void riscv_sifive_e_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_e_memmap;
@@ -172,7 +165,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 sifive_clint_create(memmap[SIFIVE_E_CLINT].base,
 memmap[SIFIVE_E_CLINT].size, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
+create_unimplemented_device("riscv.sifive.e.aon",
 memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
 sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
 
@@ -199,19 +192,19 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 
 sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART0].base,
 serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_E_UART0_IRQ));
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi0",
+create_unimplemented_device("riscv.sifive.e.qspi0",
 memmap[SIFIVE_E_QSPI0].base, memmap[SIFIVE_E_QSPI0].size);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.pwm0",
+create_unimplemented_device("riscv.sifive.e.pwm0",
 memmap[SIFIVE_E_PWM0].base, memmap[SIFIVE_E_PWM0].size);
 sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART1].base,
 serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_E_UART1_IRQ));
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi1",
+create_unimplemented_device("riscv.sifive.e.qspi1",
 memmap[SIFIVE_E_QSPI1].base, memmap[SIFIVE_E_QSPI1].size);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.pwm1",
+create_unimplemented_device("riscv.sifive.e.pwm1",
 memmap[SIFIVE_E_PWM1].base, memmap[SIFIVE_E_PWM1].size);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi2",
+create_unimplemented_device("riscv.sifive.e.qspi2",
 memmap[SIFIVE_E_QSPI2].base, memmap[SIFIVE_E_QSPI2].size);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.pwm2",
+create_unimplemented_device("riscv.sifive.e.pwm2",
 memmap[SIFIVE_E_PWM2].base, memmap[SIFIVE_E_PWM2].size);
 
 /* Flash memory */
-- 
2.7.4




[Qemu-devel] [PATCH v8 15/32] riscv: Add a sifive_cpu.h to include both E and U cpu type defines

2019-09-06 Thread Bin Meng
Group SiFive E and U cpu type defines into one header file.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 include/hw/riscv/sifive_cpu.h | 31 +++
 include/hw/riscv/sifive_e.h   |  7 +--
 include/hw/riscv/sifive_u.h   |  7 +--
 3 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/riscv/sifive_cpu.h

diff --git a/include/hw/riscv/sifive_cpu.h b/include/hw/riscv/sifive_cpu.h
new file mode 100644
index 000..1367996
--- /dev/null
+++ b/include/hw/riscv/sifive_cpu.h
@@ -0,0 +1,31 @@
+/*
+ * SiFive CPU types
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * 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 .
+ */
+
+#ifndef HW_SIFIVE_CPU_H
+#define HW_SIFIVE_CPU_H
+
+#if defined(TARGET_RISCV32)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
+#elif defined(TARGET_RISCV64)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
+#endif
+
+#endif /* HW_SIFIVE_CPU_H */
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 9c868dd..25ce7aa 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -20,6 +20,7 @@
 #define HW_SIFIVE_E_H
 
 #include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_cpu.h"
 #include "hw/riscv/sifive_gpio.h"
 
 #define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
@@ -84,10 +85,4 @@ enum {
 #define SIFIVE_E_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_E_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
-#endif
-
 #endif
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index be021ce..f25bad8 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -21,6 +21,7 @@
 
 #include "hw/net/cadence_gem.h"
 #include "hw/riscv/riscv_hart.h"
+#include "hw/riscv/sifive_cpu.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -78,10 +79,4 @@ enum {
 #define SIFIVE_U_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_U_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
-#endif
-
 #endif
-- 
2.7.4




[Qemu-devel] [PATCH v8 00/32] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine

2019-09-06 Thread Bin Meng
As of today, the QEMU 'sifive_u' machine is a special target that does
not boot the upstream OpenSBI/U-Boot firmware images built for the real
SiFive HiFive Unleashed board. Hence OpenSBI supports a special platform
"qemu/sifive_u". For U-Boot, the sifive_fu540_defconfig is referenced
in the OpenSBI doc as its payload, but that does not boot at all due
to various issues in current QEMU 'sifive_u' machine codes.

This series aims to improve the emulation fidelity of sifive_u machine,
so that the upstream OpenSBI, U-Boot and kernel images built for the
SiFive HiFive Unleashed board can be used out of the box without any
special hack.

The major changes include:
- Heterogeneous harts creation supported, so that we can create a CPU
  that exactly mirrors the real hardware: 1 E51 + 4 U54.
- Implemented a PRCI model for FU540
- Implemented an OTP model for FU540, primarily used for storing serial
  number of the board
- Fixed GEM support that was seriously broken on sifive_u
- Synced device tree with upstream Linux kernel on sifive_u

OpenSBI v0.4 image built for sifive/fu540 is included as the default
bios image for 'sifive_u' machine.

The series is tested against OpenSBI v0.4 image for sifive/fu540
paltform, U-Boot v2019.10-rc1 image for sifive_fu540_defconfig,
and Linux kernel v5.3-rc3 image with the following patch:

macb: Update compatibility string for SiFive FU540-C000 [1]

OpenSBI + U-Boot, ping/tftpboot with U-Boot MACB driver works well.
Boot Linux 64-bit defconfig image, verified that system console on
the serial 0 and ping host work pretty well.

An OpenSBI patch [2] was sent to drop the special "qemu/sifive_u" platform
support in OpenSBI. The original plan was to get the drop patch applied
after this QEMU series is merged. However after discussion in the OpenSBI
mailing list, it seems the best option for us is to let OpenSBI continue
shipping the special "qemu/sifive_u" platform support to work with QEMU
version <= 4.1 and deprecate the support sometime in the future. A patch
will need to be sent to OpenSBI mailing list to update its document.

v4 is now rebased on Palmer's QEMU RISC-V repo "for-master" branch.
Dropped the following v3 patch that was already done by someone else.
- riscv: sifive_u: Generate an aliases node in the device tree
- riscv: sifive_u: Support loading initramfs

The following v3 patch was dropped too due to a different cluster approach
suggested by Richard Henderson is used in v4:
- riscv: hart: Support heterogeneous harts population

v8 is now rebased again on Palmer's QEMU RISC-V repo "for-master" branch,
and resolved conflicts and build errors. To ease patch inter-dependencies,
v8 includes the following 2 patches so that all of them can be applied
cleanly on Palmer's QEMU RISC-V "for-master" branch.

- riscv: hw: Remove duplicated "hw/hw.h" inclusion [3]
- riscv: sifive_test: Add reset functionality [4]

The whole patch series is also available at
https://github.com/lbmeng/qemu repo, "sifive_u_cluster" branch.

[1]: https://patchwork.kernel.org/patch/11050003/
[2]: http://lists.infradead.org/pipermail/opensbi/2019-August/000335.html
[3]: http://patchwork.ozlabs.org/patch/1159063/
[4]: http://patchwork.ozlabs.org/patch/1158526/

Changes in v8:
- select UNIMP in sifive_e Kconfig due to applied commit
  "hw/misc: Add a config switch for the "unimplemented" device"
  in latest qemu/master
- Don't cast addr to an int, use the correct macros in
  sifive_u_otp_read() and sifive_u_otp_write()
- Include "hw/qdev-properties.h" in sifive_u_otp.c
- select UNIMP in sifive_u Kconfig due to applied commit
  "hw/misc: Add a config switch for the "unimplemented" device"
  in latest qemu/master

Changes in v7:
- use `s->hartid_base + idx` directly

Changes in v6:
- use s->hartid_base directly, instead of an extra variable
- generate u cpus unconditionally (not test ms->smp.cpus > 1)
  since the minimal required number of cpu is now 2, due to
  this patch is reordered
- fix incorrectly indented comment lines
- remove unneeded brackets around assignment

Changes in v5:
- new patch to change to use qemu_log_mask(LOG_GUEST_ERROR,...) instead
  in various sifive models
- new patch to remove the unnecessary include of target/riscv/cpu.h
- change to use defines instead of enums
- change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci
- creating a 32-bit val variable and using that instead of casting
  everywhere in sifive_u_prci_write()
- move all register initialization to sifive_u_prci_reset() function
- drop sifive_u_prci_create()
- s/codes that worked/code that works/g
- create sifive_u_prci block directly in the machine codes, instead
  of calling sifive_u_prci_create()
- change to use defines instead of enums
- change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_otp
- creating a 32-bit val variable and using that instead of casting
  everywhere in sifive_u_otp_write()
- move all register initialization to sifive_u_otp_reset() function
- drop sifive_u_otp_create()
- 

[Qemu-devel] [PATCH v8 10/32] riscv: sifive_u: Remove the unnecessary include of prci header

2019-09-06 Thread Bin Meng
sifive_u machine does not use PRCI as of today. Remove the prci
header inclusion.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 32d8cee..2947e06 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -38,7 +38,6 @@
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_u.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
-- 
2.7.4




[Qemu-devel] [PATCH v8 04/32] riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell

2019-09-06 Thread Bin Meng
Some of the properties only have 1 cell so we should use
qemu_fdt_setprop_cell() instead of qemu_fdt_setprop_cells().

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 18 +-
 hw/riscv/virt.c | 24 
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 0d9ff76..762223c 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -183,7 +183,7 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -208,20 +208,20 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_GEM].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
 ethclk_phandle, ethclk_phandle, ethclk_phandle);
 qemu_fdt_setprop(fdt, nodename, "clock-names", ethclk_names,
 sizeof(ethclk_names));
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 1);
-qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
+qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
 uartclk_phandle = phandle++;
@@ -241,9 +241,9 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_UART0].base,
 0x0, memmap[SIFIVE_U_UART0].size);
-qemu_fdt_setprop_cells(fdt, nodename, "clocks", uartclk_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "clocks", uartclk_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 7809170..6852178 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -233,8 +233,8 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
 (long)memmap[VIRT_PLIC].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells",
-   FDT_PLIC_ADDR_CELLS);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells",
+  FDT_PLIC_ADDR_CELLS);
 qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
   FDT_PLIC_INT_CELLS);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
@@ -247,7 +247,7 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -260,19 +260,19 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
 0x0, memmap[VIRT_VIRTIO].size);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", 
plic_phandle);

[Qemu-devel] [PATCH v8 13/32] riscv: sifive_e: prci: Update the PRCI register block size

2019-09-06 Thread Bin Meng
Currently the PRCI register block size is set to 0x8000, but in fact
0x1000 is enough, which is also what the manual says.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Alistair Francis 
---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_e_prci.c | 2 +-
 include/hw/riscv/sifive_e_prci.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_e_prci.c b/hw/riscv/sifive_e_prci.c
index bfe9b13..a1c0d44 100644
--- a/hw/riscv/sifive_e_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -87,7 +87,7 @@ static void sifive_e_prci_init(Object *obj)
 SiFiveEPRCIState *s = SIFIVE_E_PRCI(obj);
 
 memory_region_init_io(>mmio, obj, _e_prci_ops, s,
-  TYPE_SIFIVE_E_PRCI, 0x8000);
+  TYPE_SIFIVE_E_PRCI, SIFIVE_E_PRCI_REG_SIZE);
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
diff --git a/include/hw/riscv/sifive_e_prci.h b/include/hw/riscv/sifive_e_prci.h
index c4b76aa..698b0b4 100644
--- a/include/hw/riscv/sifive_e_prci.h
+++ b/include/hw/riscv/sifive_e_prci.h
@@ -47,6 +47,8 @@ enum {
 SIFIVE_E_PRCI_PLLOUTDIV_DIV1 = (1 << 8)
 };
 
+#define SIFIVE_E_PRCI_REG_SIZE  0x1000
+
 #define TYPE_SIFIVE_E_PRCI  "riscv.sifive.e.prci"
 
 #define SIFIVE_E_PRCI(obj) \
-- 
2.7.4




[Qemu-devel] [PATCH v8 05/32] riscv: hw: Remove not needed PLIC properties in device tree

2019-09-06 Thread Bin Meng
This removes "reg-names" and "riscv,max-priority" properties of the
PLIC node from device tree.

Signed-off-by: Bin Meng 
Reviewed-by: Jonathan Behrens 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- keep the PLIC compatible string unchanged as OpenSBI uses that
  for DT fix up

 hw/riscv/sifive_u.c | 2 --
 hw/riscv/virt.c | 2 --
 2 files changed, 4 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 762223c..e8acdd9 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -180,8 +180,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_PLIC].base,
 0x0, memmap[SIFIVE_U_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 6852178..090512b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -244,8 +244,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[VIRT_PLIC].base,
 0x0, memmap[VIRT_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
-- 
2.7.4




[Qemu-devel] [PATCH v8 03/32] riscv: hw: Remove superfluous "linux, phandle" property

2019-09-06 Thread Bin Meng
"linux,phandle" property is optional. Remove all instances in the
sifive_u, virt and spike machine device trees.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- remove 2 more "linux,phandle" instances in sifive_u.c and spike.c
  after rebasing on Palmer's QEMU RISC-V tree

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 4 
 hw/riscv/spike.c| 1 -
 hw/riscv/virt.c | 3 ---
 3 files changed, 8 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ae5a16e..0d9ff76 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -126,7 +126,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", cpu_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -185,7 +184,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -198,7 +196,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
 SIFIVE_U_GEM_CLOCK_FREQ);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", ethclk_phandle);
 ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
@@ -234,7 +231,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", uartclk_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", uartclk_phandle);
 uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 7c04bd5..d60415d 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -112,7 +112,6 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", 1);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", 1);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 9bced28..7809170 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -170,11 +170,9 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", cpu_phandle);
 intc_phandle = phandle++;
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", intc_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", intc_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -250,7 +248,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
-- 
2.7.4




[Qemu-devel] [PATCH v8 06/32] riscv: hw: Change create_fdt() to return void

2019-09-06 Thread Bin Meng
There is no need to return fdt at the end of create_fdt() because
it's already saved in s->fdt.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 

---

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- change create_fdt() to return void in sifive_u.c too, after rebasing
  on Palmer's QEMU RISC-V tree

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 11 ---
 hw/riscv/virt.c | 11 ---
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index e8acdd9..32d8cee 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -67,7 +67,7 @@ static const struct MemmapEntry {
 
 #define GEM_REVISION0x10070109
 
-static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
+static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -253,14 +253,11 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 
 g_free(nodename);
-
-return fdt;
 }
 
 static void riscv_sifive_u_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_u_memmap;
-void *fdt;
 
 SiFiveUState *s = g_new0(SiFiveUState, 1);
 MemoryRegion *system_memory = get_system_memory();
@@ -281,7 +278,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 riscv_find_and_load_firmware(machine, BIOS_FILENAME,
  memmap[SIFIVE_U_DRAM].base);
@@ -294,9 +291,9 @@ static void riscv_sifive_u_init(MachineState *machine)
 hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
);
-qemu_fdt_setprop_cell(fdt, "/chosen",
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
   "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 090512b..d36f562 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -112,7 +112,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
0x1800, 0, 0, 0x7);
 }
 
-static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -316,8 +316,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 g_free(nodename);
-
-return fdt;
 }
 
 
@@ -373,7 +371,6 @@ static void riscv_virt_board_init(MachineState *machine)
 size_t plic_hart_config_len;
 int i;
 unsigned int smp_cpus = machine->smp.cpus;
-void *fdt;
 
 /* Initialize SOC */
 object_initialize_child(OBJECT(machine), "soc", >soc, sizeof(s->soc),
@@ -392,7 +389,7 @@ static void riscv_virt_board_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
 memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
@@ -411,9 +408,9 @@ static void riscv_virt_board_init(MachineState *machine)
 hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
);
-qemu_fdt_setprop_cell(fdt, "/chosen",
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
   "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH v8 02/32] riscv: sifive_test: Add reset functionality

2019-09-06 Thread Bin Meng
This adds a reset opcode for sifive_test device to trigger a system
reset for testing purpose.

Signed-off-by: Bin Meng 
Reviewed-by: Palmer Dabbelt 

---

Changes in v8:
- newly included in v8 to ease patch inter dependencies

 hw/riscv/sifive_test.c | 4 
 include/hw/riscv/sifive_test.h | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_test.c b/hw/riscv/sifive_test.c
index 3a14f9f..7117409 100644
--- a/hw/riscv/sifive_test.c
+++ b/hw/riscv/sifive_test.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "qemu/module.h"
+#include "sysemu/runstate.h"
 #include "target/riscv/cpu.h"
 #include "hw/hw.h"
 #include "hw/riscv/sifive_test.h"
@@ -41,6 +42,9 @@ static void sifive_test_write(void *opaque, hwaddr addr,
 exit(code);
 case FINISHER_PASS:
 exit(0);
+case FINISHER_RESET:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+return;
 default:
 break;
 }
diff --git a/include/hw/riscv/sifive_test.h b/include/hw/riscv/sifive_test.h
index 3a603a6..1ec416a 100644
--- a/include/hw/riscv/sifive_test.h
+++ b/include/hw/riscv/sifive_test.h
@@ -36,7 +36,8 @@ typedef struct SiFiveTestState {
 
 enum {
 FINISHER_FAIL = 0x,
-FINISHER_PASS = 0x
+FINISHER_PASS = 0x,
+FINISHER_RESET = 0x
 };
 
 DeviceState *sifive_test_create(hwaddr addr);
-- 
2.7.4




  1   2   3   >