Re: [Qemu-devel] [PATCH RFC v2 00/17] VT-d: vfio enablement and misc enhances

2017-01-02 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH RFC v2 00/17] VT-d: vfio enablement and misc 
enhances
Type: series
Message-id: 1483428594-28880-1-git-send-email-pet...@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/1483428594-28880-1-git-send-email-pet...@redhat.com -> 
patchew/1483428594-28880-1-git-send-email-pet...@redhat.com
Switched to a new branch 'test'
69863b6 intel_iommu: enable vfio devices
1a464bd intel_iommu: allow dynamic switch of IOMMU region
ad7aeef intel_iommu: do replay when context invalidate
dd43a17 intel_iommu: provide its own replay() callback
1fba488 memory: add MemoryRegionIOMMUOps.replay() callback
e408082 memory: introduce memory_region_notify_one()
a89c58b memory: provide iommu_replay_all()
3c6c972 memory: add section range info for IOMMU notifier
688ef82 intel_iommu: vtd_slpt_level_shift check level
d18a425 intel_iommu: fix trace for addr translation
04056c0 intel_iommu: fix trace for inv desc handling
692f398 intel_iommu: renaming gpa to iova where proper
ec8456f intel_iommu: simplify irq region translation
1ecd377 intel_iommu: allocate new key when creating new address space
4d509be memory: handle alias in memory_region_is_iommu()
06d183d memory: handle alias for iommu notifier
0905834 IOMMU: add option to enable VTD_CAP_CM to vIOMMU capility exposoed to 
guest

=== OUTPUT BEGIN ===
Checking PATCH 1/17: IOMMU: add option to enable VTD_CAP_CM to vIOMMU capility 
exposoed to guest...
Checking PATCH 2/17: memory: handle alias for iommu notifier...
Checking PATCH 3/17: memory: handle alias in memory_region_is_iommu()...
Checking PATCH 4/17: intel_iommu: allocate new key when creating new address 
space...
Checking PATCH 5/17: intel_iommu: simplify irq region translation...
Checking PATCH 6/17: intel_iommu: renaming gpa to iova where proper...
Checking PATCH 7/17: intel_iommu: fix trace for inv desc handling...
Checking PATCH 8/17: intel_iommu: fix trace for addr translation...
Checking PATCH 9/17: intel_iommu: vtd_slpt_level_shift check level...
Checking PATCH 10/17: memory: add section range info for IOMMU notifier...
Checking PATCH 11/17: memory: provide iommu_replay_all()...
Checking PATCH 12/17: memory: introduce memory_region_notify_one()...
Checking PATCH 13/17: memory: add MemoryRegionIOMMUOps.replay() callback...
Checking PATCH 14/17: intel_iommu: provide its own replay() callback...
ERROR: Macros with complex values should be enclosed in parenthesis
#303: FILE: include/exec/memory.h:62:
+#define IOMMU_ACCESS_FLAG(r, w) ((r) ? IOMMU_RO : 0) | ((w) ? IOMMU_WO : 0)

total: 1 errors, 0 warnings, 266 lines checked

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

Checking PATCH 15/17: intel_iommu: do replay when context invalidate...
Checking PATCH 16/17: intel_iommu: allow dynamic switch of IOMMU region...
Checking PATCH 17/17: intel_iommu: enable vfio devices...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCH RFC v2 17/17] intel_iommu: enable vfio devices

2017-01-02 Thread Peter Xu
This patch is based on Aviv Ben-David ()'s patch
upstream:

  "IOMMU: enable intel_iommu map and unmap notifiers"
  https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html

However I removed/fixed some content, and added my own codes.

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.

This patch enables vfio devices for VT-d emulation.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 68 +--
 include/hw/i386/intel_iommu.h |  8 +
 2 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e66b823..fa50230 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -839,7 +839,8 @@ next:
  * @private: private data for the hook function
  */
 static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
- vtd_page_walk_hook hook_fn, void *private)
+ vtd_page_walk_hook hook_fn, void *private,
+ bool notify_unmap)
 {
 dma_addr_t addr = vtd_get_slpt_base_from_context(ce);
 uint32_t level = vtd_get_level_from_context_entry(ce);
@@ -858,7 +859,7 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t 
start, uint64_t end,
 trace_vtd_page_walk(ce->hi, ce->lo, start, end);
 
 return vtd_page_walk_level(addr, start, end, hook_fn, private,
-   level, true, true, NULL, false);
+   level, true, true, NULL, notify_unmap);
 }
 
 /* Map a device to its corresponding domain (context-entry) */
@@ -1202,6 +1203,34 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState 
*s, uint16_t domain_id)
 _id);
 }
 
+static int vtd_page_invalidate_notify_hook(IOMMUTLBEntry *entry,
+   void *private)
+{
+memory_region_notify_iommu((MemoryRegion *)private, *entry);
+return 0;
+}
+
+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
+   uint16_t domain_id, hwaddr addr,
+   uint8_t am)
+{
+IntelIOMMUNotifierNode *node;
+VTDContextEntry ce;
+int ret;
+
+QLIST_FOREACH(node, &(s->notifiers_list), next) {
+VTDAddressSpace *vtd_as = node->vtd_as;
+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+   vtd_as->devfn, );
+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
+  vtd_page_invalidate_notify_hook,
+  (void *)_as->iommu, true);
+}
+}
+}
+
+
 static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
   hwaddr addr, uint8_t am)
 {
@@ -1212,6 +1241,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, 
uint16_t domain_id,
 info.addr = addr;
 info.mask = ~((1 << am) - 1);
 g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, );
+vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am);
 }
 
 /* Flush IOTLB
@@ -2172,15 +2202,34 @@ static void vtd_iommu_notify_flag_changed(MemoryRegion 
*iommu,
   IOMMUNotifierFlag new)
 {
 VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
+IntelIOMMUState *s = vtd_as->iommu_state;
+IntelIOMMUNotifierNode *node = NULL;
+IntelIOMMUNotifierNode *next_node = NULL;
 
-if (new & IOMMU_NOTIFIER_MAP) {
-error_report("Device at bus %s addr %02x.%d requires iommu "
- "notifier which is currently not supported by "
- "intel-iommu emulation",
- vtd_as->bus->qbus.name, PCI_SLOT(vtd_as->devfn),
- PCI_FUNC(vtd_as->devfn));
+if (!s->cache_mode_enabled && new & IOMMU_NOTIFIER_MAP) {
+error_report("We need to set cache_mode=1 for intel-iommu to enable "
+ "device assignment with IOMMU protection.");
 exit(1);
 }
+
+/* Add new ndoe if no mapping was exising before this call */
+if (old == IOMMU_NOTIFIER_NONE) {
+node = g_malloc0(sizeof(*node));
+node->vtd_as = vtd_as;
+QLIST_INSERT_HEAD(>notifiers_list, node, next);
+return;
+}
+
+/* update notifier node with new flags */
+QLIST_FOREACH_SAFE(node, >notifiers_list, next, next_node) {
+if (node->vtd_as == vtd_as) {
+if (new == IOMMU_NOTIFIER_NONE) {
+QLIST_REMOVE(node, next);
+g_free(node);
+}
+return;
+}
+}
 }
 
 static const VMStateDescription vtd_vmstate = {
@@ -2595,7 +2644,7 @@ static void vtd_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier 

[Qemu-devel] [PATCH RFC v2 14/17] intel_iommu: provide its own replay() callback

2017-01-02 Thread Peter Xu
The default replay() don't work for VT-d since vt-d will have a huge
default memory region which covers address range 0-(2^64-1). This will
normally bring a dead loop when guest starts.

The solution is simple - we don't walk over all the regions. Instead, we
jump over the regions when we found that the page directories are empty.
It'll greatly reduce the time to walk the whole region.

To achieve this, we provided a page walk helper to do that, invoking
corresponding hook function when we found an page we are interested in.
vtd_page_walk_level() is the core logic for the page walking. It's
interface is designed to suite further use case, e.g., to invalidate a
range of addresses.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 212 --
 hw/i386/trace-events  |   8 ++
 include/exec/memory.h |   2 +
 3 files changed, 217 insertions(+), 5 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index abb9d2e..6f26bcb 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -600,6 +600,22 @@ static inline uint32_t 
vtd_get_agaw_from_context_entry(VTDContextEntry *ce)
 return 30 + (ce->hi & VTD_CONTEXT_ENTRY_AW) * 9;
 }
 
+static inline uint64_t vtd_iova_limit(VTDContextEntry *ce)
+{
+uint32_t ce_agaw = vtd_get_agaw_from_context_entry(ce);
+return 1ULL << MIN(ce_agaw, VTD_MGAW);
+}
+
+/* Return true if IOVA passes range check, otherwise false. */
+static inline bool vtd_iova_range_check(uint64_t iova, VTDContextEntry *ce)
+{
+/*
+ * Check if @iova is above 2^X-1, where X is the minimum of MGAW
+ * in CAP_REG and AW in context-entry.
+ */
+return !(iova & ~(vtd_iova_limit(ce) - 1));
+}
+
 static const uint64_t vtd_paging_entry_rsvd_field[] = {
 [0] = ~0ULL,
 /* For not large page */
@@ -635,13 +651,9 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
 uint32_t level = vtd_get_level_from_context_entry(ce);
 uint32_t offset;
 uint64_t slpte;
-uint32_t ce_agaw = vtd_get_agaw_from_context_entry(ce);
 uint64_t access_right_check;
 
-/* Check if @iova is above 2^X-1, where X is the minimum of MGAW
- * in CAP_REG and AW in context-entry.
- */
-if (iova & ~((1ULL << MIN(ce_agaw, VTD_MGAW)) - 1)) {
+if (!vtd_iova_range_check(iova, ce)) {
 error_report("IOVA 0x%"PRIx64 " exceeds limits", iova);
 return -VTD_FR_ADDR_BEYOND_MGAW;
 }
@@ -689,6 +701,166 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
 }
 }
 
+typedef int (*vtd_page_walk_hook)(IOMMUTLBEntry *entry, void *private);
+
+/**
+ * vtd_page_walk_level - walk over specific level for IOVA range
+ *
+ * @addr: base GPA addr to start the walk
+ * @start: IOVA range start address
+ * @end: IOVA range end address (start <= addr < end)
+ * @hook_fn: hook func to be called when detected page
+ * @private: private data to be passed into hook func
+ * @read: whether parent level has read permission
+ * @write: whether parent level has write permission
+ * @skipped: accumulated skipped ranges
+ * @notify_unmap: whether we should notify invalid entries
+ */
+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
+   uint64_t end, vtd_page_walk_hook hook_fn,
+   void *private, uint32_t level,
+   bool read, bool write, uint64_t *skipped,
+   bool notify_unmap)
+{
+bool read_cur, write_cur, entry_valid;
+uint32_t offset;
+uint64_t slpte;
+uint64_t subpage_size, subpage_mask;
+IOMMUTLBEntry entry;
+uint64_t iova = start;
+uint64_t iova_next;
+uint64_t skipped_local = 0;
+int ret = 0;
+
+trace_vtd_page_walk_level(addr, level, start, end);
+
+subpage_size = 1ULL << vtd_slpt_level_shift(level);
+subpage_mask = vtd_slpt_level_page_mask(level);
+
+while (iova < end) {
+iova_next = (iova & subpage_mask) + subpage_size;
+
+offset = vtd_iova_level_offset(iova, level);
+slpte = vtd_get_slpte(addr, offset);
+
+/*
+ * When one of the following case happens, we assume the whole
+ * range is invalid:
+ *
+ * 1. read block failed
+ * 3. reserved area non-zero
+ * 2. both read & write flag are not set
+ */
+
+if (slpte == (uint64_t)-1) {
+trace_vtd_page_walk_skip_read(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
+trace_vtd_page_walk_skip_reserve(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+/* Permissions are stacked with parents' */
+read_cur = read && (slpte & VTD_SL_R);
+write_cur = write && (slpte & VTD_SL_W);
+
+/*
+ * As long as we have either read/write permission, 

[Qemu-devel] [PATCH RFC v2 16/17] intel_iommu: allow dynamic switch of IOMMU region

2017-01-02 Thread Peter Xu
This is preparation work to finally enabled dynamic switching ON/OFF for
VT-d protection. The old VT-d codes is using static IOMMU region, and
that won't satisfy vfio-pci device listeners.

Let me explain.

vfio-pci devices depend on the memory region listener and IOMMU replay
mechanism to make sure the device mapping is coherent with the guest
even if there are domain switches. And there are two kinds of domain
switches:

  (1) switch from domain A -> B
  (2) switch from domain A -> no domain (e.g., turn DMAR off)

Case (1) is handled by the context entry invalidation handling by the
VT-d replay logic. What the replay function should do here is to replay
the existing page mappings in domain B.

However for case (2), we don't want to replay any domain mappings - we
just need the default GPA->HPA mappings (the address_space_memory
mapping). And this patch helps on case (2) to build up the mapping
automatically by leveraging the vfio-pci memory listeners.

Another important thing that this patch does is to seperate
IR (Interrupt Remapping) from DMAR (DMA Remapping). IR region should not
depend on the DMAR region (like before this patch). It should be a
standalone region, and it should be able to be activated without
DMAR (which is a common behavior of Linux kernel - by default it enables
IR while disabled DMAR).

Signed-off-by: Peter Xu 
---
v3:
- fix another trivial style issue patchew reported but I missed in v2

v2:
- fix issues reported by patchew
- switch domain by enable/disable memory regions [David]
- provide vtd_switch_address_space{_all}()
- provide a better comment on the memory regions

test done: with intel_iommu device, boot vm with/without
"intel_iommu=on" parameter.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 78 ---
 hw/i386/trace-events  |  2 +-
 include/hw/i386/intel_iommu.h |  2 ++
 3 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index ed60cfa..e66b823 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1333,9 +1333,49 @@ static void vtd_handle_gcmd_sirtp(IntelIOMMUState *s)
 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_IRTPS);
 }
 
+static void vtd_switch_address_space(VTDAddressSpace *as, bool iommu_enabled)
+{
+assert(as);
+
+trace_vtd_switch_address_space(pci_bus_num(as->bus),
+   VTD_PCI_SLOT(as->devfn),
+   VTD_PCI_FUNC(as->devfn),
+   iommu_enabled);
+
+/* Turn off first then on the other */
+if (iommu_enabled) {
+memory_region_set_enabled(>sys_alias, false);
+memory_region_set_enabled(>iommu, true);
+} else {
+memory_region_set_enabled(>iommu, false);
+memory_region_set_enabled(>sys_alias, true);
+}
+}
+
+static void vtd_switch_address_space_all(IntelIOMMUState *s, bool enabled)
+{
+GHashTableIter iter;
+VTDBus *vtd_bus;
+int i;
+
+g_hash_table_iter_init(, s->vtd_as_by_busptr);
+while (g_hash_table_iter_next(, NULL, (void **)_bus)) {
+for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
+if (!vtd_bus->dev_as[i]) {
+continue;
+}
+vtd_switch_address_space(vtd_bus->dev_as[i], enabled);
+}
+}
+}
+
 /* Handle Translation Enable/Disable */
 static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
 {
+if (s->dmar_enabled == en) {
+return;
+}
+
 VTD_DPRINTF(CSR, "Translation Enable %s", (en ? "on" : "off"));
 
 if (en) {
@@ -1350,6 +1390,8 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool 
en)
 /* Ok - report back to driver */
 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_TES, 0);
 }
+
+vtd_switch_address_space_all(s, en);
 }
 
 /* Handle Interrupt Remap Enable/Disable */
@@ -2492,15 +2534,43 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
PCIBus *bus, int devfn)
 vtd_dev_as->devfn = (uint8_t)devfn;
 vtd_dev_as->iommu_state = s;
 vtd_dev_as->context_cache_entry.context_cache_gen = 0;
+
+/*
+ * Memory region relationships looks like (Address range shows
+ * only lower 32 bits to make it short in length...):
+ *
+ * |-+---+--|
+ * | Name| Address range | Priority |
+ * |-+---+--+
+ * | vtd_root| - |0 |
+ * |  intel_iommu| - |1 |
+ * |  vtd_sys_alias  | - |1 |
+ * |  intel_iommu_ir | fee0-feef |   64 |
+ * |-+---+--|
+ *
+ * We enable/disable DMAR by switching enablement for
+ * vtd_sys_alias and intel_iommu regions. IR 

[Qemu-devel] [PATCH RFC v2 15/17] intel_iommu: do replay when context invalidate

2017-01-02 Thread Peter Xu
Before this one we only invalidate context cache when we receive context
entry invalidations. However it's possible that the invalidation also
contains a domain switch (only if cache-mode is enabled for vIOMMU). In
that case we need to notify all the registered components about the new
mapping.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6f26bcb..ed60cfa 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1152,6 +1152,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState 
*s,
 trace_vtd_inv_desc_cc_device(bus_n, (devfn_it >> 3) & 0x1f,
  devfn_it & 3);
 vtd_as->context_cache_entry.context_cache_gen = 0;
+memory_region_iommu_replay_all(_as->iommu);
 }
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 11/17] memory: provide iommu_replay_all()

2017-01-02 Thread Peter Xu
This is an "global" version of exising memory_region_iommu_replay() - we
announce the translations to all the registered notifiers, instead of a
specific one.

Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 8 
 memory.c  | 9 +
 2 files changed, 17 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index cecfed1..d8363a0 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -694,6 +694,14 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 bool is_write);
 
 /**
+ * memory_region_iommu_replay_all: replay existing IOMMU translations
+ * to all the notifiers registered.
+ *
+ * @mr: the memory region to observe
+ */
+void memory_region_iommu_replay_all(MemoryRegion *mr);
+
+/**
  * memory_region_unregister_iommu_notifier: unregister a notifier for
  * changes to IOMMU translation entries.
  *
diff --git a/memory.c b/memory.c
index e88bb54..df62bd1 100644
--- a/memory.c
+++ b/memory.c
@@ -1645,6 +1645,15 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 }
 }
 
+void memory_region_iommu_replay_all(MemoryRegion *mr)
+{
+IOMMUNotifier *notifier;
+
+QLIST_FOREACH(notifier, >iommu_notify, node) {
+memory_region_iommu_replay(mr, notifier, false);
+}
+}
+
 void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
  IOMMUNotifier *n)
 {
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 10/17] memory: add section range info for IOMMU notifier

2017-01-02 Thread Peter Xu
In this patch, IOMMUNotifier.{start|end} are introduced to store section
information for a specific notifier. When notification occurs, we not
only check the notification type (MAP|UNMAP), but also check whether the
notified iova is in the range of specific IOMMU notifier, and skip those
notifiers if not in the listened range.

When removing an region, we need to make sure we removed the correct
VFIOGuestIOMMU by checking the IOMMUNotifier.start address as well.

Suggested-by: David Gibson 
Reviewed-by: David Gibson 
Signed-off-by: Peter Xu 
---
 hw/vfio/common.c  | 7 ++-
 include/exec/memory.h | 3 +++
 memory.c  | 4 +++-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 801578b..6f648da 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -455,6 +455,10 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 giommu->container = container;
 giommu->n.notify = vfio_iommu_map_notify;
 giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
+giommu->n.start = section->offset_within_region;
+llend = int128_add(int128_make64(giommu->n.start), section->size);
+llend = int128_sub(llend, int128_one());
+giommu->n.end = int128_get64(llend);
 QLIST_INSERT_HEAD(>giommu_list, giommu, giommu_next);
 
 memory_region_register_iommu_notifier(giommu->iommu, >n);
@@ -525,7 +529,8 @@ static void vfio_listener_region_del(MemoryListener 
*listener,
 VFIOGuestIOMMU *giommu;
 
 QLIST_FOREACH(giommu, >giommu_list, giommu_next) {
-if (giommu->iommu == section->mr) {
+if (giommu->iommu == section->mr &&
+giommu->n.start == section->offset_within_region) {
 memory_region_unregister_iommu_notifier(giommu->iommu,
 >n);
 QLIST_REMOVE(giommu, giommu_next);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 958f4b2..cecfed1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -84,6 +84,9 @@ typedef enum {
 struct IOMMUNotifier {
 void (*notify)(struct IOMMUNotifier *notifier, IOMMUTLBEntry *data);
 IOMMUNotifierFlag notifier_flags;
+/* Notify for address space range start <= addr <= end */
+hwaddr start;
+hwaddr end;
 QLIST_ENTRY(IOMMUNotifier) node;
 };
 typedef struct IOMMUNotifier IOMMUNotifier;
diff --git a/memory.c b/memory.c
index 2bfc37f..e88bb54 100644
--- a/memory.c
+++ b/memory.c
@@ -1671,7 +1671,9 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 }
 
 QLIST_FOREACH(iommu_notifier, >iommu_notify, node) {
-if (iommu_notifier->notifier_flags & request_flags) {
+if (iommu_notifier->notifier_flags & request_flags &&
+iommu_notifier->start <= entry.iova &&
+iommu_notifier->end >= entry.iova) {
 iommu_notifier->notify(iommu_notifier, );
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 13/17] memory: add MemoryRegionIOMMUOps.replay() callback

2017-01-02 Thread Peter Xu
Originally we have one memory_region_iommu_replay() function, which is
the default behavior to replay the translations of the whole IOMMU
region. However, on some platform like x86, we may want our own replay
logic for IOMMU regions. This patch add one more hook for IOMMUOps for
the callback, and it'll override the default if set.

Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 2 ++
 memory.c  | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index afe150c..a26763f 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -181,6 +181,8 @@ struct MemoryRegionIOMMUOps {
 void (*notify_flag_changed)(MemoryRegion *iommu,
 IOMMUNotifierFlag old_flags,
 IOMMUNotifierFlag new_flags);
+/* Set this up to provide customized IOMMU replay function */
+void (*replay)(MemoryRegion *iommu, IOMMUNotifier *notifier);
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
diff --git a/memory.c b/memory.c
index 6e4c872..609ac67 100644
--- a/memory.c
+++ b/memory.c
@@ -1629,6 +1629,12 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 hwaddr addr, granularity;
 IOMMUTLBEntry iotlb;
 
+/* If the IOMMU has its own replay callback, override */
+if (mr->iommu_ops->replay) {
+mr->iommu_ops->replay(mr, n);
+return;
+}
+
 granularity = memory_region_iommu_get_min_page_size(mr);
 
 for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 12/17] memory: introduce memory_region_notify_one()

2017-01-02 Thread Peter Xu
Generalizing the notify logic in memory_region_notify_iommu() into a
single function. This can be further used in customized replay()
functions for IOMMUs.

Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 15 +++
 memory.c  | 29 ++---
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index d8363a0..afe150c 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -669,6 +669,21 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 IOMMUTLBEntry entry);
 
 /**
+ * memory_region_notify_one: notify a change in an IOMMU translation
+ *   entry to a single notifier
+ *
+ * This works just like memory_region_notify_iommu(), but it only
+ * notifies a specific notifier, not all of them.
+ *
+ * @notifier: the notifier to be notified
+ * @entry: the new entry in the IOMMU translation table.  The entry
+ * replaces all old entries for the same virtual I/O address range.
+ * Deleted entries have .@perm == 0.
+ */
+void memory_region_notify_one(IOMMUNotifier *notifier,
+  IOMMUTLBEntry *entry);
+
+/**
  * memory_region_register_iommu_notifier: register a notifier for changes to
  * IOMMU translation entries.
  *
diff --git a/memory.c b/memory.c
index df62bd1..6e4c872 100644
--- a/memory.c
+++ b/memory.c
@@ -1665,26 +1665,33 @@ void 
memory_region_unregister_iommu_notifier(MemoryRegion *mr,
 memory_region_update_iommu_notify_flags(mr);
 }
 
-void memory_region_notify_iommu(MemoryRegion *mr,
-IOMMUTLBEntry entry)
+void memory_region_notify_one(IOMMUNotifier *notifier,
+  IOMMUTLBEntry *entry)
 {
-IOMMUNotifier *iommu_notifier;
 IOMMUNotifierFlag request_flags;
 
-assert(memory_region_is_iommu(mr));
-
-if (entry.perm & IOMMU_RW) {
+if (entry->perm & IOMMU_RW) {
 request_flags = IOMMU_NOTIFIER_MAP;
 } else {
 request_flags = IOMMU_NOTIFIER_UNMAP;
 }
 
+if (notifier->notifier_flags & request_flags &&
+notifier->start <= entry->iova &&
+notifier->end >= entry->iova) {
+notifier->notify(notifier, entry);
+}
+}
+
+void memory_region_notify_iommu(MemoryRegion *mr,
+IOMMUTLBEntry entry)
+{
+IOMMUNotifier *iommu_notifier;
+
+assert(memory_region_is_iommu(mr));
+
 QLIST_FOREACH(iommu_notifier, >iommu_notify, node) {
-if (iommu_notifier->notifier_flags & request_flags &&
-iommu_notifier->start <= entry.iova &&
-iommu_notifier->end >= entry.iova) {
-iommu_notifier->notify(iommu_notifier, );
-}
+memory_region_notify_one(iommu_notifier, );
 }
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 09/17] intel_iommu: vtd_slpt_level_shift check level

2017-01-02 Thread Peter Xu
This helps in debugging incorrect level passed in.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f1118dd..abb9d2e 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -168,6 +168,7 @@ static gboolean vtd_hash_remove_by_domain(gpointer key, 
gpointer value,
 /* The shift of an addr for a certain level of paging structure */
 static inline uint32_t vtd_slpt_level_shift(uint32_t level)
 {
+assert(level != 0);
 return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 08/17] intel_iommu: fix trace for addr translation

2017-01-02 Thread Peter Xu
Another patch to convert the DPRINTF() stuffs. This patch focuses on the
address translation path and caching.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 87 ---
 hw/i386/trace-events  |  7 +
 2 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 36ea90f..f1118dd 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -260,11 +260,9 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t 
source_id,
 uint64_t *key = g_malloc(sizeof(*key));
 uint64_t gfn = vtd_get_iotlb_gfn(addr, level);
 
-VTD_DPRINTF(CACHE, "update iotlb sid 0x%"PRIx16 " iova 0x%"PRIx64
-" slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr, slpte,
-domain_id);
+trace_vtd_iotlb_page_update(source_id, addr, slpte, domain_id);
 if (g_hash_table_size(s->iotlb) >= VTD_IOTLB_MAX_SIZE) {
-VTD_DPRINTF(CACHE, "iotlb exceeds size limit, forced to reset");
+trace_vtd_iotlb_reset("iotlb exceeds size limit");
 vtd_reset_iotlb(s);
 }
 
@@ -505,8 +503,8 @@ static int vtd_get_root_entry(IntelIOMMUState *s, uint8_t 
index,
 
 addr = s->root + index * sizeof(*re);
 if (dma_memory_read(_space_memory, addr, re, sizeof(*re))) {
-VTD_DPRINTF(GENERAL, "error: fail to access root-entry at 0x%"PRIx64
-" + %"PRIu8, s->root, index);
+error_report("Fail to access root-entry at 0x%"PRIx64
+ " index %"PRIu8, s->root, index);
 re->val = 0;
 return -VTD_FR_ROOT_TABLE_INV;
 }
@@ -525,13 +523,12 @@ static int vtd_get_context_entry_from_root(VTDRootEntry 
*root, uint8_t index,
 dma_addr_t addr;
 
 if (!vtd_root_entry_present(root)) {
-VTD_DPRINTF(GENERAL, "error: root-entry is not present");
+error_report("Root-entry is not present");
 return -VTD_FR_ROOT_ENTRY_P;
 }
 addr = (root->val & VTD_ROOT_ENTRY_CTP) + index * sizeof(*ce);
 if (dma_memory_read(_space_memory, addr, ce, sizeof(*ce))) {
-VTD_DPRINTF(GENERAL, "error: fail to access context-entry at 0x%"PRIx64
-" + %"PRIu8,
+error_report("Fail to access context-entry at 0x%"PRIx64" ind %"PRIu8,
 (uint64_t)(root->val & VTD_ROOT_ENTRY_CTP), index);
 return -VTD_FR_CONTEXT_TABLE_INV;
 }
@@ -644,7 +641,7 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
  * in CAP_REG and AW in context-entry.
  */
 if (iova & ~((1ULL << MIN(ce_agaw, VTD_MGAW)) - 1)) {
-VTD_DPRINTF(GENERAL, "error: iova 0x%"PRIx64 " exceeds limits", iova);
+error_report("IOVA 0x%"PRIx64 " exceeds limits", iova);
 return -VTD_FR_ADDR_BEYOND_MGAW;
 }
 
@@ -656,7 +653,7 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
 slpte = vtd_get_slpte(addr, offset);
 
 if (slpte == (uint64_t)-1) {
-VTD_DPRINTF(GENERAL, "error: fail to access second-level paging "
+error_report("Fail to access second-level paging "
 "entry at level %"PRIu32 " for iova 0x%"PRIx64,
 level, iova);
 if (level == vtd_get_level_from_context_entry(ce)) {
@@ -669,13 +666,13 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
 *reads = (*reads) && (slpte & VTD_SL_R);
 *writes = (*writes) && (slpte & VTD_SL_W);
 if (!(slpte & access_right_check)) {
-VTD_DPRINTF(GENERAL, "error: lack of %s permission for "
-"iova 0x%"PRIx64 " slpte 0x%"PRIx64,
-(is_write ? "write" : "read"), iova, slpte);
+error_report("Lack of %s permission for iova 0x%"PRIx64
+ " slpte 0x%"PRIx64,
+ (is_write ? "write" : "read"), iova, slpte);
 return is_write ? -VTD_FR_WRITE : -VTD_FR_READ;
 }
 if (vtd_slpte_nonzero_rsvd(slpte, level)) {
-VTD_DPRINTF(GENERAL, "error: non-zero reserved field in second "
+error_report("Non-zero reserved field in second "
 "level paging entry level %"PRIu32 " slpte 0x%"PRIx64,
 level, slpte);
 return -VTD_FR_PAGING_ENTRY_RSVD;
@@ -704,12 +701,13 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, 
uint8_t bus_num,
 }
 
 if (!vtd_root_entry_present()) {
-VTD_DPRINTF(GENERAL, "error: root-entry #%"PRIu8 " is not present",
-bus_num);
+/* Not error - it's okay we don't have root entry. */
+trace_vtd_re_not_present(bus_num);
 return -VTD_FR_ROOT_ENTRY_P;
 } else if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD)) {
-VTD_DPRINTF(GENERAL, "error: non-zero reserved field in root-entry "
-"hi 0x%"PRIx64 " 

[Qemu-devel] [PATCH RFC v2 06/17] intel_iommu: renaming gpa to iova where proper

2017-01-02 Thread Peter Xu
There are lots of places in current intel_iommu.c codes that named
"iova" as "gpa". It is really confusing to use a name "gpa" in these
places (which is very easily to be understood as "Guest Physical
Address", while it's not). To make the codes (much) easier to be read, I
decided to do this once and for all.

No functional change is made. Only literal ones.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 74243b5..6009091 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -259,7 +259,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t 
source_id,
 uint64_t *key = g_malloc(sizeof(*key));
 uint64_t gfn = vtd_get_iotlb_gfn(addr, level);
 
-VTD_DPRINTF(CACHE, "update iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64
+VTD_DPRINTF(CACHE, "update iotlb sid 0x%"PRIx16 " iova 0x%"PRIx64
 " slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr, slpte,
 domain_id);
 if (g_hash_table_size(s->iotlb) >= VTD_IOTLB_MAX_SIZE) {
@@ -575,12 +575,12 @@ static uint64_t vtd_get_slpte(dma_addr_t base_addr, 
uint32_t index)
 return slpte;
 }
 
-/* Given a gpa and the level of paging structure, return the offset of current
- * level.
+/* Given an iova and the level of paging structure, return the offset
+ * of current level.
  */
-static inline uint32_t vtd_gpa_level_offset(uint64_t gpa, uint32_t level)
+static inline uint32_t vtd_iova_level_offset(uint64_t iova, uint32_t level)
 {
-return (gpa >> vtd_slpt_level_shift(level)) &
+return (iova >> vtd_slpt_level_shift(level)) &
 ((1ULL << VTD_SL_LEVEL_BITS) - 1);
 }
 
@@ -628,10 +628,10 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, 
uint32_t level)
 }
 }
 
-/* Given the @gpa, get relevant @slptep. @slpte_level will be the last level
+/* Given the @iova, get relevant @slptep. @slpte_level will be the last level
  * of the translation, can be used for deciding the size of large page.
  */
-static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t gpa, bool is_write,
+static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_write,
 uint64_t *slptep, uint32_t *slpte_level,
 bool *reads, bool *writes)
 {
@@ -642,11 +642,11 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
gpa, bool is_write,
 uint32_t ce_agaw = vtd_get_agaw_from_context_entry(ce);
 uint64_t access_right_check;
 
-/* Check if @gpa is above 2^X-1, where X is the minimum of MGAW in CAP_REG
- * and AW in context-entry.
+/* Check if @iova is above 2^X-1, where X is the minimum of MGAW
+ * in CAP_REG and AW in context-entry.
  */
-if (gpa & ~((1ULL << MIN(ce_agaw, VTD_MGAW)) - 1)) {
-VTD_DPRINTF(GENERAL, "error: gpa 0x%"PRIx64 " exceeds limits", gpa);
+if (iova & ~((1ULL << MIN(ce_agaw, VTD_MGAW)) - 1)) {
+VTD_DPRINTF(GENERAL, "error: iova 0x%"PRIx64 " exceeds limits", iova);
 return -VTD_FR_ADDR_BEYOND_MGAW;
 }
 
@@ -654,13 +654,13 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
gpa, bool is_write,
 access_right_check = is_write ? VTD_SL_W : VTD_SL_R;
 
 while (true) {
-offset = vtd_gpa_level_offset(gpa, level);
+offset = vtd_iova_level_offset(iova, level);
 slpte = vtd_get_slpte(addr, offset);
 
 if (slpte == (uint64_t)-1) {
 VTD_DPRINTF(GENERAL, "error: fail to access second-level paging "
-"entry at level %"PRIu32 " for gpa 0x%"PRIx64,
-level, gpa);
+"entry at level %"PRIu32 " for iova 0x%"PRIx64,
+level, iova);
 if (level == vtd_get_level_from_context_entry(ce)) {
 /* Invalid programming of context-entry */
 return -VTD_FR_CONTEXT_ENTRY_INV;
@@ -672,8 +672,8 @@ static int vtd_gpa_to_slpte(VTDContextEntry *ce, uint64_t 
gpa, bool is_write,
 *writes = (*writes) && (slpte & VTD_SL_W);
 if (!(slpte & access_right_check)) {
 VTD_DPRINTF(GENERAL, "error: lack of %s permission for "
-"gpa 0x%"PRIx64 " slpte 0x%"PRIx64,
-(is_write ? "write" : "read"), gpa, slpte);
+"iova 0x%"PRIx64 " slpte 0x%"PRIx64,
+(is_write ? "write" : "read"), iova, slpte);
 return is_write ? -VTD_FR_WRITE : -VTD_FR_READ;
 }
 if (vtd_slpte_nonzero_rsvd(slpte, level)) {
@@ -820,7 +820,7 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, 
PCIBus *bus,
 /* Try to fetch slpte form IOTLB */
 iotlb_entry = vtd_lookup_iotlb(s, source_id, addr);
 if (iotlb_entry) {
-VTD_DPRINTF(CACHE, "hit iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64
+VTD_DPRINTF(CACHE, "hit 

[Qemu-devel] [PATCH RFC v2 04/17] intel_iommu: allocate new key when creating new address space

2017-01-02 Thread Peter Xu
From: Jason Wang 

We use the pointer to stack for key for new address space, this will
break hash table searching, fixing by g_malloc() a new key instead.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Acked-by: Peter Xu 
Signed-off-by: Jason Wang 
Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6c7362a..f4d3cce 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2327,12 +2327,13 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
PCIBus *bus, int devfn)
 VTDAddressSpace *vtd_dev_as;
 
 if (!vtd_bus) {
+uintptr_t *new_key = g_malloc(sizeof(*new_key));
+*new_key = (uintptr_t)bus;
 /* No corresponding free() */
 vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
 X86_IOMMU_PCI_DEVFN_MAX);
 vtd_bus->bus = bus;
-key = (uintptr_t)bus;
-g_hash_table_insert(s->vtd_as_by_busptr, , vtd_bus);
+g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
 }
 
 vtd_dev_as = vtd_bus->dev_as[devfn];
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 07/17] intel_iommu: fix trace for inv desc handling

2017-01-02 Thread Peter Xu
VT-d codes are still using static DEBUG_INTEL_IOMMU macro. That's not
good, and we should end the day when we need to recompile the code
before getting useful debugging information for vt-d. Time to switch to
the trace system.

This is the first patch to do it.

Generally, the rule of mine is:

- for the old GENERAL typed message, I use error_report() directly if
  apply. Those are something shouldn't happen, and we should print those
  errors in all cases, even without enabling debug and tracing.

- for the non-GENERAL typed messages, remove those VTD_PRINTF()s that
  looks hardly used, and convert the rest lines into trace_*().

- for useless DPRINTFs, I removed them.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 98 ---
 hw/i386/trace-events  | 13 +++
 2 files changed, 59 insertions(+), 52 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6009091..36ea90f 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -35,6 +35,7 @@
 #include "sysemu/kvm.h"
 #include "hw/i386/apic_internal.h"
 #include "kvm_i386.h"
+#include "trace.h"
 
 /*#define DEBUG_INTEL_IOMMU*/
 #ifdef DEBUG_INTEL_IOMMU
@@ -474,22 +475,19 @@ static void vtd_handle_inv_queue_error(IntelIOMMUState *s)
 /* Set the IWC field and try to generate an invalidation completion interrupt 
*/
 static void vtd_generate_completion_event(IntelIOMMUState *s)
 {
-VTD_DPRINTF(INV, "completes an invalidation wait command with "
-"Interrupt Flag");
 if (vtd_get_long_raw(s, DMAR_ICS_REG) & VTD_ICS_IWC) {
-VTD_DPRINTF(INV, "there is a previous interrupt condition to be "
-"serviced by software, "
-"new invalidation event is not generated");
+trace_vtd_inv_desc_wait_irq("One pending, skip current");
 return;
 }
 vtd_set_clear_mask_long(s, DMAR_ICS_REG, 0, VTD_ICS_IWC);
 vtd_set_clear_mask_long(s, DMAR_IECTL_REG, 0, VTD_IECTL_IP);
 if (vtd_get_long_raw(s, DMAR_IECTL_REG) & VTD_IECTL_IM) {
-VTD_DPRINTF(INV, "IM filed in IECTL_REG is set, new invalidation "
-"event is not generated");
+trace_vtd_inv_desc_wait_irq("IM in IECTL_REG is set, "
+"new event not generated");
 return;
 } else {
 /* Generate the interrupt event */
+trace_vtd_inv_desc_wait_irq("Generating complete event");
 vtd_generate_interrupt(s, DMAR_IEADDR_REG, DMAR_IEDATA_REG);
 vtd_set_clear_mask_long(s, DMAR_IECTL_REG, VTD_IECTL_IP, 0);
 }
@@ -916,6 +914,7 @@ static void vtd_interrupt_remap_table_setup(IntelIOMMUState 
*s)
 
 static void vtd_context_global_invalidate(IntelIOMMUState *s)
 {
+trace_vtd_inv_desc_cc_global();
 s->context_cache_gen++;
 if (s->context_cache_gen == VTD_CONTEXT_CACHE_GEN_MAX) {
 vtd_reset_context_cache(s);
@@ -955,9 +954,11 @@ static void vtd_context_device_invalidate(IntelIOMMUState 
*s,
 uint16_t mask;
 VTDBus *vtd_bus;
 VTDAddressSpace *vtd_as;
-uint16_t devfn;
+uint8_t bus_n, devfn;
 uint16_t devfn_it;
 
+trace_vtd_inv_desc_cc_devices(source_id, func_mask);
+
 switch (func_mask & 3) {
 case 0:
 mask = 0;   /* No bits in the SID field masked */
@@ -973,16 +974,16 @@ static void vtd_context_device_invalidate(IntelIOMMUState 
*s,
 break;
 }
 mask = ~mask;
-VTD_DPRINTF(INV, "device-selective invalidation source 0x%"PRIx16
-" mask %"PRIu16, source_id, mask);
-vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id));
+
+bus_n = VTD_SID_TO_BUS(source_id);
+vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
 if (vtd_bus) {
 devfn = VTD_SID_TO_DEVFN(source_id);
 for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
 vtd_as = vtd_bus->dev_as[devfn_it];
 if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
-VTD_DPRINTF(INV, "invalidate context-cahce of devfn 0x%"PRIx16,
-devfn_it);
+trace_vtd_inv_desc_cc_device(bus_n, (devfn_it >> 3) & 0x1f,
+ devfn_it & 3);
 vtd_as->context_cache_entry.context_cache_gen = 0;
 }
 }
@@ -1295,7 +1296,7 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, 
VTDInvDesc *inv_desc)
 {
 if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) ||
 (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) {
-VTD_DPRINTF(GENERAL, "error: non-zero reserved field in Invalidation "
+error_report("Non-zero reserved field in Invalidation "
 "Wait Descriptor hi 0x%"PRIx64 " lo 0x%"PRIx64,
 inv_desc->hi, inv_desc->lo);
 return false;
@@ -1309,21 +1310,20 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, 
VTDInvDesc *inv_desc)
 
 /* FIXME: need 

[Qemu-devel] [PATCH RFC v2 03/17] memory: handle alias in memory_region_is_iommu()

2017-01-02 Thread Peter Xu
From: Jason Wang 

Cc: Paolo Bonzini 
Acked-by: Paolo Bonzini 
Signed-off-by: Jason Wang 
Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 64560f6..958f4b2 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -628,6 +628,9 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
  */
 static inline bool memory_region_is_iommu(MemoryRegion *mr)
 {
+if (mr->alias) {
+return memory_region_is_iommu(mr->alias);
+}
 return mr->iommu_ops;
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 05/17] intel_iommu: simplify irq region translation

2017-01-02 Thread Peter Xu
Before we have int-remap, we need to bypass interrupt write requests.
That's not necessary now - we have supported int-remap, and all the irq
region requests should be redirected there. Cleaning up the block with
an assertion instead.

Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c | 28 ++--
 1 file changed, 6 insertions(+), 22 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f4d3cce..74243b5 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -811,28 +811,12 @@ static void vtd_do_iommu_translate(VTDAddressSpace 
*vtd_as, PCIBus *bus,
 bool writes = true;
 VTDIOTLBEntry *iotlb_entry;
 
-/* Check if the request is in interrupt address range */
-if (vtd_is_interrupt_addr(addr)) {
-if (is_write) {
-/* FIXME: since we don't know the length of the access here, we
- * treat Non-DWORD length write requests without PASID as
- * interrupt requests, too. Withoud interrupt remapping support,
- * we just use 1:1 mapping.
- */
-VTD_DPRINTF(MMU, "write request to interrupt address "
-"gpa 0x%"PRIx64, addr);
-entry->iova = addr & VTD_PAGE_MASK_4K;
-entry->translated_addr = addr & VTD_PAGE_MASK_4K;
-entry->addr_mask = ~VTD_PAGE_MASK_4K;
-entry->perm = IOMMU_WO;
-return;
-} else {
-VTD_DPRINTF(GENERAL, "error: read request from interrupt address "
-"gpa 0x%"PRIx64, addr);
-vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write);
-return;
-}
-}
+/*
+ * We have standalone memory region for interrupt addresses, we
+ * should never receive translation requests in this region.
+ */
+assert(!vtd_is_interrupt_addr(addr));
+
 /* Try to fetch slpte form IOTLB */
 iotlb_entry = vtd_lookup_iotlb(s, source_id, addr);
 if (iotlb_entry) {
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 01/17] IOMMU: add option to enable VTD_CAP_CM to vIOMMU capility exposoed to guest

2017-01-02 Thread Peter Xu
From: Aviv Ben-David 

This capability asks the guest to invalidate cache before each map operation.
We can use this invalidation to trap map operations in the hypervisor.

Signed-off-by: Aviv Ben-David 
Signed-off-by: Peter Xu 
---
 hw/i386/intel_iommu.c  | 5 +
 hw/i386/intel_iommu_internal.h | 1 +
 include/hw/i386/intel_iommu.h  | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 5f3e351..6c7362a 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2018,6 +2018,7 @@ static Property vtd_properties[] = {
 DEFINE_PROP_ON_OFF_AUTO("eim", IntelIOMMUState, intr_eim,
 ON_OFF_AUTO_AUTO),
 DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false),
+DEFINE_PROP_BOOL("cache-mode", IntelIOMMUState, cache_mode_enabled, FALSE),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2392,6 +2393,10 @@ static void vtd_init(IntelIOMMUState *s)
 assert(s->intr_eim != ON_OFF_AUTO_AUTO);
 }
 
+if (s->cache_mode_enabled) {
+s->cap |= VTD_CAP_CM;
+}
+
 vtd_reset_context_cache(s);
 vtd_reset_iotlb(s);
 
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 11abfa2..00cbe0d 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -201,6 +201,7 @@
 #define VTD_CAP_MAMV(VTD_MAMV << 48)
 #define VTD_CAP_PSI (1ULL << 39)
 #define VTD_CAP_SLLPS   ((1ULL << 34) | (1ULL << 35))
+#define VTD_CAP_CM  (1ULL << 7)
 
 /* Supported Adjusted Guest Address Widths */
 #define VTD_CAP_SAGAW_SHIFT 8
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 405c9d1..749eef9 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -257,6 +257,8 @@ struct IntelIOMMUState {
 uint8_t womask[DMAR_REG_SIZE];  /* WO (write only - read returns 0) */
 uint32_t version;
 
+bool cache_mode_enabled;/* RO - is cap CM enabled? */
+
 dma_addr_t root;/* Current root table pointer */
 bool root_extended; /* Type of root table (extended or not) */
 bool dmar_enabled;  /* Set if DMA remapping is enabled */
-- 
2.7.4




[Qemu-devel] [PATCH RFC v2 00/17] VT-d: vfio enablement and misc enhances

2017-01-02 Thread Peter Xu
(I renamed the title for this RFC v2, since starting from this version
 the series will be based on master, also I picked up some more fixes
 for vt-d into this series)

v2:
- change comment for "end" parameter in vtd_page_walk() [Tianyu]
- change comment for "a iova" to "an iova" [Yi]
- fix fault printed val for GPA address in vtd_page_walk_level (debug
  only)
- rebased to master (rather than Aviv's v6 series) and merged Aviv's
  series v6: picked patch 1 (as patch 1 in this series), dropped patch
  2, re-wrote patch 3 (as patch 17 of this series).
- picked up two more bugfix patches from Jason's DMAR series
- picked up the following patch as well:
  "[PATCH v3] intel_iommu: allow dynamic switch of IOMMU region"

This RFC series is a re-work for Aviv B.D.'s vfio enablement series
with vt-d:

  https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01452.html

Aviv has done a great job there, and what we still lack there are
mostly the following:

(1) VFIO got duplicated IOTLB notifications due to splitted VT-d IOMMU
memory region.

(2) VT-d still haven't provide a correct replay() mechanism (e.g.,
when IOMMU domain switches, things will broke).

This series should have solved the above two issues.

Online repo:

  https://github.com/xzpeter/qemu/tree/vtd-vfio-enablement-v2

I would be glad to hear about any review comments for above patches.

=
Test Done
=

Build test passed for x86_64/arm/ppc64.

Simply tested with x86_64, assigning two PCI devices to a single VM,
boot the VM using:

bin=x86_64-softmmu/qemu-system-x86_64
$bin -M q35,accel=kvm,kernel-irqchip=split -m 1G \
 -device intel-iommu,intremap=on,eim=off,cache-mode=on \
 -netdev user,id=net0,hostfwd=tcp::-:22 \
 -device virtio-net-pci,netdev=net0 \
 -device vfio-pci,host=03:00.0 \
 -device vfio-pci,host=02:00.0 \
 -trace events=".trace.vfio" \
 /var/lib/libvirt/images/vm1.qcow2

pxdev:bin [vtd-vfio-enablement]# cat .trace.vfio
vtd_page_walk*
vtd_replay*
vtd_inv_desc*

Then, in the guest, run the following tool:

  
https://github.com/xzpeter/clibs/blob/master/gpl/userspace/vfio-bind-group/vfio-bind-group.c

With parameter:

  ./vfio-bind-group 00:03.0 00:04.0

Check host side trace log, I can see pages are replayed and mapped in
00:04.0 device address space, like:

...
vtd_replay_ce_valid replay valid context device 00:04.00 hi 0x401 lo 0x38fe1001
vtd_page_walk Page walk for ce (0x401, 0x38fe1001) iova range 0x0 - 0x80
vtd_page_walk_level Page walk (base=0x38fe1000, level=3) iova range 0x0 - 
0x80
vtd_page_walk_level Page walk (base=0x35d31000, level=2) iova range 0x0 - 
0x4000
vtd_page_walk_level Page walk (base=0x34979000, level=1) iova range 0x0 - 
0x20
vtd_page_walk_one Page walk detected map level 0x1 iova 0x0 -> gpa 0x22dc3000 
mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x1000 -> gpa 
0x22e25000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x2000 -> gpa 
0x22e12000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x3000 -> gpa 
0x22e2d000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x4000 -> gpa 
0x12a49000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x5000 -> gpa 
0x129bb000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x6000 -> gpa 
0x128db000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x7000 -> gpa 
0x12a8 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x8000 -> gpa 
0x12a7e000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0x9000 -> gpa 
0x12b22000 mask 0xfff perm 3
vtd_page_walk_one Page walk detected map level 0x1 iova 0xa000 -> gpa 
0x12b41000 mask 0xfff perm 3
...

=
Todo List
=

- error reporting for the assigned devices (as Tianyu has mentioned)

- per-domain address-space: A better solution in the future may be -
  we maintain one address space per IOMMU domain in the guest (so
  multiple devices can share a same address space if they are sharing
  the same IOMMU domains in the guest), rather than one address space
  per device (which is current implementation of vt-d). However that's
  a step further than this series, and let's see whether we can first
  provide a workable version of device assignment with vt-d
  protection.

- more to come...

Thanks,

Aviv Ben-David (1):
  IOMMU: add option to enable VTD_CAP_CM to vIOMMU capility exposoed to
guest

Jason Wang (3):
  memory: handle alias for iommu notifier
  memory: handle alias in memory_region_is_iommu()
  intel_iommu: allocate new key when creating new address space

Peter Xu (13):
  intel_iommu: simplify irq region translation
  intel_iommu: renaming gpa to iova where proper
  intel_iommu: fix trace for inv desc handling
  intel_iommu: fix trace for addr translation
  intel_iommu: vtd_slpt_level_shift check level
  

[Qemu-devel] [PATCH RFC v2 02/17] memory: handle alias for iommu notifier

2017-01-02 Thread Peter Xu
From: Jason Wang 

Cc: Paolo Bonzini 
Acked-by: Paolo Bonzini 
Signed-off-by: Jason Wang 
Signed-off-by: Peter Xu 
---
 memory.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/memory.c b/memory.c
index 33110e9..2bfc37f 100644
--- a/memory.c
+++ b/memory.c
@@ -1603,6 +1603,11 @@ static void 
memory_region_update_iommu_notify_flags(MemoryRegion *mr)
 void memory_region_register_iommu_notifier(MemoryRegion *mr,
IOMMUNotifier *n)
 {
+if (mr->alias) {
+memory_region_register_iommu_notifier(mr->alias, n);
+return;
+}
+
 /* We need to register for at least one bitfield */
 assert(n->notifier_flags != IOMMU_NOTIFIER_NONE);
 QLIST_INSERT_HEAD(>iommu_notify, n, node);
@@ -1643,6 +1648,10 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
  IOMMUNotifier *n)
 {
+if (mr->alias) {
+memory_region_unregister_iommu_notifier(mr->alias, n);
+return;
+}
 QLIST_REMOVE(n, node);
 memory_region_update_iommu_notify_flags(mr);
 }
-- 
2.7.4




Re: [Qemu-devel] [PATCH] dp8393x: fix dp8393x_receive

2017-01-02 Thread Laurent Vivier
Le 03/01/2017 à 04:37, Jason Wang a écrit :
> 
> 
> On 2017年01月02日 07:00, Laurent Vivier wrote:
>> address_space_rw() access size must be multiplied by width.
>> dp8393x_receive() must return the number of bytes read, not the length
>> of the last memory access.
>>
>> Signed-off-by: Laurent Vivier 
>> ---
>>   hw/net/dp8393x.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
>> index 17f0338..3506bca 100644
>> --- a/hw/net/dp8393x.c
>> +++ b/hw/net/dp8393x.c
>> @@ -766,10 +766,11 @@ static ssize_t dp8393x_receive(NetClientState
>> *nc, const uint8_t * buf,
>>   /* EOL detected */
>>   s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
>>   } else {
>> +size = sizeof(uint16_t) * width;
>>   data[0 * width] = 0; /* in_use */
>>   address_space_rw(>as,
>>   ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) +
>> sizeof(uint16_t) * 6 * width,
>> -MEMTXATTRS_UNSPECIFIED, (uint8_t *)data,
>> sizeof(uint16_t), 1);
>> +MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1);
> 
> I think patch makes different only when width is 2. But if we just want
> to tag in_use flag, sizeof(uint16_t) should be sufficient?

In fact, I'm using this device to implement Quadra 800 macsonic
emulation, and in this case all registers are byteswapped according the
size of width (32bit in my case, see kernel sources,
drivers/net/ethernet/natsemi/sonic.h and macsonic.c), so debugging the
kernel I've seen used part of the register is never cleared.

Thanks,
Laurent




[Qemu-devel] [PATCH] virtio-crypto: fix possible integer and heap overflow

2017-01-02 Thread Gonglei
Because the 'size_t' type is 4 bytes in 32-bit platform, which
is the same with 'int'. It's easy to make 'max_len' to zero when
integer overflow and then cause heap overflow if 'max_len' is zero.

Using uint_64 instead of size_t to avoid the integer overflow.

Cc: qemu-sta...@nongnu.org
Reported-by: Li Qiang 
Signed-off-by: Gonglei 
Tested-by: Li Qiang 
---
 hw/virtio/virtio-crypto.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 978bb98..fc30bc3 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -416,7 +416,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
 uint32_t hash_start_src_offset = 0, len_to_hash = 0;
 uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
 
-size_t max_len, curr_size = 0;
+uint64_t max_len, curr_size = 0;
 size_t s;
 
 /* Plain cipher */
@@ -441,7 +441,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
 return NULL;
 }
 
-max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
+max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len;
 if (unlikely(max_len > vcrypto->conf.max_size)) {
 virtio_error(vdev, "virtio-crypto too big length");
 return NULL;
-- 
1.8.3.1





Re: [Qemu-devel] [PATCH v10 16/26] intel_iommu: add support for split irqchip

2017-01-02 Thread Peter Xu
On Sun, Jun 26, 2016 at 03:27:50PM +0200, Jan Kiszka wrote:
> On 2016-06-26 03:48, Peter Xu wrote:
> > On Sat, Jun 25, 2016 at 05:18:40PM +0200, Jan Kiszka wrote:
> >> On 2016-06-25 15:18, Peter Xu wrote:
> >>> On Sat, Jun 25, 2016 at 10:08:10AM +0200, Jan Kiszka wrote:
> > 
> > [...]
> > 
> >>> I have a thought on how to implement the "sink" you have mentioned:
> >>>
> >>> First of all, in KVM, we provide a new KVM_IRQ_ROUTING_* type, maybe
> >>> called:
> >>>
> >>>   KVM_IRQ_ROUTING_EVENTFD
> >>
> >> Not really, because all sources are either using eventfds, which you can
> >> also terminate in user space (already done for vhost and vfio in certain
> >> scenarios - IIRC) or originate there anyway (IOAPIC).
> > 
> > But how should we handle the cases when the interrupt path are all in
> > kernel?
> 
> There are none which we can't redirect (only full in-kernel irqchip
> would have, but that's unsupported anyway).
> 
> > 
> > For vhost, data should be transfered all inside kernel when split
> > irqchip and irqfd are used: when vhost got data, it triggers irqfd to
> > deliver the interrupt to KVM. Along the way, we should all in kernel.
> > 
> > For vfio, we have vfio_msihandler() who handles the hardware IRQ and
> > then triggers irqfd as well to KVM. Again, it seems all in kernel
> > space, no chance to stop that as well.
> > 
> > Please correct me if I was wrong.
> 
> Look at what vhost is doing e.g.: when a virtqueue is masked, it
> installs an event notifier that records incoming events in a pending
> state field. When it's unmasked, the corresponding KVM irqfd is installed.

Hmm I think it's time I pick up this topic up again... :)

Since it's been half a year from the last post of this thread (I
believe this thread is the so-called "cold data" and should be stored
on tapes already... and sorry fot the long delay), I'd like to do a
quick summary on this: interrupt remap still cannot work well when we
install fault interrupts - when that happens, we should inject VT-d
fault, rather than keeping silence.

The suggestion from Jan above should be a good solution that only need
to touch qemu part - that's the most benefit AFAIU. However, OTOH IMO
we need to modify all the kvm irqfd users with this fix (pci-assign,
ioapic, ivshmem, vfio-pci, virtio) - we need to have all these devices
init with an "fault sink" eventfd, then when we detected specific
irqfd install error, we install the "fault sink". What's worse, if we
add new devices with irqfd support, we need to implement the same
error handling logic as well. Am I understanding it correctly? If so,
isn't that awkward?

Now I am re-thinking about my KVM_IRQ_ROUTING_EVENTFD proposal to do
it - in that case, we should not need to worry about the users of kvm
irqfd, and the error handling is done automatically even with new
irqfd users coming in. The disadvantage is of course we need to touch
both qemu and kvm, also we need to touch KVM API for it (though I
think it'll only need very small change in KVM). And not sure whether
that would worth it.

Or, any better way to do it?

Hope I didn't miss anything. Comments are welcomed!

Regards,

-- peterx



Re: [Qemu-devel] [PATCH 5/6] prep: add IBM RS/6000 7020 (40p) memory controller

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:15PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 
> ---
>  default-configs/ppc-softmmu.mak |   1 +
>  hw/ppc/Makefile.objs|   1 +
>  hw/ppc/rs6000_mc.c  | 232 
> 
>  hw/ppc/trace-events |   7 ++
>  4 files changed, 241 insertions(+)
>  create mode 100644 hw/ppc/rs6000_mc.c
> 
> diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
> index d4d0f9b..e567658 100644
> --- a/default-configs/ppc-softmmu.mak
> +++ b/default-configs/ppc-softmmu.mak
> @@ -47,3 +47,4 @@ CONFIG_LIBDECNUMBER=y
>  # For PReP
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
> +CONFIG_RS6000_MC=y
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index db72297..0012934 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -17,6 +17,7 @@ obj-y += ppc4xx_pci.o
>  # PReP
>  obj-$(CONFIG_PREP) += prep.o
>  obj-$(CONFIG_PREP) += prep_systemio.o
> +obj-${CONFIG_RS6000_MC} += rs6000_mc.o
>  # OldWorld PowerMac
>  obj-$(CONFIG_MAC) += mac_oldworld.o
>  # NewWorld PowerMac
> diff --git a/hw/ppc/rs6000_mc.c b/hw/ppc/rs6000_mc.c
> new file mode 100644
> index 000..c684421
> --- /dev/null
> +++ b/hw/ppc/rs6000_mc.c
> @@ -0,0 +1,232 @@
> +/*
> + * QEMU RS/6000 memory controller
> + *
> + * Copyright (c) 2016 Hervé Poussineau
> + *
> + * 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) version 3 or any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/isa/isa.h"
> +#include "exec/address-spaces.h"
> +#include "hw/boards.h"
> +#include "qapi/error.h"
> +#include "trace.h"
> +
> +#define TYPE_RS6000MC "rs6000-mc"
> +#define RS6000MC_DEVICE(obj) \
> +OBJECT_CHECK(RS6000MCState, (obj), TYPE_RS6000MC)
> +
> +typedef struct RS6000MCState {
> +ISADevice parent_obj;
> +/* see US patent 5,684,979 for details (expired 2001-11-04) */
> +uint32_t ram_size;
> +bool autoconfigure;
> +MemoryRegion simm[6];
> +unsigned int simm_size[6];
> +uint32_t end_address[8];
> +uint8_t port0820_index;
> +PortioList portio;
> +} RS6000MCState;
> +
> +/* P0RT 0803 -- SIMM ID Register (32/8 MB) (Read Only) */
> +
> +static uint32_t rs6000mc_port0803_read(void *opaque, uint32_t addr)
> +{
> +RS6000MCState *s = opaque;
> +uint32_t val = 0;
> +int socket;
> +
> +/* (1 << socket) indicates 32 MB SIMM at given socket */
> +for (socket = 0; socket < 6; socket++) {
> +if (s->simm_size[socket] == 32) {
> +val |= (1 << socket);
> +}
> +}
> +
> +trace_rs6000mc_id_read(addr, val);
> +return val;
> +}
> +
> +/* PORT 0804 -- SIMM Presence Register (Read Only) */
> +
> +static uint32_t rs6000mc_port0804_read(void *opaque, uint32_t addr)
> +{
> +RS6000MCState *s = opaque;
> +uint32_t val = 0xff;
> +int socket;
> +
> +/* (1 << socket) indicates SIMM absence at given socket */
> +for (socket = 0; socket < 6; socket++) {
> +if (s->simm_size[socket]) {
> +val &= ~(1 << socket);
> +}
> +}
> +s->port0820_index = 0;
> +
> +trace_rs6000mc_presence_read(addr, val);
> +return val;
> +}
> +
> +/* Memory Controller Size Programming Register */
> +
> +static uint32_t rs6000mc_port0820_read(void *opaque, uint32_t addr)
> +{
> +RS6000MCState *s = opaque;
> +uint32_t val = s->end_address[s->port0820_index] & 0x1f;
> +s->port0820_index = (s->port0820_index + 1) & 7;
> +trace_rs6000mc_size_read(addr, val);
> +return val;
> +}
> +
> +static void rs6000mc_port0820_write(void *opaque, uint32_t addr, uint32_t 
> val)
> +{
> +RS6000MCState *s = opaque;
> +uint8_t socket = val >> 5;
> +uint32_t end_address = val & 0x1f;
> +
> +trace_rs6000mc_size_write(addr, val);
> +s->end_address[socket] = end_address;
> +if (socket > 0 && socket < 7) {
> +if (s->simm_size[socket - 1]) {
> +uint32_t size;
> +uint32_t start_address = 0;
> +if (socket > 1) {
> +start_address = s->end_address[socket - 1];
> +}
> +
> +size = end_address - start_address;
> +memory_region_set_enabled(>simm[socket - 1], size != 0);
> +memory_region_set_address(>simm[socket - 1],
> +  start_address 

Re: [Qemu-devel] [PATCH 6/6] prep: add IBM RS/6000 7020 (40p) machine emulation

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:16PM +0100, Hervé Poussineau wrote:
> Machine supports both Open Hack'Ware and OpenBIOS.
> Open Hack'Ware is the default because OpenBIOS is currently unable to boot
> PReP boot partitions or PReP kernels.
> 
> Signed-off-by: Hervé Poussineau 
> ---
>  default-configs/ppc-softmmu.mak |   1 +
>  hw/ppc/prep.c   | 231 
> 
>  2 files changed, 232 insertions(+)
> 
> diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
> index e567658..7dd004e 100644
> --- a/default-configs/ppc-softmmu.mak
> +++ b/default-configs/ppc-softmmu.mak
> @@ -18,6 +18,7 @@ CONFIG_I82378=y
>  CONFIG_PC87312=y
>  CONFIG_MACIO=y
>  CONFIG_PCSPK=y
> +CONFIG_CS4231A=y
>  CONFIG_CUDA=y
>  CONFIG_ADB=y
>  CONFIG_MAC_NVRAM=y
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 9fb89d3..c0373d1 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -2,6 +2,7 @@
>   * QEMU PPC PREP hardware System Emulator
>   *
>   * Copyright (c) 2003-2007 Jocelyn Mayer
> + * Copyright (c) 2016 Hervé Poussineau
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
>   * of this software and associated documentation files (the "Software"), to 
> deal
> @@ -43,6 +44,7 @@
>  #include "hw/isa/pc87312.h"
>  #include "sysemu/block-backend.h"
>  #include "sysemu/arch_init.h"
> +#include "sysemu/kvm.h"
>  #include "sysemu/qtest.h"
>  #include "exec/address-spaces.h"
>  #include "trace.h"
> @@ -54,6 +56,8 @@
>  
>  #define MAX_IDE_BUS 2
>  
> +#define CFG_ADDR 0xf510
> +
>  #define BIOS_SIZE (1024 * 1024)
>  #define BIOS_FILENAME "ppc_rom.bin"
>  #define KERNEL_LOAD_ADDR 0x0100
> @@ -316,6 +320,12 @@ static uint32_t PREP_io_800_readb (void *opaque, 
> uint32_t addr)
>  
>  #define NVRAM_SIZE0x2000
>  
> +static void fw_cfg_boot_set(void *opaque, const char *boot_device,
> +Error **errp)
> +{
> +fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
> +}
> +
>  static void ppc_prep_reset(void *opaque)
>  {
>  PowerPCCPU *cpu = opaque;
> @@ -677,4 +687,225 @@ static void prep_machine_init(MachineClass *mc)
>  mc->default_boot_order = "cad";
>  }
>  
> +static int prep_set_cmos_checksum(DeviceState *dev, void *opaque)
> +{
> +uint16_t checksum = *(uint16_t *)opaque;
> +ISADevice *rtc;
> +
> +rtc = ISA_DEVICE(object_dynamic_cast(OBJECT(dev), "mc146818rtc"));
> +if (rtc) {

I don't think this is strictly safe though you'll probably get away
with it.  You need to test the result of object_dynamic_cast() against
NULL *before* you upcast it to the IsaDevice.

> +rtc_set_memory(rtc, 0x2e, checksum & 0xff);
> +rtc_set_memory(rtc, 0x3e, checksum & 0xff);
> +rtc_set_memory(rtc, 0x2f, checksum >> 8);
> +rtc_set_memory(rtc, 0x3f, checksum >> 8);
> +}
> +return 0;
> +}
> +
> +static void ibm_40p_init(MachineState *machine)
> +{
> +CPUPPCState *env = NULL;
> +uint16_t cmos_checksum;
> +PowerPCCPU *cpu;
> +DeviceState *dev;
> +SysBusDevice *pcihost;
> +Nvram *m48t59 = NULL;
> +PCIBus *pci_bus;
> +ISABus *isa_bus;
> +void *fw_cfg;
> +const char *vga_type;
> +int i;
> +uint32_t kernel_base = 0, initrd_base = 0;
> +long kernel_size = 0, initrd_size = 0;
> +char boot_device;
> +
> +/* init CPU */
> +if (!machine->cpu_model) {
> +machine->cpu_model = "604";
> +}
> +cpu = cpu_ppc_init(machine->cpu_model);
> +if (cpu == NULL) {
> +fprintf(stderr, "Unable to find PowerPC CPU definition\n");
> +exit(1);
> +}
> +env = >env;
> +
> +if (env->flags & POWERPC_FLAG_RTC_CLK) {
> +/* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
> +cpu_ppc_tb_init(env, 7812500UL);
> +} else {
> +/* Set time-base frequency to 100 Mhz */
> +cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
> +}
> +qemu_register_reset(ppc_prep_reset, cpu);
> +if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
> +hw_error("Only 6xx bus is supported on PREP machine\n");
> +}
> +
> +/* PCI host */
> +dev = qdev_create(NULL, "raven-pcihost");
> +if (!bios_name) {
> +bios_name = BIOS_FILENAME;
> +}
> +qdev_prop_set_string(dev, "bios-name", bios_name);
> +qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE);
> +pcihost = SYS_BUS_DEVICE(dev);
> +object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), 
> NULL);
> +qdev_init_nofail(dev);
> +pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0"));
> +if (pci_bus == NULL) {
> +fprintf(stderr, "Couldn't create PCI host controller.\n");
> +exit(1);
> +}
> +
> +/* PCI -> ISA bridge */
> +dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378"));
> +qdev_connect_gpio_out(dev, 0,
> +  

Re: [Qemu-devel] [PATCH 4/6] prep: QOM'ify System I/O

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:14PM +0100, Hervé Poussineau wrote:
> Part of the functionality is copied from hw/ppc/prep.c.
> Also add support for board identification/equipment registers.
> 
> Signed-off-by: Hervé Poussineau 
> ---
>  hw/ppc/Makefile.objs   |   1 +
>  hw/ppc/prep_systemio.c | 302 
> +
>  hw/ppc/trace-events|   4 +
>  3 files changed, 307 insertions(+)
>  create mode 100644 hw/ppc/prep_systemio.c
> 
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index 8025129..db72297 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -16,6 +16,7 @@ obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o 
> ppc440_bamboo.o
>  obj-y += ppc4xx_pci.o
>  # PReP
>  obj-$(CONFIG_PREP) += prep.o
> +obj-$(CONFIG_PREP) += prep_systemio.o
>  # OldWorld PowerMac
>  obj-$(CONFIG_MAC) += mac_oldworld.o
>  # NewWorld PowerMac
> diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c
> new file mode 100644
> index 000..449056c
> --- /dev/null
> +++ b/hw/ppc/prep_systemio.c
> @@ -0,0 +1,302 @@
> +/*
> + * QEMU PReP System I/O emulation
> + *
> + * Copyright (c) 2016 Herve Poussineau
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/isa/isa.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/error-report.h" /* for error_report() */
> +#include "sysemu/sysemu.h" /* for vm_stop() */
> +#include "cpu.h"
> +#include "trace.h"
> +
> +#define TYPE_PREP_SYSTEMIO "prep-systemio"
> +#define PREP_SYSTEMIO(obj) \
> +OBJECT_CHECK(PrepSystemIoState, (obj), TYPE_PREP_SYSTEMIO)
> +
> +/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */
> +#define PREP_BIT(n) (1 << (7 - (n)))
> +
> +typedef struct PrepSystemIoState {
> +ISADevice parent_obj;
> +MemoryRegion ppc_parity_mem;
> +
> +qemu_irq non_contiguous_io_map_irq;
> +uint8_t sreset; /* 0x0092 */
> +uint8_t equipment; /* 0x080c */
> +uint8_t system_control; /* 0x081c */
> +uint8_t iomap_type; /* 0x0850 */
> +uint8_t ibm_planar_id; /* 0x0852 */
> +qemu_irq softreset_irq;
> +PortioList portio;
> +} PrepSystemIoState;
> +
> +/* PORT 0092 -- Special Port 92 (Read/Write) */
> +
> +enum {
> +PORT0092_SOFTRESET  = PREP_BIT(7),
> +PORT0092_LE_MODE= PREP_BIT(6),
> +};
> +
> +static void prep_port0092_write(void *opaque, uint32_t addr, uint32_t val)
> +{
> +PrepSystemIoState *s = opaque;
> +
> +trace_prep_systemio_write(addr, val);
> +
> +if ((val & PORT0092_SOFTRESET) != 0) {
> +qemu_irq_raise(s->softreset_irq);
> +s->sreset = 1;
> +} else {
> +qemu_irq_lower(s->softreset_irq);
> +s->sreset = 0;

You could just use
s->sreset = val & PORT0092_SOFTRESET;
qemu_set_irq(irq, s->sreset);
here, rather than the if.

> +}
> +
> +if ((val & PORT0092_LE_MODE) != 0) {
> +/* XXX Not supported yet */
> +error_report("little-endian mode not supported");
> +vm_stop(RUN_STATE_PAUSED);
> +} else {
> +/* Nothing to do */
> +}
> +}
> +
> +static uint32_t prep_port0092_read(void *opaque, uint32_t addr)
> +{
> +PrepSystemIoState *s = opaque;
> +/* XXX LE mode unsupported */
> +trace_prep_systemio_read(addr, 0);
> +return s->sreset;

This doesn't seem to quite logically match the write side.  On the
write side you convert the PORT0092_SOFTRESET bit into an explicit
0/1, here you return the raw 0/1.  It ends up being the same thing
because PORT0092_SOFTRESET == 0x01, but that's not terribly obvious.

> +}
> +
> +/* PORT 0808 -- Hardfile Light Register (Write Only) */
> +
> +enum {
> +PORT0808_HARDFILE_LIGHT_ON  = PREP_BIT(7),
> +};
> +
> +static void prep_port0808_write(void *opaque, uint32_t addr, uint32_t val)
> +{
> +trace_prep_systemio_write(addr, val);
> +}
> +
> +/* 

Re: [Qemu-devel] [PATCH 3/6] prep: do not use global variable to access nvram

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:13PM +0100, Hervé Poussineau wrote:
> Signed-off-by: Hervé Poussineau 

This makes sense on its own, so I've applied it to ppc-for-2.9.

> ---
>  hw/ppc/prep.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 054af1e..9fb89d3 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -339,13 +339,13 @@ static PortioList prep_port_list;
>  /* NVRAM helpers */
>  static inline uint32_t nvram_read(Nvram *nvram, uint32_t addr)
>  {
> -NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram);
> +NvramClass *k = NVRAM_GET_CLASS(nvram);
>  return (k->read)(nvram, addr);
>  }
>  
>  static inline void nvram_write(Nvram *nvram, uint32_t addr, uint32_t val)
>  {
> -NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram);
> +NvramClass *k = NVRAM_GET_CLASS(nvram);
>  (k->write)(nvram, addr, val);
>  }
>  

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH V4 08/10] memory: handle alias for iommu notifier

2017-01-02 Thread Peter Xu
On Fri, Dec 30, 2016 at 06:09:17PM +0800, Jason Wang wrote:
> Cc: Paolo Bonzini 
> Acked-by: Paolo Bonzini 
> Signed-off-by: Jason Wang 

Reviewed-by: Peter Xu 

> ---
>  memory.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/memory.c b/memory.c
> index 33110e9..2bfc37f 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1603,6 +1603,11 @@ static void 
> memory_region_update_iommu_notify_flags(MemoryRegion *mr)
>  void memory_region_register_iommu_notifier(MemoryRegion *mr,
> IOMMUNotifier *n)
>  {
> +if (mr->alias) {
> +memory_region_register_iommu_notifier(mr->alias, n);
> +return;
> +}
> +
>  /* We need to register for at least one bitfield */
>  assert(n->notifier_flags != IOMMU_NOTIFIER_NONE);
>  QLIST_INSERT_HEAD(>iommu_notify, n, node);
> @@ -1643,6 +1648,10 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
> IOMMUNotifier *n,
>  void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
>   IOMMUNotifier *n)
>  {
> +if (mr->alias) {
> +memory_region_unregister_iommu_notifier(mr->alias, n);
> +return;
> +}
>  QLIST_REMOVE(n, node);
>  memory_region_update_iommu_notify_flags(mr);
>  }
> -- 
> 2.7.4
> 

-- peterx



Re: [Qemu-devel] [PATCH V4 09/10] memory: handle alias in memory_region_is_iommu()

2017-01-02 Thread Peter Xu
On Fri, Dec 30, 2016 at 06:09:18PM +0800, Jason Wang wrote:
> Cc: Paolo Bonzini 
> Acked-by: Paolo Bonzini 
> Signed-off-by: Jason Wang 

Reviewed-by: Peter Xu 

> ---
>  include/exec/memory.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 358edfb..bec9756 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -628,6 +628,9 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
>   */
>  static inline bool memory_region_is_iommu(MemoryRegion *mr)
>  {
> +if (mr->alias) {
> +return memory_region_is_iommu(mr->alias);
> +}
>  return mr->iommu_ops;
>  }
>  
> -- 
> 2.7.4
> 

-- peterx



Re: [Qemu-devel] [PATCH V4 05/10] intel_iommu: support device iotlb descriptor

2017-01-02 Thread Peter Xu
On Fri, Dec 30, 2016 at 06:09:14PM +0800, Jason Wang wrote:
> This patch enables device IOTLB support for intel iommu. The major
> work is to implement QI device IOTLB descriptor processing and notify
> the device through iommu notifier.
> 
> Cc: Paolo Bonzini 
> Cc: Richard Henderson 
> Cc: Eduardo Habkost 
> Cc: Michael S. Tsirkin 
> Signed-off-by: Jason Wang 

Reviewed-by: Peter Xu 

> ---
>  hw/i386/intel_iommu.c  | 83 
> +++---
>  hw/i386/intel_iommu_internal.h | 13 ++-
>  hw/i386/x86-iommu.c| 17 +
>  include/hw/i386/x86-iommu.h|  1 +
>  4 files changed, 107 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 58ab143..bcbe5a7 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -738,11 +738,18 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, 
> uint8_t bus_num,
>  "context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
>  ce->hi, ce->lo);
>  return -VTD_FR_CONTEXT_ENTRY_INV;
> -} else if (ce->lo & VTD_CONTEXT_ENTRY_TT) {
> -VTD_DPRINTF(GENERAL, "error: unsupported Translation Type in "
> -"context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
> -ce->hi, ce->lo);
> -return -VTD_FR_CONTEXT_ENTRY_INV;
> +} else {
> +switch (ce->lo & VTD_CONTEXT_ENTRY_TT) {
> +case VTD_CONTEXT_TT_MULTI_LEVEL:
> +/* fall through */
> +case VTD_CONTEXT_TT_DEV_IOTLB:
> +break;
> +default:
> +VTD_DPRINTF(GENERAL, "error: unsupported Translation Type in "
> +"context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
> +ce->hi, ce->lo);
> +return -VTD_FR_CONTEXT_ENTRY_INV;
> +}
>  }
>  return 0;
>  }
> @@ -1438,7 +1445,61 @@ static bool vtd_process_inv_iec_desc(IntelIOMMUState 
> *s,
>  vtd_iec_notify_all(s, !inv_desc->iec.granularity,
> inv_desc->iec.index,
> inv_desc->iec.index_mask);
> +return true;
> +}
> +
> +static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
> +  VTDInvDesc *inv_desc)
> +{
> +VTDAddressSpace *vtd_dev_as;
> +IOMMUTLBEntry entry;
> +struct VTDBus *vtd_bus;
> +hwaddr addr;
> +uint64_t sz;
> +uint16_t sid;
> +uint8_t devfn;
> +bool size;
> +uint8_t bus_num;
> +
> +addr = VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->hi);
> +sid = VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->lo);
> +devfn = sid & 0xff;
> +bus_num = sid >> 8;
> +size = VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->hi);
> +
> +if ((inv_desc->lo & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) ||
> +(inv_desc->hi & VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI)) {
> +VTD_DPRINTF(GENERAL, "error: non-zero reserved field in Device "
> +"IOTLB Invalidate Descriptor hi 0x%"PRIx64 " lo 
> 0x%"PRIx64,
> +inv_desc->hi, inv_desc->lo);
> +return false;
> +}
> +
> +vtd_bus = vtd_find_as_from_bus_num(s, bus_num);
> +if (!vtd_bus) {
> +goto done;
> +}
> +
> +vtd_dev_as = vtd_bus->dev_as[devfn];
> +if (!vtd_dev_as) {
> +goto done;
> +}
> +
> +if (size) {
> +sz = 1 << (ctz64(~(addr | (VTD_PAGE_MASK_4K - 1))) + 1);
> +addr &= ~(sz - 1);
> +} else {
> +sz = VTD_PAGE_SIZE;
> +}
>  
> +entry.target_as = _dev_as->as;
> +entry.addr_mask = sz - 1;
> +entry.iova = addr;
> +entry.perm = IOMMU_NONE;
> +entry.translated_addr = 0;
> +memory_region_notify_iommu(entry.target_as->root, entry);
> +
> +done:
>  return true;
>  }
>  
> @@ -1490,6 +1551,14 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
>  }
>  break;
>  
> +case VTD_INV_DESC_DEVICE:
> +VTD_DPRINTF(INV, "Device IOTLB Invalidation Descriptor hi 0x%"PRIx64
> +" lo 0x%"PRIx64, inv_desc.hi, inv_desc.lo);
> +if (!vtd_process_device_iotlb_desc(s, _desc)) {
> +return false;
> +}
> +break;
> +
>  default:
>  VTD_DPRINTF(GENERAL, "error: unkonw Invalidation Descriptor type "
>  "hi 0x%"PRIx64 " lo 0x%"PRIx64 " type %"PRIu8,
> @@ -2395,6 +2464,10 @@ static void vtd_init(IntelIOMMUState *s)
>  assert(s->intr_eim != ON_OFF_AUTO_AUTO);
>  }
>  
> +if (x86_iommu->dt_supported) {
> +s->ecap |= VTD_ECAP_DT;
> +}
> +
>  vtd_reset_context_cache(s);
>  vtd_reset_iotlb(s);
>  
> diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
> index 11abfa2..356f188 100644
> --- a/hw/i386/intel_iommu_internal.h
> +++ b/hw/i386/intel_iommu_internal.h
> @@ -183,6 +183,7 @@
>  /* (offset 

Re: [Qemu-devel] [PATCH] dp8393x: fix dp8393x_receive

2017-01-02 Thread Jason Wang



On 2017年01月02日 07:00, Laurent Vivier wrote:

address_space_rw() access size must be multiplied by width.
dp8393x_receive() must return the number of bytes read, not the length
of the last memory access.

Signed-off-by: Laurent Vivier 
---
  hw/net/dp8393x.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 17f0338..3506bca 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -766,10 +766,11 @@ static ssize_t dp8393x_receive(NetClientState *nc, const 
uint8_t * buf,
  /* EOL detected */
  s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
  } else {
+size = sizeof(uint16_t) * width;
  data[0 * width] = 0; /* in_use */
  address_space_rw(>as,
  ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + 
sizeof(uint16_t) * 6 * width,
-MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, sizeof(uint16_t), 1);
+MEMTXATTRS_UNSPECIFIED, (uint8_t *)data, size, 1);


I think patch makes different only when width is 2. But if we just want 
to tag in_use flag, sizeof(uint16_t) should be sufficient?


Thanks


  s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
  s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX;
  s->regs[SONIC_RSC] = (s->regs[SONIC_RSC] & 0xff00) | (((s->regs[SONIC_RSC] 
& 0x00ff) + 1) & 0x00ff);
@@ -783,7 +784,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const 
uint8_t * buf,
  /* Done */
  dp8393x_update_irq(s);
  
-return size;

+return rx_len;
  }
  
  static void dp8393x_reset(DeviceState *dev)





[Qemu-devel] [Bug 1653577] [NEW] Ability to set umask for 9pfs

2017-01-02 Thread Nathan Rennie-Waldock
Public bug reported:

We should be able to specify the umask for 9pfs so that files created by
the guest can be accessed by other users on the host. Currently they're
only accessible by the user running qemu (and of course, root).

** 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/1653577

Title:
  Ability to set umask for 9pfs

Status in QEMU:
  New

Bug description:
  We should be able to specify the umask for 9pfs so that files created
  by the guest can be accessed by other users on the host. Currently
  they're only accessible by the user running qemu (and of course,
  root).

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



Re: [Qemu-devel] vhost-user breaks after 96a3d98.

2017-01-02 Thread Jason Wang



On 2016年12月30日 20:41, Flavio Leitner wrote:

Hi,

While I was testing vhost-user using OVS 2.5 and DPDK 2.2.0 in the
host and testpmd dpdk 2.2.0 in the guest, I found that the commit
below breaks the environment and no packets gets into the guest.

dpdk port --> OVS --> vhost-user --> guest --> testpmd
  ^--- drops here ^--- no packets here.

commit 96a3d98d2cdbd897ff5ab33427aa4cfb94077665
Author: Jason Wang 
Date:   Mon Aug 1 16:07:58 2016 +0800

 vhost: don't set vring call if no vector
 
 We used to set vring call fd unconditionally even if guest driver does

 not use MSIX for this vritqueue at all. This will cause lots of
 unnecessary userspace access and other checks for drivers does not use
 interrupt at all (e.g virtio-net pmd). So check and clean vring call
 fd if guest does not use any vector for this virtqueue at
 all.
[...]

Thanks,


Hi Flavio:

Thanks for reporting this issue, could this be a bug of vhost-user? (I 
believe virito-net pmd does not use interrupt for rx/tx at all)


Anyway, will try to reproduce it.



Re: [Qemu-devel] [kvm-unit-tests PATCH 0/2] run_tests: support concurrent test execution

2017-01-02 Thread Peter Xu
On Mon, Jan 02, 2017 at 06:07:56PM +0100, Paolo Bonzini wrote:
> 
> 
> On 01/01/2017 11:34, Peter Xu wrote:
> > run_tests.sh is getting slower. Maybe it's time to let it run faster.
> > An obvious issue is that, we were running the tests sequentially in
> > the past.
> > 
> > This series provides another new "-j" parameter. "-j 8" means we run
> > the tests on 8 task queues. That'll fasten the script a lot. A very
> > quick test of mine shows 3x speed boost with 8 task queues.
> > 
> > Most of the changes are in scripts/tash.bash of patch 2, which
> > implemented the main logic for task managements. Please see commit
> > message for more information.
> > 
> > I did a quick "make standalone" test to make sure this series won't
> > break it. However I am not sure whether it'll break other thing that I
> > don't know...
> 
> Would it work if run_tests.sh wrote a Makefile for all the tests (with
> phony targets only), and then simply ran "make -f Makefile.tmp -jN"?

Would this be a little bit tricky? This version 1 is kind-of overkill
(hundreds of lines of codes), I can make it much shorter if you like
in v2 according to Radim's suggestion.

Thanks,

-- peterx



Re: [Qemu-devel] [kvm-unit-tests PATCH 0/2] run_tests: support concurrent test execution

2017-01-02 Thread Peter Xu
On Mon, Jan 02, 2017 at 09:25:56PM +0100, Radim Krčmář wrote:
> 2017-01-02 18:07+0100, Paolo Bonzini:
> > On 01/01/2017 11:34, Peter Xu wrote:
> >> run_tests.sh is getting slower. Maybe it's time to let it run faster.
> >> An obvious issue is that, we were running the tests sequentially in
> >> the past.
> >> 
> >> This series provides another new "-j" parameter. "-j 8" means we run
> >> the tests on 8 task queues. That'll fasten the script a lot. A very
> >> quick test of mine shows 3x speed boost with 8 task queues.
> >> 
> >> Most of the changes are in scripts/tash.bash of patch 2, which
> >> implemented the main logic for task managements. Please see commit
> >> message for more information.
> >> 
> >> I did a quick "make standalone" test to make sure this series won't
> >> break it. However I am not sure whether it'll break other thing that I
> >> don't know...
> > 
> > Would it work if run_tests.sh wrote a Makefile for all the tests (with
> > phony targets only), and then simply ran "make -f Makefile.tmp -jN"?
> 
> We would need to change for_each_unittest to print the command line
> instead of running it and add a executable wrapper for run() from
> scripts/runtime.bash to have something to pass those arguments to.
> After that, we could generate a Makefile.
> 
> I think we can do the queue with ~3 lines of bash and the Makefile would
> complicate it more.
> 
> Btw. I just leaned that xargs provides a simpler, but sufficient,
> queueing functionality, e.g.
> 
>   echo "echo a\0 (sleep 1; echo b)\0 echo c\0 sleep 1\0 echo d" |
> xargs -0 -L 1 -P 2 sh -c

Good to know this. :)

Looks like above example didn't work, I changed it a bit:

  echo -e "echo a\0 sleep 1 && echo b\0 echo c\0 sleep 1 && echo d" | xargs -0 
-L 1 -P 2 sh -c

But I would still prefer not using it - I'll prefer "readability" over
"less lines of codes" in this case.

-- peterx



Re: [Qemu-devel] [kvm-unit-tests PATCH 2/2] run_tests: allow run tests in parallel

2017-01-02 Thread Peter Xu
On Mon, Jan 02, 2017 at 09:18:24PM +0100, Radim Krčmář wrote:
> 2017-01-01 18:34+0800, Peter Xu:
> > run_task.sh is getting slow. This patch is trying to make it faster by
> > running the tests concurrently.
> > 
> > First of all, we provide a new parameter "-j" for the run_tests.sh,
> > which can be used to specify how many run queues we want for the tests.
> > When "-j" is not provided, we'll keep the old behavior.
> > 
> > When the tests are running concurrently, we will use seperate log file
> > for each test case (currently located in logs/ dir, with name
> > test.TESTNAME.log), to avoid test logs messing up with each other.
> > 
> > A quick test on my laptop (x86 with 4 cores and 2 threads, so 8
> > processors) shows 3x improvement on overall test time:
> > 
> >|-+---|
> >| command | time used |
> >|-+---|
> >| run_test.sh | 75s   |
> >| run_test.sh -j8 | 27s   |
> >|-+---|
> > 
> > Signed-off-by: Peter Xu 
> > ---
> > diff --git a/scripts/functions.bash b/scripts/functions.bash
> > @@ -1,7 +1,18 @@
> > +source scripts/global.bash
> > +source scripts/task.bash
> > +
> >  function run_task()
> >  {
> > -   RUNTIME_log_file=$ut_default_log_file
> > -   "$@"
> > +   local testname="$2"
> > +
> > +   if ut_in_parallel; then
> > +   RUNTIME_log_file="${ut_log_dir}/test.${testname}.log"
> 
> No need for the "test." prefix.
> 
> I would do this change regardless of ut_in_parallel.  Having output of
> all tests in one file just wasted time when most usecases were to find a
> specific failed test.
> 
> > +   # run in background
> > +   task_enqueue "$@"
> 
> Couldn't the queue be much simpler ...
> 
> > +   else
> > +   RUNTIME_log_file=$ut_default_log_file
> > +   "$@"
> > +   fi
> >  }
> >  
> >  function for_each_unittest()
> > @@ -51,5 +62,10 @@ function for_each_unittest()
> > fi
> > done
> 
> ... like this:
> 
>   while [ "`jobs | wc -l`" -gt $ut_run_queues ]; do
> wait

I suppose you mean "wait -n" here? And also a "if" should suffice
here, though a "while" won't hurt as well.

>   done
>   run_task "$cmd" "$testname" "$groups" "$smp" "$kernel" "$opts" "$arch" 
> "$check" "$accel" "$timeout" &

I think this might work, however it has assumption that these $cmd
tasks are the only jobs that is running in the background.

I didn't notice the "-n" parameter for "wait", otherwise I won't
bother using SIGUSR1 at all. :)

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH qemu] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64

2017-01-02 Thread David Gibson
On Thu, Dec 22, 2016 at 12:13:12PM +1100, Alexey Kardashevskiy wrote:
> KVM_CAP_SPAPR_TCE capability allows creating TCE tables in KVM which
> allows having in-kernel acceleration for H_PUT_TCE_xxx hypercalls.
> However it only supports 32bit DMA windows at zero bus offset.
> 
> There is a new KVM_CAP_SPAPR_TCE_64 capability which supports 64bit
> window size, variable page size and bus offset.
> 
> This makes use of the new capability. The kernel headers are already
> updated as the kernel support went in to v4.6.
> 
> Signed-off-by: Alexey Kardashevskiy 
> ---
>  target-ppc/kvm_ppc.h | 12 +++-
>  hw/ppc/spapr_iommu.c |  8 +---
>  target-ppc/kvm.c | 48 +---
>  3 files changed, 49 insertions(+), 19 deletions(-)
> 
> diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
> index bd1d78bfbe..14320c2378 100644
> --- a/target-ppc/kvm_ppc.h
> +++ b/target-ppc/kvm_ppc.h
> @@ -36,8 +36,9 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
>  #ifndef CONFIG_USER_ONLY
>  off_t kvmppc_alloc_rma(void **rma);
>  bool kvmppc_spapr_use_multitce(void);
> -void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
> -  bool need_vfio);
> +void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
> +  uint64_t bus_offset, uint32_t nb_table,
> +  int *pfd, bool need_vfio);
>  int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
>  int kvmppc_reset_htab(int shift_hint);
>  uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
> @@ -168,9 +169,10 @@ static inline bool kvmppc_spapr_use_multitce(void)
>  return false;
>  }
>  
> -static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
> -uint32_t window_size, int *fd,
> -bool need_vfio)
> +static inline void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t 
> page_shift,
> +uint64_t bus_offset,
> +uint32_t nb_table,
> +int *pfd, bool need_vfio)
>  {
>  return NULL;
>  }
> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
> index ae30bbe30f..29c80bb3c8 100644
> --- a/hw/ppc/spapr_iommu.c
> +++ b/hw/ppc/spapr_iommu.c
> @@ -79,15 +79,16 @@ static IOMMUAccessFlags 
> spapr_tce_iommu_access_flags(uint64_t tce)
>  
>  static uint64_t *spapr_tce_alloc_table(uint32_t liobn,
> uint32_t page_shift,
> +   uint64_t bus_offset,
> uint32_t nb_table,
> int *fd,
> bool need_vfio)
>  {
>  uint64_t *table = NULL;
> -uint64_t window_size = (uint64_t)nb_table << page_shift;
>  
> -if (kvm_enabled() && !(window_size >> 32)) {
> -table = kvmppc_create_spapr_tce(liobn, window_size, fd, need_vfio);
> +if (kvm_enabled()) {

This is broken.  Previously, if we had a >4GiB window, we'd fall back
to managing it in userspace, which would work, albeit slowly.  Now, if
you have an older kernel which doesn't support KVM_CAP_SPAPR_TCE_64 it
will attempt to allocate it in the kernel, and fail completely.

> +table = kvmppc_create_spapr_tce(liobn, page_shift, bus_offset, 
> nb_table,
> +fd, need_vfio);
>  }
>  
>  if (!table) {
> @@ -342,6 +343,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
>  tcet->nb_table = nb_table;
>  tcet->table = spapr_tce_alloc_table(tcet->liobn,
>  tcet->page_shift,
> +tcet->bus_offset,
>  tcet->nb_table,
>  >fd,
>  tcet->need_vfio);
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 9c4834c4fc..6e91a4d8bb 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -71,6 +71,7 @@ static int cap_booke_sregs;
>  static int cap_ppc_smt;
>  static int cap_ppc_rma;
>  static int cap_spapr_tce;
> +static int cap_spapr_tce_64;
>  static int cap_spapr_multitce;
>  static int cap_spapr_vfio;
>  static int cap_hior;
> @@ -123,6 +124,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
>  cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
>  cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
>  cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
> +cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
>  cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
>  cap_spapr_vfio = false;
>  cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
> @@ -2201,13 +2203,10 @@ bool 

[Qemu-devel] [PATCH 3/6] crypto: implement nettle-backed AEAD algorithms

2017-01-02 Thread Longpeng(Mike)
This patch add nettle-backed AEAD algorithms

Signed-off-by: Longpeng(Mike) 
---
 crypto/aead-nettle.c | 174 ---
 1 file changed, 167 insertions(+), 7 deletions(-)

diff --git a/crypto/aead-nettle.c b/crypto/aead-nettle.c
index cfb9d33..7a2296d 100644
--- a/crypto/aead-nettle.c
+++ b/crypto/aead-nettle.c
@@ -19,17 +19,124 @@
 #include 
 #include 
 
+typedef void (*qcrypto_nettle_aead_setkey)(void *ctx,
+  const uint8_t *key);
+
+typedef void (*qcrypto_nettle_aead_setiv)(void *ctx,
+  size_t length, const uint8_t *iv);
+
+typedef void (*qcrypto_nettle_aead_setnonce)(void *ctx,
+  size_t length, const uint8_t *nonce,
+  size_t authlen, size_t msglen, size_t taglen);
+
+typedef void (*qcrypto_nettle_aead_update)(void *ctx,
+  size_t length, const uint8_t *data);
+
+typedef void (*qcrypto_nettle_aead_encrypt)(void *ctx,
+  size_t length, uint8_t *dst, const uint8_t *src);
+
+typedef void (*qcrypto_nettle_aead_decrypt)(void *ctx,
+  size_t length, uint8_t *dst, const uint8_t *src);
+
+typedef void (*qcrypto_nettle_aead_digest)(void *ctx,
+  size_t length, uint8_t *digest);
+
+#define NETTLE_AEAD_SET_CCM_FN(alg) { \
+.setkey = (qcrypto_nettle_aead_setkey)ccm_##alg##_set_key, \
+.u_op.setnonce = (qcrypto_nettle_aead_setnonce)ccm_##alg##_set_nonce, \
+.update = (qcrypto_nettle_aead_update)ccm_##alg##_update, \
+.encrypt = (qcrypto_nettle_aead_encrypt)ccm_##alg##_encrypt, \
+.decrypt = (qcrypto_nettle_aead_decrypt)ccm_##alg##_decrypt, \
+.digest = (qcrypto_nettle_aead_digest)ccm_##alg##_digest, \
+}
+
+#define NETTLE_AEAD_SET_GCM_FN(alg) { \
+.setkey = (qcrypto_nettle_aead_setkey)gcm_##alg##_set_key, \
+.u_op.setiv = (qcrypto_nettle_aead_setiv)gcm_##alg##_set_iv, \
+.update = (qcrypto_nettle_aead_update)gcm_##alg##_update, \
+.encrypt = (qcrypto_nettle_aead_encrypt)gcm_##alg##_encrypt, \
+.decrypt = (qcrypto_nettle_aead_decrypt)gcm_##alg##_decrypt, \
+.digest = (qcrypto_nettle_aead_digest)gcm_##alg##_digest, \
+}
+
+static struct qcrypto_nettle_aead_alg {
+qcrypto_nettle_aead_setkey setkey;
+union {
+qcrypto_nettle_aead_setnonce setnonce;
+qcrypto_nettle_aead_setiv setiv;
+} u_op;
+qcrypto_nettle_aead_update update;
+qcrypto_nettle_aead_encrypt encrypt;
+qcrypto_nettle_aead_decrypt decrypt;
+qcrypto_nettle_aead_digest digest;
+} qcrypto_aead_alg_map[][QCRYPTO_AEAD_ALG__MAX] = {
+{
+[QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_CCM_FN(aes128),
+[QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_CCM_FN(aes192),
+[QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_CCM_FN(aes256),
+},
+{
+[QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_GCM_FN(aes128),
+[QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_GCM_FN(aes192),
+[QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_GCM_FN(aes256),
+}
+};
+
+typedef struct QCryptoAeadNettle QCryptoAeadNettle;
+struct QCryptoAeadNettle {
+union qcrypto_nettle_aead_ctx {
+struct ccm_aes128_ctx c_aes128_ctx;
+struct ccm_aes192_ctx c_aes192_ctx;
+struct ccm_aes256_ctx c_aes256_ctx;
+struct gcm_aes128_ctx g_aes128_ctx;
+struct gcm_aes192_ctx g_aes192_ctx;
+struct gcm_aes256_ctx g_aes256_ctx;
+} u;
+};
+
 QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
   QCryptoCipherMode mode,
   const uint8_t *key, size_t nkey,
   Error **errp)
 {
-return NULL;
+QCryptoAead *aead;
+QCryptoAeadNettle *ctx;
+
+if (!qcrypto_aead_supports(alg, mode)) {
+return NULL;
+}
+
+if (nkey != qcrypto_aead_get_key_len(alg)) {
+error_setg(errp, "Cipher key length %zu is invalid",
+   nkey);
+return NULL;
+}
+
+aead = g_new0(QCryptoAead, 1);
+aead->alg = alg;
+aead->mode = mode;
+
+ctx = g_new0(QCryptoAeadNettle, 1);
+
+qcrypto_aead_alg_map[mode][alg].setkey(>u, key);
+
+aead->opaque = ctx;
+
+return aead;
 }
 
 void qcrypto_aead_free(QCryptoAead *aead)
 {
-return;
+QCryptoAeadNettle *ctx;
+
+if (!aead) {
+return;
+}
+
+ctx = aead->opaque;
+
+g_free(ctx);
+g_free(aead);
 }
 
 int qcrypto_aead_set_nonce(QCryptoAead *aead,
@@ -38,14 +145,43 @@ int qcrypto_aead_set_nonce(QCryptoAead *aead,
size_t tag_len,
Error **errp)
 {
-return -1;
+QCryptoAeadNettle *ctx;
+struct qcrypto_nettle_aead_alg *aead_ops;
+
+ctx = (QCryptoAeadNettle *)aead->opaque;
+
+switch (aead->mode) {
+case QCRYPTO_CIPHER_MODE_CCM:
+aead_ops = _aead_alg_map[aead->mode][aead->alg];
+aead_ops->u_op.setnonce(>u, nonce_len, nonce, aad_len,
+  in_len, tag_len);
+   

[Qemu-devel] [PATCH 1/6] configure: add CONFIG_GCRYPT/NETTLE_AEAD item

2017-01-02 Thread Longpeng(Mike)
This item will be used for gcrypt/nettle backed AEAD algorithms.

It's hardly to decide which version of gcrypt/nettle started
supporting AEAD algorithms, but it's easily for us to making
a test in configure to know whether current gcrypt/nettle
support AEAD.

Signed-off-by: Longpeng(Mike) 
---
 configure | 36 
 1 file changed, 36 insertions(+)

diff --git a/configure b/configure
index 218df87..14f558c 100755
--- a/configure
+++ b/configure
@@ -309,8 +309,10 @@ tls_priority="NORMAL"
 gnutls=""
 gnutls_rnd=""
 nettle=""
+nettle_aead="no"
 nettle_kdf="no"
 gcrypt=""
+gcrypt_aead="no"
 gcrypt_hmac="no"
 gcrypt_kdf="no"
 vte=""
@@ -2429,6 +2431,19 @@ EOF
 if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
 gcrypt_hmac=yes
 fi
+
+cat > $TMPC << EOF
+#include 
+int main(void) {
+  gcry_cipher_hd_t handle;
+  gcry_cipher_open(, 0, 0, 0);
+  gcry_cipher_authenticate(handle, NULL, 0);
+  return 0;
+}
+EOF
+if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
+gcrypt_aead=yes
+fi
 else
 if test "$gcrypt" = "yes"; then
 feature_not_found "gcrypt" "Install gcrypt devel"
@@ -2460,6 +2475,21 @@ EOF
 if compile_prog "$nettle_cflags" "$nettle_libs" ; then
 nettle_kdf=yes
 fi
+
+cat > $TMPC << EOF
+#include 
+#include 
+#include 
+#include 
+int main(void) {
+ ccm_aes128_encrypt(NULL, 0, NULL, NULL);
+ gcm_aes128_encrypt(NULL, 0, NULL, NULL);
+ return 0;
+}
+EOF
+if compile_prog "$nettle_cflags" "$nettle_libs" ; then
+nettle_aead=yes
+fi
 else
 if test "$nettle" = "yes"; then
 feature_not_found "nettle" "Install nettle devel"
@@ -5399,6 +5429,9 @@ if test "$gnutls_rnd" = "yes" ; then
 fi
 if test "$gcrypt" = "yes" ; then
   echo "CONFIG_GCRYPT=y" >> $config_host_mak
+  if test "$gcrypt_aead" = "yes" ; then
+echo "CONFIG_GCRYPT_AEAD=y" >> $config_host_mak
+  fi
   if test "$gcrypt_hmac" = "yes" ; then
 echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak
   fi
@@ -5409,6 +5442,9 @@ fi
 if test "$nettle" = "yes" ; then
   echo "CONFIG_NETTLE=y" >> $config_host_mak
   echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
+  if test "$nettle_aead" = "yes" ; then
+echo "CONFIG_NETTLE_AEAD=y" >> $config_host_mak
+  fi
   if test "$nettle_kdf" = "yes" ; then
 echo "CONFIG_NETTLE_KDF=y" >> $config_host_mak
   fi
-- 
2.9.3





[Qemu-devel] [PATCH 6/6] crypto: add AEAD algorithms testcases

2017-01-02 Thread Longpeng(Mike)
This patch add some AEAD algorithms testcases

Signed-off-by: Longpeng(Mike) 
---
 tests/Makefile.include   |   2 +
 tests/test-crypto-aead.c | 357 +++
 2 files changed, 359 insertions(+)
 create mode 100644 tests/test-crypto-aead.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 4841d58..686ba30 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -93,6 +93,7 @@ gcov-files-test-write-threshold-y = block/write-threshold.c
 check-unit-y += tests/test-crypto-hash$(EXESUF)
 check-unit-y += tests/test-crypto-hmac$(EXESUF)
 check-unit-y += tests/test-crypto-cipher$(EXESUF)
+check-unit-y += tests/test-crypto-aead$(EXESUF)
 check-unit-y += tests/test-crypto-secret$(EXESUF)
 check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
 check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
@@ -574,6 +575,7 @@ tests/test-bitops$(EXESUF): tests/test-bitops.o 
$(test-util-obj-y)
 tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
 tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
 tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o 
$(test-crypto-obj-y)
+tests/test-crypto-aead$(EXESUF): tests/test-crypto-aead.o $(test-crypto-obj-y)
 tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o 
$(test-crypto-obj-y)
 tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
 
diff --git a/tests/test-crypto-aead.c b/tests/test-crypto-aead.c
new file mode 100644
index 000..c757be3
--- /dev/null
+++ b/tests/test-crypto-aead.c
@@ -0,0 +1,357 @@
+/*
+ * QEMU Crypto aead algorithms testcase
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *Longpeng(Mike) 
+ *
+ * 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.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/init.h"
+#include "crypto/aead.h"
+#include "qapi/error.h"
+
+typedef struct QCryptoAeadTestData QCryptoAeadTestData;
+struct QCryptoAeadTestData {
+const char *path;
+QCryptoCipherAlgorithm alg;
+QCryptoCipherMode mode;
+const char *hex_key;
+const char *hex_nonce;
+const char *hex_aad;
+const char *hex_plain;
+const char *hex_cipher;
+const char *hex_tag;
+};
+
+static QCryptoAeadTestData test_data[] = {
+{
+/* Borrowed from libgcrypt */
+.path = "/crypto/aead/gcm-aes-128",
+.alg = QCRYPTO_CIPHER_ALG_AES_128,
+.mode = QCRYPTO_CIPHER_MODE_GCM,
+.hex_key = ""
+   "",
+.hex_nonce = ""
+ "",
+.hex_aad = "",
+.hex_plain = ""
+ "",
+.hex_cipher = "0388dace60b6a392"
+  "f328c2b971b2fe78",
+.hex_tag = "ab6e47d42cec13bd"
+   "f53a67b21257bddf",
+},
+{
+/* Borrowed from libgcrypt */
+.path = "/crypto/aead/gcm-aes-192",
+.alg = QCRYPTO_CIPHER_ALG_AES_192,
+.mode = QCRYPTO_CIPHER_MODE_GCM,
+.hex_key = "feffe9928665731c"
+   "6d6a8f9467308308"
+   "feffe9928665731c",
+.hex_nonce = "9313225df88406e5"
+ "55909c5aff5269aa"
+ "6a7a9538534f7da1"
+ "e4c303d2a318a728"
+ "c3c0c95156809539"
+ "fcf0e2429a6b5254"
+ "16aedbf5a0de6a57"
+ "a637b39b",
+.hex_aad = "feedfacedeadbeef"
+   "feedfacedeadbeef"
+   "abaddad2",
+.hex_plain = "d9313225f88406e5"
+ "a55909c5aff5269a"
+ "86a7a9531534f7da"
+ "2e4c303d8a318a72"
+ "1c3c0c9595680953"
+ "2fcf0e2449a6b525"
+ "b16aedf5aa0de657"
+ "ba637b39",
+.hex_cipher = "d27e88681ce3243c"
+  "4830165a8fdcf9ff"
+  "1de9a1d8e6b447ef"
+  "6ef7b79828666e45"
+  "81e79012af34ddd9"
+  "e2f037589b292db3"
+  "e67c036745fa22e7"
+  "e9b7373b",
+.hex_tag = "dcf566ff291c25bb"
+   "b8568fc3d376a6d9",
+},
+{
+/* Borrowed from libgcrypt */
+.path = "/crypto/aead/gcm-aes-256",
+.alg = QCRYPTO_CIPHER_ALG_AES_256,
+.mode = QCRYPTO_CIPHER_MODE_GCM,
+.hex_key = "feffe9928665731c"
+   "6d6a8f9467308308"
+   "feffe9928665731c"
+   "6d6a8f9467308308",
+.hex_nonce = "9313225df88406e5"
+ "55909c5aff5269aa"
+

[Qemu-devel] [PATCH 2/6] crypto: add AEAD algorithms framework

2017-01-02 Thread Longpeng(Mike)
This patch introduce AEAD algorithms framework.

We currently plan to support six basic AEAD algorithms,
ccm(aes128/192/256) and gcm(aes128/192/256), so we need
to add ccm/gcm mode in qapi/crypto.json simultaneously.

Signed-off-by: Longpeng(Mike) 
---
 crypto/Makefile.objs |   3 +
 crypto/aead-gcrypt.c |  70 
 crypto/aead-nettle.c |  72 +
 crypto/aead.c|  84 
 crypto/aead.h| 180 +++
 qapi/crypto.json |   4 +-
 6 files changed, 412 insertions(+), 1 deletion(-)
 create mode 100644 crypto/aead-gcrypt.c
 create mode 100644 crypto/aead-nettle.c
 create mode 100644 crypto/aead.c
 create mode 100644 crypto/aead.h

diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 1f749f2..2c5243d 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -3,6 +3,9 @@ crypto-obj-y += hash.o
 crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o
 crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
 crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
+crypto-obj-y += aead.o
+crypto-obj-$(CONFIG_NETTLE_AEAD) += aead-nettle.o
+crypto-obj-$(if $(CONFIG_NETTLE_AEAD),n,$(CONFIG_GCRYPT_AEAD)) += aead-gcrypt.o
 crypto-obj-y += hmac.o
 crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
 crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
diff --git a/crypto/aead-gcrypt.c b/crypto/aead-gcrypt.c
new file mode 100644
index 000..9465518
--- /dev/null
+++ b/crypto/aead-gcrypt.c
@@ -0,0 +1,70 @@
+/*
+ * QEMU Crypto aead algorithms (based on libgcrypt)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *Longpeng(Mike) 
+ *
+ * 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.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/aead.h"
+#include 
+
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+  QCryptoCipherMode mode,
+  const uint8_t *key, size_t nkey,
+  Error **errp)
+{
+return NULL;
+}
+
+void qcrypto_aead_free(QCryptoAead *aead)
+{
+return;
+}
+
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+   const uint8_t *nonce, size_t nonce_len,
+   size_t aad_len, size_t in_len,
+   size_t tag_len,
+   Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+  const uint8_t *aad, size_t aad_len,
+  Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_decrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+ Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_get_tag(QCryptoAead *aead,
+ uint8_t *tag, size_t tag_len,
+ Error **errp)
+{
+return -1;
+}
diff --git a/crypto/aead-nettle.c b/crypto/aead-nettle.c
new file mode 100644
index 000..cfb9d33
--- /dev/null
+++ b/crypto/aead-nettle.c
@@ -0,0 +1,72 @@
+/*
+ * QEMU Crypto aead algorithms (based on nettle)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *Longpeng(Mike) 
+ *
+ * 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.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/aead.h"
+#include 
+#include 
+#include 
+
+QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
+  QCryptoCipherMode mode,
+  const uint8_t *key, size_t nkey,
+  Error **errp)
+{
+return NULL;
+}
+
+void qcrypto_aead_free(QCryptoAead *aead)
+{
+return;
+}
+
+int qcrypto_aead_set_nonce(QCryptoAead *aead,
+   const uint8_t *nonce, size_t nonce_len,
+   size_t aad_len, size_t in_len,
+   size_t tag_len,
+   Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_authenticate(QCryptoAead *aead,
+  const uint8_t *aad, size_t aad_len,
+  Error **errp)
+{
+return -1;
+}
+
+int qcrypto_aead_encrypt(QCryptoAead *aead,
+ const uint8_t *in, size_t in_len,
+ uint8_t *out, size_t out_len,
+

[Qemu-devel] [PATCH 0/6] add AEAD algorithms support

2017-01-02 Thread Longpeng(Mike)
Since QEMU has been supported cryptodev, so it is necessary to support
more crypto algorithms(i.e. hmac,aead) in QEMU backend.

We have already added HMAC support, and this patchset adds AEAD algos
support.

Longpeng(Mike) (6):
  configure: add CONFIG_GCRYPT/NETTLE_AEAD item
  crypto: add AEAD algorithms framework
  crypto: implement nettle-backed AEAD algorithms
  crypto: implement gcrypt-backed AEAD algorithms
  crypto: implement other common funcs for AEAD algorithms
  crypto: add AEAD algorithms testcases

 configure|  36 +
 crypto/Makefile.objs |   3 +
 crypto/aead-gcrypt.c | 231 ++
 crypto/aead-nettle.c | 232 ++
 crypto/aead.c| 124 
 crypto/aead.h| 180 
 qapi/crypto.json |   4 +-
 tests/Makefile.include   |   2 +
 tests/test-crypto-aead.c | 357 +++
 9 files changed, 1168 insertions(+), 1 deletion(-)
 create mode 100644 crypto/aead-gcrypt.c
 create mode 100644 crypto/aead-nettle.c
 create mode 100644 crypto/aead.c
 create mode 100644 crypto/aead.h
 create mode 100644 tests/test-crypto-aead.c

-- 
2.9.3





[Qemu-devel] [PATCH 4/6] crypto: implement gcrypt-backed AEAD algorithms

2017-01-02 Thread Longpeng(Mike)
This patch add gcrypt-backed AEAD algorithms support

Signed-off-by: Longpeng(Mike) 
---
 crypto/aead-gcrypt.c | 173 +--
 1 file changed, 167 insertions(+), 6 deletions(-)

diff --git a/crypto/aead-gcrypt.c b/crypto/aead-gcrypt.c
index 9465518..9892e3b 100644
--- a/crypto/aead-gcrypt.c
+++ b/crypto/aead-gcrypt.c
@@ -17,17 +17,100 @@
 #include "crypto/aead.h"
 #include 
 
+typedef struct QCryptoAeadGcrypt QCryptoAeadGcrypt;
+struct QCryptoAeadGcrypt {
+gcry_cipher_hd_t handle;
+};
+
 QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
   QCryptoCipherMode mode,
   const uint8_t *key, size_t nkey,
   Error **errp)
 {
+QCryptoAead *aead;
+QCryptoAeadGcrypt *ctx;
+gcry_error_t err;
+int gcryalg, gcrymode;
+
+switch (mode) {
+case QCRYPTO_CIPHER_MODE_CCM:
+gcrymode = GCRY_CIPHER_MODE_CCM;
+break;
+case QCRYPTO_CIPHER_MODE_GCM:
+gcrymode = GCRY_CIPHER_MODE_GCM;
+break;
+default:
+error_setg(errp, "Unsupported AEAD mode %s",
+   QCryptoCipherMode_lookup[mode]);
+return NULL;
+}
+
+if (nkey != qcrypto_aead_get_key_len(alg)) {
+error_setg(errp, "Cipher key length %zu is invalid",
+   nkey);
+return NULL;
+}
+
+switch (alg) {
+case QCRYPTO_CIPHER_ALG_AES_128:
+gcryalg = GCRY_CIPHER_AES128;
+break;
+case QCRYPTO_CIPHER_ALG_AES_192:
+gcryalg = GCRY_CIPHER_AES192;
+break;
+case QCRYPTO_CIPHER_ALG_AES_256:
+gcryalg = GCRY_CIPHER_AES256;
+break;
+default:
+error_setg(errp, "Unsupported AEAD algorithm %s",
+   QCryptoCipherAlgorithm_lookup[alg]);
+return NULL;
+}
+
+aead = g_new0(QCryptoAead, 1);
+aead->alg = alg;
+aead->mode = mode;
+
+ctx = g_new0(QCryptoAeadGcrypt, 1);
+
+err = gcry_cipher_open(>handle, gcryalg, gcrymode, 0);
+if (err) {
+error_setg(errp, "Cannot initialize aead: %s",
+   gcry_strerror(err));
+goto error;
+}
+
+err = gcry_cipher_setkey(ctx->handle, key, nkey);
+if (err) {
+error_setg(errp, "Cannot set key: %s",
+   gcry_strerror(err));
+goto error;
+}
+
+aead->opaque = ctx;
+
+return aead;
+
+error:
+gcry_cipher_close(ctx->handle);
+g_free(ctx);
+g_free(aead);
 return NULL;
 }
 
 void qcrypto_aead_free(QCryptoAead *aead)
 {
-return;
+QCryptoAeadGcrypt *ctx;
+
+if (!aead) {
+return;
+}
+
+ctx = aead->opaque;
+
+gcry_cipher_close(ctx->handle);
+g_free(ctx);
+g_free(aead);
 }
 
 int qcrypto_aead_set_nonce(QCryptoAead *aead,
@@ -36,14 +119,54 @@ int qcrypto_aead_set_nonce(QCryptoAead *aead,
size_t tag_len,
Error **errp)
 {
-return -1;
+QCryptoAeadGcrypt *ctx;
+gcry_error_t err;
+
+ctx = aead->opaque;
+
+err = gcry_cipher_setiv(ctx->handle, nonce, nonce_len);
+if (err) {
+error_setg(errp, "Cannot set iv/nonce: %s",
+   gcry_strerror(err));
+return -1;
+}
+
+if (aead->mode == QCRYPTO_CIPHER_MODE_CCM) {
+size_t ctl_para[3];
+
+ctl_para[0] = in_len;
+ctl_para[1] = aad_len;
+ctl_para[2] = tag_len;
+
+err = gcry_cipher_ctl(ctx->handle, GCRYCTL_SET_CCM_LENGTHS,
+  ctl_para, sizeof(ctl_para));
+if (err) {
+error_setg(errp, "Cannot set lengths: %s",
+   gcry_strerror(err));
+return -1;
+}
+}
+
+return 0;
 }
 
 int qcrypto_aead_authenticate(QCryptoAead *aead,
   const uint8_t *aad, size_t aad_len,
   Error **errp)
 {
-return -1;
+QCryptoAeadGcrypt *ctx;
+gcry_error_t err;
+
+ctx = aead->opaque;
+
+err = gcry_cipher_authenticate(ctx->handle, aad, aad_len);
+if (err) {
+error_setg(errp, "Cannot set associated data: %s",
+   gcry_strerror(err));
+return -1;
+}
+
+return 0;
 }
 
 int qcrypto_aead_encrypt(QCryptoAead *aead,
@@ -51,7 +174,20 @@ int qcrypto_aead_encrypt(QCryptoAead *aead,
  uint8_t *out, size_t out_len,
  Error **errp)
 {
-return -1;
+QCryptoAeadGcrypt *ctx;
+gcry_error_t err;
+
+ctx = aead->opaque;
+
+err = gcry_cipher_encrypt(ctx->handle, out, out_len,
+  in, in_len);
+if (err) {
+error_setg(errp, "Cannot encrypt data: %s",
+   gcry_strerror(err));
+return -1;
+}
+
+return 0;
 }
 
 int qcrypto_aead_decrypt(QCryptoAead *aead,
@@ -59,12 +195,37 @@ int qcrypto_aead_decrypt(QCryptoAead *aead,
  uint8_t *out, 

[Qemu-devel] [PATCH 5/6] crypto: implement other common funcs for AEAD algorithms

2017-01-02 Thread Longpeng(Mike)
If currently gcrypt/nettle doesn't support AEAD alg, then
we should implement some no-op funcs.

Signed-off-by: Longpeng(Mike) 
---
 crypto/aead.c | 44 ++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/crypto/aead.c b/crypto/aead.c
index 47639b7..effe45e 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -16,18 +16,58 @@
 #include "qapi/error.h"
 #include "crypto/aead.h"
 
+#if defined(CONFIG_NETTLE_AEAD) || defined(CONFIG_GCRYPT_AEAD)
+
+static size_t alg_key_len[QCRYPTO_AEAD_ALG__MAX] = {
+[QCRYPTO_CIPHER_ALG_AES_128] = 16,
+[QCRYPTO_CIPHER_ALG_AES_192] = 24,
+[QCRYPTO_CIPHER_ALG_AES_256] = 32,
+};
+
 bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
 {
+switch (alg) {
+case QCRYPTO_CIPHER_ALG_AES_128:
+case QCRYPTO_CIPHER_ALG_AES_192:
+case QCRYPTO_CIPHER_ALG_AES_256:
+break;
+default:
+return false;
+}
+
+switch (mode) {
+case QCRYPTO_CIPHER_MODE_CCM:
+case QCRYPTO_CIPHER_MODE_GCM:
+return true;
+default:
+break;
+}
+
 return false;
 }
 
 size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg)
 {
-return -1;
+if (alg > G_N_ELEMENTS(alg_key_len)) {
+return 0;
+}
+
+return alg_key_len[alg];
 }
 
-#if !defined(CONFIG_NETTLE_AEAD) && !defined(CONFIG_GCRYPT_AEAD)
+#else
+
+bool qcrypto_aead_supports(QCryptoCipherAlgorithm alg,
+   QCryptoCipherMode mode)
+{
+return false;
+}
+
+size_t qcrypto_aead_get_key_len(QCryptoCipherAlgorithm alg)
+{
+return -1;
+}
 
 QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg,
   QCryptoCipherMode mode,
-- 
2.9.3





Re: [Qemu-devel] [PATCH v4 2/6] target-ppc: Implement bcds. instruction

2017-01-02 Thread David Gibson
On Mon, Dec 19, 2016 at 02:47:40PM -0200, Jose Ricardo Ziviani wrote:
> bcds.: Decimal shift. Given two registers vra and vrb, this instruction
> shift the vrb value by vra bits into the result register.
> 
> Signed-off-by: Jose Ricardo Ziviani 
> ---
>  target-ppc/helper.h |  1 +
>  target-ppc/int_helper.c | 40 
> +
>  target-ppc/translate/vmx-impl.inc.c |  3 +++
>  target-ppc/translate/vmx-ops.inc.c  |  3 ++-
>  4 files changed, 46 insertions(+), 1 deletion(-)
> 
> diff --git a/target-ppc/helper.h b/target-ppc/helper.h
> index 4707db4..1a49b40 100644
> --- a/target-ppc/helper.h
> +++ b/target-ppc/helper.h
> @@ -398,6 +398,7 @@ DEF_HELPER_3(bcdcfsq, i32, avr, avr, i32)
>  DEF_HELPER_3(bcdctsq, i32, avr, avr, i32)
>  DEF_HELPER_4(bcdcpsgn, i32, avr, avr, avr, i32)
>  DEF_HELPER_3(bcdsetsgn, i32, avr, avr, i32)
> +DEF_HELPER_4(bcds, i32, avr, avr, avr, i32)
>  
>  DEF_HELPER_2(xsadddp, void, env, i32)
>  DEF_HELPER_2(xssubdp, void, env, i32)
> diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
> index 7989b1f..35e14dc 100644
> --- a/target-ppc/int_helper.c
> +++ b/target-ppc/int_helper.c
> @@ -3043,6 +3043,46 @@ uint32_t helper_bcdsetsgn(ppc_avr_t *r, ppc_avr_t *b, 
> uint32_t ps)
>  return bcd_cmp_zero(r);
>  }
>  
> +uint32_t helper_bcds(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
> +{
> +int cr;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +int i = a->s8[7];
> +#else
> +int i = a->s8[8];
> +#endif
> +bool ox_flag = false;
> +int sgnb = bcd_get_sgn(b);
> +ppc_avr_t ret = *b;
> +ret.u64[LO_IDX] &= ~0xf;
> +
> +if (bcd_is_valid(b) == false) {
> +return CRF_SO;
> +}
> +
> +if (unlikely(i > 31)) {
> +i = 31;
> +} else if (unlikely(i < -31)) {
> +i = -31;
> +}
> +
> +if (i > 0) {
> +ulshift([LO_IDX], [HI_IDX], i * 4, _flag);
> +} else {
> +urshift([LO_IDX], [HI_IDX], -i * 4);
> +}
> +bcd_put_digit(, bcd_preferred_sgn(sgnb, ps), 0);
> +
> +*r = ret;
> +
> +cr = bcd_cmp_zero(r);
> +if (unlikely(ox_flag)) {

I can imagine use cases where an overflow is not unlikely.  Best to
remove the unlikely() here and let the CPU's dynamic branch prediction
handle it.

> +cr |= CRF_SO;
> +}
> +
> +return cr;
> +}
> +
>  void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
>  {
>  int i;
> diff --git a/target-ppc/translate/vmx-impl.inc.c 
> b/target-ppc/translate/vmx-impl.inc.c
> index e8e527f..84ebb7e 100644
> --- a/target-ppc/translate/vmx-impl.inc.c
> +++ b/target-ppc/translate/vmx-impl.inc.c
> @@ -1016,6 +1016,7 @@ GEN_BCD2(bcdcfsq)
>  GEN_BCD2(bcdctsq)
>  GEN_BCD2(bcdsetsgn)
>  GEN_BCD(bcdcpsgn);
> +GEN_BCD(bcds);
>  
>  static void gen_xpnd04_1(DisasContext *ctx)
>  {
> @@ -1090,6 +1091,8 @@ GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
>  bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
>  GEN_VXFORM_DUAL(vaddshs, PPC_ALTIVEC, PPC_NONE, \
>  bcdcpsgn, PPC_NONE, PPC2_ISA300)
> +GEN_VXFORM_DUAL(vsubudm, PPC2_ALTIVEC_207, PPC_NONE, \
> +bcds, PPC_NONE, PPC2_ISA300)
>  
>  static void gen_vsbox(DisasContext *ctx)
>  {
> diff --git a/target-ppc/translate/vmx-ops.inc.c 
> b/target-ppc/translate/vmx-ops.inc.c
> index 57dce6e..7b4b009 100644
> --- a/target-ppc/translate/vmx-ops.inc.c
> +++ b/target-ppc/translate/vmx-ops.inc.c
> @@ -62,7 +62,8 @@ GEN_VXFORM_207(vaddudm, 0, 3),
>  GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
>  GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
>  GEN_VXFORM(vsubuwm, 0, 18),
> -GEN_VXFORM_207(vsubudm, 0, 19),
> +GEN_VXFORM_DUAL(vsubudm, bcds, 0, 19, PPC2_ALTIVEC_207, PPC2_ISA300),
> +GEN_VXFORM_300(bcds, 0, 27),
>  GEN_VXFORM(vmaxub, 1, 0),
>  GEN_VXFORM(vmaxuh, 1, 1),
>  GEN_VXFORM(vmaxuw, 1, 2),

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v4 1/6] target-ppc: Implement unsigned quadword left/right shift and unit tests

2017-01-02 Thread David Gibson
On Mon, Dec 19, 2016 at 02:47:39PM -0200, Jose Ricardo Ziviani wrote:
> This commit implements functions to right and left shifts and the
> unittest for them. Such functions is needed due to instructions
> that requires them.
> 
> Today, there is already a right shift implementation in int128.h
> but it's designed for signed numbers.

The subject line is misleading, since this isn't actually local to
target-ppc.  I'd want an ack from Paolo or Eric Blake before taking
this change to host-utils through my tree.

> 
> Signed-off-by: Jose Ricardo Ziviani 
> ---
>  include/qemu/host-utils.h |  3 ++
>  tests/Makefile.include|  5 ++-
>  tests/test-shift128.c | 98 
> +++
>  util/Makefile.objs|  2 +-
>  util/host-utils.c | 44 +
>  5 files changed, 150 insertions(+), 2 deletions(-)
>  create mode 100644 tests/test-shift128.c
> 
> diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
> index 46187bb..e87de19 100644
> --- a/include/qemu/host-utils.h
> +++ b/include/qemu/host-utils.h
> @@ -516,4 +516,7 @@ static inline uint64_t pow2ceil(uint64_t value)
>  return 1ULL << (64 - nlz);
>  }
>  
> +void urshift(uint64_t *plow, uint64_t *phigh, uint32_t shift);
> +void ulshift(uint64_t *plow, uint64_t *phigh, uint32_t shift, bool 
> *overflow);
> +
>  #endif
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index b574964..8ccaa3e 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -65,6 +65,8 @@ check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
>  endif
>  check-unit-y += tests/test-cutils$(EXESUF)
>  gcov-files-test-cutils-y += util/cutils.c
> +check-unit-y += tests/test-shift128$(EXESUF)
> +gcov-files-test-shift128-y = util/host-utils.c
>  check-unit-y += tests/test-mul64$(EXESUF)
>  gcov-files-test-mul64-y = util/host-utils.c
>  check-unit-y += tests/test-int128$(EXESUF)
> @@ -464,7 +466,7 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o 
> tests/check-qdict.o \
>   tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
>   tests/test-opts-visitor.o tests/test-qmp-event.o \
>   tests/rcutorture.o tests/test-rcu-list.o \
> - tests/test-qdist.o \
> + tests/test-qdist.o tests/test-shift128.o \
>   tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
>   tests/atomic_add-bench.o
>  
> @@ -572,6 +574,7 @@ tests/test-qmp-commands$(EXESUF): 
> tests/test-qmp-commands.o tests/test-qmp-marsh
>  tests/test-visitor-serialization$(EXESUF): 
> tests/test-visitor-serialization.o $(test-qapi-obj-y)
>  tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o 
> $(test-qapi-obj-y)
>  
> +tests/test-shift128$(EXESUF): tests/test-shift128.o $(test-util-obj-y)
>  tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
>  tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
>  tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o 
> $(test-crypto-obj-y)
> diff --git a/tests/test-shift128.c b/tests/test-shift128.c
> new file mode 100644
> index 000..52be6a2
> --- /dev/null
> +++ b/tests/test-shift128.c
> @@ -0,0 +1,98 @@
> +/*
> + * Test unsigned left and right shift
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/host-utils.h"
> +
> +typedef struct {
> +uint64_t low;
> +uint64_t high;
> +uint64_t rlow;
> +uint64_t rhigh;
> +int32_t shift;
> +bool overflow;
> +} test_data;
> +
> +static const test_data test_ltable[] = {
> +{ 1223ULL, 0, 1223ULL,   0, 0, false },
> +{ 1ULL,0, 2ULL,   0, 1, false }
> +{ 1ULL,0, 4ULL,   0, 2, false },
> +{ 1ULL,0, 16ULL,  0, 4, false },
> +{ 1ULL,0, 256ULL, 0, 8, false },
> +{ 1ULL,0, 65536ULL, 0, 16, false },
> +{ 1ULL,0, 2147483648ULL, 0, 31, false },
> +{ 1ULL,0, 35184372088832ULL, 0, 45, false },
> +{ 1ULL,0, 1152921504606846976ULL, 0, 60, false },

These test cases would be much easier to follow in hex
,
> +{ 1ULL,0, 0, 1ULL, 64, false },
> +{ 1ULL,0, 0, 65536ULL, 80, false },
> +{ 1ULL,0, 0, 9223372036854775808ULL, 127, false },
> +{ 0ULL,1, 0, 0, 64, true },
> +{ 0xULL, 0xULL,
> +0x8000ULL, 0x9888ULL, 60, true },
> +{ 0xULL, 0xULL,
> +0, 0xULL, 64, true },
> +{ 0x8ULL, 0, 0, 0x8ULL, 64, false },
> +{ 0x8ULL, 0, 0, 0x8000ULL, 124, false },
> +{ 0x1ULL, 0, 0, 0x4000ULL, 126, false },
> +{ 0x1ULL, 0, 0, 0x8000ULL, 127, false },
> +{ 0x1ULL, 0, 0x1ULL, 0, 128, true },
> +{ 0, 0, 0ULL, 0, 200, false },
> +};
> +
> +static const test_data test_rtable[] = {
> +{ 1223ULL, 0, 1223ULL,   0, 

Re: [Qemu-devel] [PATCH 0/4] QOM'ify work for ppc

2017-01-02 Thread David Gibson
On Sat, Dec 31, 2016 at 09:18:27AM +0800, xiaoqiang zhao wrote:
> This is some QOM'ify work relate with ppc.
> See each commit message for details.
> 
> xiaoqiang zhao (4):
>   hw/gpio: QOM'ify mpc8xxx.c
>   hw/ppc: QOM'ify e500.c
>   hw/ppc: QOM'ify ppce500_spin.c
>   hw/ppc: QOM'ify spapr_vio.c
> 
>  hw/gpio/mpc8xxx.c | 20 +++-
>  hw/ppc/e500.c | 17 -
>  hw/ppc/ppce500_spin.c | 18 --
>  hw/ppc/spapr_vio.c|  2 --
>  4 files changed, 23 insertions(+), 34 deletions(-)

Patches 1-3 all have the same problem - they move memory region
initialization and similar to an instance_init function.  This is not
how things are generally done in the qdev model.  Instead that phase
of initialization should be done from a dc->realize() function.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH qemu 2/2] spapr_pci: Advertise 16M IOMMU pages when available

2017-01-02 Thread David Gibson
On Thu, Dec 22, 2016 at 04:22:12PM +1100, Alexey Kardashevskiy wrote:
> On sPAPR, IOMMU page size varies and if QEMU is running with RAM
> backed with hugepages, we can advertise this to the guest so does
> this patch.
> 
> Signed-off-by: Alexey Kardashevskiy 
> ---
>  hw/ppc/spapr_pci.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index fd6fc1d953..09244056fc 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1505,6 +1505,9 @@ static void spapr_phb_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  /* DMA setup */
> +/* This allows huge pages for IOMMU when guest is backed with huge pages 
> */
> +sphb->page_size_mask |= qemu_getrampagesize();

This doesn't look right - you're unconditionally enabling the host ram
page size, regardless of anything else.  Instead the backing page size
should be used to filter out those sizes which are possible from the
list of those supported by the guest hardware.  This patch will give
particularly odd results if you ran it on x86 with hugepages for
example: it would advertise a 2M IOMMU page size, which could never
exist on native POWER.

Except... come to think of it, why is the backing RAM page size
relevant at all?  Or rather.. I think VFIO should be able to cope with
any guest IOMMU page size which is larger than the host ram page size
(although if it's much larger it could get expensive in the host
tables).  This case would already be routine for ppc64 on x86, where
the guest IOMMU page size is 64kiB, but the host page size is 4 kiB.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 1/6] pci: add pci_vga_type(), giving the device name of the chosen VGA device

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:11PM +0100, Hervé Poussineau wrote:
> This is in fact a split of pci_vga_init() function in two parts.
> 
> Signed-off-by: Hervé Poussineau 

Reviewed-by: David Gibson 

I think it needs Michael or someone to merge it though.

> ---
>  hw/pci/pci.c | 22 --
>  include/hw/pci/pci.h |  1 +
>  2 files changed, 17 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 24fae16..0d5a862 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -1816,19 +1816,19 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus 
> *rootbus,
>  return pci_dev;
>  }
>  
> -PCIDevice *pci_vga_init(PCIBus *bus)
> +const char *pci_vga_type(void)
>  {
>  switch (vga_interface_type) {
>  case VGA_CIRRUS:
> -return pci_create_simple(bus, -1, "cirrus-vga");
> +return "cirrus-vga";
>  case VGA_QXL:
> -return pci_create_simple(bus, -1, "qxl-vga");
> +return "qxl-vga";
>  case VGA_STD:
> -return pci_create_simple(bus, -1, "VGA");
> +return "VGA";
>  case VGA_VMWARE:
> -return pci_create_simple(bus, -1, "vmware-svga");
> +return "vmware-svga";
>  case VGA_VIRTIO:
> -return pci_create_simple(bus, -1, "virtio-vga");
> +return "virtio-vga";
>  case VGA_NONE:
>  default: /* Other non-PCI types. Checking for unsupported types is 
> already
>  done in vl.c. */
> @@ -1836,6 +1836,16 @@ PCIDevice *pci_vga_init(PCIBus *bus)
>  }
>  }
>  
> +PCIDevice *pci_vga_init(PCIBus *bus)
> +{
> +const char *vga_type = pci_vga_type();
> +if (vga_type) {
> +return pci_create_simple(bus, -1, vga_type);
> +} else {
> +return NULL;
> +}
> +}
> +
>  /* Whether a given bus number is in range of the secondary
>   * bus of the given bridge device. */
>  static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 772692f..aa8d014 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -420,6 +420,7 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus 
> *rootbus,
> const char *default_model,
> const char *default_devaddr);
>  
> +const char *pci_vga_type(void);
>  PCIDevice *pci_vga_init(PCIBus *bus);
>  
>  int pci_bus_num(PCIBus *s);

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 2/6] vga: increase priority of 0xa0000 memory region

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:12PM +0100, Hervé Poussineau wrote:
> VGA device registers vram as BAR 0. If this BAR is activated as a very low 
> address which
> crosses 0xa-0xb, low memory region is not accessible anymore.
> 
> This fixes display on PReP machine if we enable PCI mapping at
> address 0.

This commit message needs more information.  What exactly is the VGA
BAR colliding with?  Why does the other thing have higher priority?
Why is it safe for the VGA BAR to override the other thing?  Why is
this safe on all platforms?

> Signed-off-by: Hervé Poussineau 
> ---
>  hw/display/vga.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index 2a88b3c..c573f35 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -2265,7 +2265,7 @@ void vga_init(VGACommonState *s, Object *obj, 
> MemoryRegion *address_space,
>  memory_region_add_subregion_overlap(address_space,
>  0x000a,
>  vga_io_memory,
> -1);
> +2);
>  memory_region_set_coalescing(vga_io_memory);
>  if (init_vga_ports) {
>  portio_list_init(>vga_port_list, obj, vga_ports, s, "vga");

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 4/6] prep: QOM'ify System I/O

2017-01-02 Thread David Gibson
On Thu, Dec 29, 2016 at 11:12:14PM +0100, Hervé Poussineau wrote:
> Part of the functionality is copied from hw/ppc/prep.c.
> Also add support for board identification/equipment registers.

Needs more detail in the commit message.  What is system I/O?  what is
it for?

The 1-line summary is also misleading; "QOM'ify" suggests you are
changing an existing device to use QOM conventions, but no existing
device is removed here.  Is this actually something new, or is it a
duplicate QOMified version of something else?  If so, what?
> 
> Signed-off-by: Hervé Poussineau 
> ---
>  hw/ppc/Makefile.objs   |   1 +
>  hw/ppc/prep_systemio.c | 302 
> +
>  hw/ppc/trace-events|   4 +
>  3 files changed, 307 insertions(+)
>  create mode 100644 hw/ppc/prep_systemio.c
> 
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index 8025129..db72297 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -16,6 +16,7 @@ obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o 
> ppc440_bamboo.o
>  obj-y += ppc4xx_pci.o
>  # PReP
>  obj-$(CONFIG_PREP) += prep.o
> +obj-$(CONFIG_PREP) += prep_systemio.o
>  # OldWorld PowerMac
>  obj-$(CONFIG_MAC) += mac_oldworld.o
>  # NewWorld PowerMac
> diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c
> new file mode 100644
> index 000..449056c
> --- /dev/null
> +++ b/hw/ppc/prep_systemio.c
> @@ -0,0 +1,302 @@
> +/*
> + * QEMU PReP System I/O emulation
> + *
> + * Copyright (c) 2016 Herve Poussineau
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/isa/isa.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/error-report.h" /* for error_report() */
> +#include "sysemu/sysemu.h" /* for vm_stop() */
> +#include "cpu.h"
> +#include "trace.h"
> +
> +#define TYPE_PREP_SYSTEMIO "prep-systemio"
> +#define PREP_SYSTEMIO(obj) \
> +OBJECT_CHECK(PrepSystemIoState, (obj), TYPE_PREP_SYSTEMIO)
> +
> +/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */
> +#define PREP_BIT(n) (1 << (7 - (n)))
> +
> +typedef struct PrepSystemIoState {
> +ISADevice parent_obj;
> +MemoryRegion ppc_parity_mem;
> +
> +qemu_irq non_contiguous_io_map_irq;
> +uint8_t sreset; /* 0x0092 */
> +uint8_t equipment; /* 0x080c */
> +uint8_t system_control; /* 0x081c */
> +uint8_t iomap_type; /* 0x0850 */
> +uint8_t ibm_planar_id; /* 0x0852 */
> +qemu_irq softreset_irq;
> +PortioList portio;
> +} PrepSystemIoState;
> +
> +/* PORT 0092 -- Special Port 92 (Read/Write) */
> +
> +enum {
> +PORT0092_SOFTRESET  = PREP_BIT(7),
> +PORT0092_LE_MODE= PREP_BIT(6),
> +};
> +
> +static void prep_port0092_write(void *opaque, uint32_t addr, uint32_t val)
> +{
> +PrepSystemIoState *s = opaque;
> +
> +trace_prep_systemio_write(addr, val);
> +
> +if ((val & PORT0092_SOFTRESET) != 0) {
> +qemu_irq_raise(s->softreset_irq);
> +s->sreset = 1;
> +} else {
> +qemu_irq_lower(s->softreset_irq);
> +s->sreset = 0;
> +}
> +
> +if ((val & PORT0092_LE_MODE) != 0) {
> +/* XXX Not supported yet */
> +error_report("little-endian mode not supported");
> +vm_stop(RUN_STATE_PAUSED);
> +} else {
> +/* Nothing to do */
> +}
> +}
> +
> +static uint32_t prep_port0092_read(void *opaque, uint32_t addr)
> +{
> +PrepSystemIoState *s = opaque;
> +/* XXX LE mode unsupported */
> +trace_prep_systemio_read(addr, 0);
> +return s->sreset;
> +}
> +
> +/* PORT 0808 -- Hardfile Light Register (Write Only) */
> +
> +enum {
> +PORT0808_HARDFILE_LIGHT_ON  = PREP_BIT(7),
> +};
> +
> +static void prep_port0808_write(void *opaque, uint32_t addr, uint32_t val)
> +{
> +trace_prep_systemio_write(addr, val);
> +}
> +
> +/* PORT 0810 -- Password Protect 1 Register (Write Only) */
> 

Re: [Qemu-devel] [PATCH 4/4] hw/ppc: QOM'ify spapr_vio.c

2017-01-02 Thread David Gibson
On Sat, Dec 31, 2016 at 09:18:31AM +0800, xiaoqiang zhao wrote:
> Drop the old and empty SysBus init
> 
> Signed-off-by: xiaoqiang zhao 

This should also actually remove the empty function.

> ---
>  hw/ppc/spapr_vio.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
> index cc1e09c568..1739b73a13 100644
> --- a/hw/ppc/spapr_vio.c
> +++ b/hw/ppc/spapr_vio.c
> @@ -548,11 +548,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev)
>  
>  static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
>  {
> -SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
>  dc->fw_name = "vdevice";
> -k->init = spapr_vio_bridge_init;
>  }
>  
>  static const TypeInfo spapr_vio_bridge_info = {

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH qemu 1/2] exec, kvm, target-ppc: Move getrampagesize() to common code

2017-01-02 Thread David Gibson
On Thu, Dec 22, 2016 at 04:22:11PM +1100, Alexey Kardashevskiy wrote:
> getrampagesize() returns the largest supported page size and mainly
> used to know if huge pages are enabled.
> 
> However is implemented in target-ppc/kvm.c and not available
> in TCG or other architectures.
> 
> This renames and moves gethugepagesize() to mmap-alloc.c where
> fd-based analog of it is already implemented. This renames and moves
> getrampagesize() to exec.c as it seems to be the common place for
> helpers like this.
> 
> This first user for it is going to be a spapr-pci-host-bridge which
> needs to know the largest RAM page size so the guest could try
> using bigger IOMMU pages to save memory.
> 
> Signed-off-by: Alexey Kardashevskiy 

Reviewed-by: David Gibson 

Seems sensible to me, but I'm not comfortable merging this via my tree
since it touches such core code.  Probably should go via Paolo.

> ---
>  include/exec/ram_addr.h   |   1 +
>  include/qemu/mmap-alloc.h |   2 +
>  exec.c|  82 
>  target-ppc/kvm.c  | 105 
> ++
>  util/mmap-alloc.c |  25 +++
>  5 files changed, 113 insertions(+), 102 deletions(-)
> 
> diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
> index 54d7108a9e..3935cbcfcd 100644
> --- a/include/exec/ram_addr.h
> +++ b/include/exec/ram_addr.h
> @@ -91,6 +91,7 @@ typedef struct RAMList {
>  } RAMList;
>  extern RAMList ram_list;
>  
> +long qemu_getrampagesize(void);
>  ram_addr_t last_ram_offset(void);
>  void qemu_mutex_lock_ramlist(void);
>  void qemu_mutex_unlock_ramlist(void);
> diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
> index 933c024ac5..50385e3f81 100644
> --- a/include/qemu/mmap-alloc.h
> +++ b/include/qemu/mmap-alloc.h
> @@ -5,6 +5,8 @@
>  
>  size_t qemu_fd_getpagesize(int fd);
>  
> +size_t qemu_mempath_getpagesize(const char *mem_path);
> +
>  void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared);
>  
>  void qemu_ram_munmap(void *ptr, size_t size);
> diff --git a/exec.c b/exec.c
> index 08c558eecf..d73b477a70 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -32,6 +32,7 @@
>  #endif
>  #include "sysemu/kvm.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/numa.h"
>  #include "qemu/timer.h"
>  #include "qemu/config-file.h"
>  #include "qemu/error-report.h"
> @@ -1218,6 +1219,87 @@ void qemu_mutex_unlock_ramlist(void)
>  }
>  
>  #ifdef __linux__
> +/*
> + * FIXME TOCTTOU: this iterates over memory backends' mem-path, which
> + * may or may not name the same files / on the same filesystem now as
> + * when we actually open and map them.  Iterate over the file
> + * descriptors instead, and use qemu_fd_getpagesize().
> + */
> +static int find_max_supported_pagesize(Object *obj, void *opaque)
> +{
> +char *mem_path;
> +long *hpsize_min = opaque;
> +
> +if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
> +mem_path = object_property_get_str(obj, "mem-path", NULL);
> +if (mem_path) {
> +long hpsize = qemu_mempath_getpagesize(mem_path);
> +if (hpsize < *hpsize_min) {
> +*hpsize_min = hpsize;
> +}
> +} else {
> +*hpsize_min = getpagesize();
> +}
> +}
> +
> +return 0;
> +}
> +
> +long qemu_getrampagesize(void)
> +{
> +long hpsize = LONG_MAX;
> +long mainrampagesize;
> +Object *memdev_root;
> +
> +if (mem_path) {
> +mainrampagesize = qemu_mempath_getpagesize(mem_path);
> +} else {
> +mainrampagesize = getpagesize();
> +}
> +
> +/* it's possible we have memory-backend objects with
> + * hugepage-backed RAM. these may get mapped into system
> + * address space via -numa parameters or memory hotplug
> + * hooks. we want to take these into account, but we
> + * also want to make sure these supported hugepage
> + * sizes are applicable across the entire range of memory
> + * we may boot from, so we take the min across all
> + * backends, and assume normal pages in cases where a
> + * backend isn't backed by hugepages.
> + */
> +memdev_root = object_resolve_path("/objects", NULL);
> +if (memdev_root) {
> +object_child_foreach(memdev_root, find_max_supported_pagesize, 
> );
> +}
> +if (hpsize == LONG_MAX) {
> +/* No additional memory regions found ==> Report main RAM page size 
> */
> +return mainrampagesize;
> +}
> +
> +/* If NUMA is disabled or the NUMA nodes are not backed with a
> + * memory-backend, then there is at least one node using "normal" RAM,
> + * so if its page size is smaller we have got to report that size 
> instead.
> + */
> +if (hpsize > mainrampagesize &&
> +(nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
> +static bool warned;
> +if (!warned) {
> +

[Qemu-devel] [Bug 925405] Re: VNC server does not work with Mac Screen Sharing

2017-01-02 Thread mmu_man
There is no need to change the protocol version itself to use new 
encoding, there are provisions for that in the existing one.

IIRC the problem was also that each party was waiting for the other one 
to send data after the protocol version exchange, but that was 5y ago.

Yes it should be possible to work around this, but I don't have a Mac
now.

François.

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

Title:
  VNC server does not work with Mac Screen Sharing

Status in QEMU:
  Incomplete
Status in Ubuntu:
  Invalid

Bug description:
  When connecting to a QEMU instance from a Mac using any VNC settings
  on the QEMU CLI and any target arch (ARM, Intel, etc.), the connection
  is attempted but the negotiation never finishes.

  I've verified this when building QEMU from source (1.0 and HEAD) on
  Ubuntu, Fedora and Debian or when using Ubuntu (Oneiric) and Debian
  (Lenny) packages.

  It does not matter whether I specify authentication (or anything else)
  on QEMU's side, the behavior is always the same - I see the connection
  being established using netstat and tcpdump, but QEMU does not seem to
  send back any pixmap data after the connection setup.

  Best guess as to why this happens is that the VNC negotiation on QEMU
  does not like the protocol version and VNC encoding sent by the Mac's
  built-in VNC client, or that its negotiation logic is subtly broken. I
  appreciate that it's not meant to be a full VNC server, but it
  prevents me from using it remotely until a stable Mac build is
  feasible.

  Background info:

  Mac OS X includes a VNC client called Screen Sharing that you can
  invoke in two different ways:

  * At a terminal, by typing "open vnc://hostname:tcp_port"
  * From any URI-enabled field (such as the Safari URI field), where you can 
just type the URI as vnc://hostname:tcp_port

  Please do not confuse the enhanced VNC protocol Apple Remote Desktop
  uses with Screen Sharing - they are not mutually exclusive, but they
  are not incompatible either, since what Apple does is to negotiate
  extra pixmap encoding and authentication options - I use Screen
  Sharing to access many VNC servers such as vnc4server, tightvncserver,
  vino, etc. without any issues whatsoever, so the issue I'm reporting
  is not an issue with Apple's implementation.

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



[Qemu-devel] QEMU online/offline cpu

2017-01-02 Thread Ozgur O Kilic
Hi

I am trying to understand how QEMU threads respond to set a vCPU online or 
offline. 

Specifically, what happens to QEMU thread if in the guest, we execute:

echo 0 > /sys/devices/system/cpu/cpu1/online

Is the corresponding QEMU thread paused?

Thank you
Ozgur Ozan Kilic


Re: [Qemu-devel] [PATCH] [M25P80] Make sure not to overrun the internal data buffer.

2017-01-02 Thread Jean-Christophe DUBOIS

Le 30/12/2016 à 19:09, mar.krzeminski a écrit :

Can you check spi controller model code?


I'll double check.

But why is the SPI memory/device even responding if CS is not set ?

Looking at ssi code it should not.
Flash (so the m25p80) is responding when CS line is low and it seem 
that this is default.


So I fixed the CS handling in the i.MX SPI device emulator and I don't 
experience crashes anymore. Thanks for your help.


You may still want to harden the m25p80 code to make sure it doesn't 
overrun its internal buffer.




Thanks,
Marcin





Thanks,
Marcin













[Qemu-devel] [PATCH v2] [i.MX] Remove MSGDATA register support.

2017-01-02 Thread Jean-Christophe Dubois
>From the documentation it is not clear what this SPI register is about.

Moreover, neither linux driver nor xvisor driver are using this SPI register.

For now we just remove it and issue a log on register write access.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
* Fix coding style issue.

 hw/ssi/imx_spi.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index c2d293c..3a0400e 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -338,9 +338,6 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
   TYPE_IMX_SPI, __func__);
 break;
 case ECSPI_TXDATA:
-case ECSPI_MSGDATA:
-/* Is there any difference between TXDATA and MSGDATA ? */
-/* I'll have to look in the linux driver */
 if (!imx_spi_is_enabled(s)) {
 /* Ignore writes if device is disabled */
 break;
@@ -391,6 +388,14 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 
 break;
+case ECSPI_MSGDATA:
+/* it is not clear from the spec what MSGDATA is for */
+/* Anyway it is not used by Linux driver */
+/* So for now we just ignore it */
+qemu_log_mask(LOG_GUEST_ERROR,
+  "[%s]%s: Trying to write to MSGDATA, ignoring\n",
+  TYPE_IMX_SPI, __func__);
+break;
 default:
 s->regs[index] = value;
 
-- 
2.9.3




[Qemu-devel] [PATCH v2] [i.MX] fix CS handling during SPI access.

2017-01-02 Thread Jean-Christophe Dubois
The i.MX SPI device was not de-asserting the CS line at the end of
memory access.

This triggered a SIGSEGV in Qemu when the sabrelite emulator was acessing
a SPI flash memory.

Whit this path the CS signal is correctly asserted and deasserted arround
memory access.

This was tested by:
* booting linux on Sabrelite Qemu emulator.
* booting xvisor on Sabrelite Qemu emultor.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
* Fix coding style issue.

 hw/ssi/imx_spi.c | 33 ++---
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index e4e395f..c2d293c 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -152,13 +152,20 @@ static bool imx_spi_is_multiple_master_burst(IMXSPIState 
*s)
 
 static void imx_spi_flush_txfifo(IMXSPIState *s)
 {
-uint32_t tx;
-uint32_t rx;
+uint32_t i;
 
 DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
 fifo32_num_used(>tx_fifo), fifo32_num_used(>rx_fifo));
 
+/* Activate the requested CS line */
+for (i = 0; i < 4; i++) {
+qemu_set_irq(s->cs_lines[i],
+ i == imx_spi_selected_channel(s) ? 0 : 1);
+}
+
 while (!fifo32_is_empty(>tx_fifo)) {
+uint32_t tx;
+uint32_t rx = 0;
 int tx_burst = 0;
 int index = 0;
 
@@ -178,8 +185,6 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 
 tx_burst = MIN(s->burst_length, 32);
 
-rx = 0;
-
 while (tx_burst) {
 uint8_t byte = tx & 0xff;
 
@@ -221,6 +226,13 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
 }
 
+/* Deselect all SS lines if transfert if completed */
+if (s->regs[ECSPI_STATREG] & ECSPI_STATREG_TC) {
+for (i = 0; i < 4; i++) {
+qemu_set_irq(s->cs_lines[i], 1);
+}
+}
+
 /* TODO: We should also use TDR and RDR bits */
 
 DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n",
@@ -230,6 +242,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 static void imx_spi_reset(DeviceState *dev)
 {
 IMXSPIState *s = IMX_SPI(dev);
+uint32_t i;
 
 DPRINTF("\n");
 
@@ -243,6 +256,11 @@ static void imx_spi_reset(DeviceState *dev)
 imx_spi_update_irq(s);
 
 s->burst_length = 0;
+
+/* Disable all CS lines */
+for (i = 0; i < 4; i++) {
+qemu_set_irq(s->cs_lines[i], 1);
+}
 }
 
 static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
@@ -359,15 +377,8 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 
 if (imx_spi_channel_is_master(s)) {
-int i;
-
 /* We are in master mode */
 
-for (i = 0; i < 4; i++) {
-qemu_set_irq(s->cs_lines[i],
- i == imx_spi_selected_channel(s) ? 0 : 1);
-}
-
 if ((value & change_mask & ECSPI_CONREG_SMC) &&
 !fifo32_is_empty(>tx_fifo)) {
 /* SMC bit is set and TX FIFO has some slots filled in */
-- 
2.9.3




Re: [Qemu-devel] [PATCH] [i.MX] fix CS handling during SPI access.

2017-01-02 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH] [i.MX] fix CS handling during SPI access.
Message-id: 20170102205521.4101-1-...@tribudubois.net
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20170102205521.4101-1-...@tribudubois.net -> 
patchew/20170102205521.4101-1-...@tribudubois.net
Switched to a new branch 'test'
3d25a87 fix CS handling during SPI access.

=== OUTPUT BEGIN ===
Checking PATCH 1/1: fix CS handling during SPI access
ERROR: suspect code indent for conditional statements (4, 7)
#86: FILE: hw/ssi/imx_spi.c:261:
+for (i = 0; i < 4; i++) {
+   qemu_set_irq(s->cs_lines[i], 1);

total: 1 errors, 0 warnings, 76 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

Re: [Qemu-devel] [PATCH] [i.MX] Remove MSGDATA register support.

2017-01-02 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH] [i.MX] Remove MSGDATA register support.
Message-id: 20170102205536.4151-1-...@tribudubois.net
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20170102205536.4151-1-...@tribudubois.net -> 
patchew/20170102205536.4151-1-...@tribudubois.net
Switched to a new branch 'test'
45fec27 Remove MSGDATA register support.

=== OUTPUT BEGIN ===
Checking PATCH 1/1: Remove MSGDATA register support
ERROR: code indent should never use tabs
#35: FILE: hw/ssi/imx_spi.c:382:
+^I/* Anyway it is not used by Linux driver */$

ERROR: code indent should never use tabs
#36: FILE: hw/ssi/imx_spi.c:383:
+^I/* So for now we just ignore it */$

total: 2 errors, 0 warnings, 23 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCH] [i.MX] Remove MSGDATA register support.

2017-01-02 Thread Jean-Christophe Dubois
>From the documentation it is not clear what this SPI register is about.

Moreover, neither linux driver nor xvisor driver are using this SPI register.

For now we just remove it and issue a log on register write access.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/ssi/imx_spi.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index c2d293c..3a0400e 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -338,9 +338,6 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
   TYPE_IMX_SPI, __func__);
 break;
 case ECSPI_TXDATA:
-case ECSPI_MSGDATA:
-/* Is there any difference between TXDATA and MSGDATA ? */
-/* I'll have to look in the linux driver */
 if (!imx_spi_is_enabled(s)) {
 /* Ignore writes if device is disabled */
 break;
@@ -391,6 +388,14 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 
 break;
+case ECSPI_MSGDATA:
+/* it is not clear from the spec what MSGDATA is for */
+   /* Anyway it is not used by Linux driver */
+   /* So for now we just ignore it */
+qemu_log_mask(LOG_GUEST_ERROR,
+  "[%s]%s: Trying to write to MSGDATA, ignoring\n",
+  TYPE_IMX_SPI, __func__);
+break;
 default:
 s->regs[index] = value;
 
-- 
2.9.3




[Qemu-devel] [PATCH] [i.MX] fix CS handling during SPI access.

2017-01-02 Thread Jean-Christophe Dubois
The i.MX SPI device was not de-asserting the CS line at the end of
memory access.

This triggered a SIGSEGV in Qemu when the sabrelite emulator was acessing
a SPI flash memory.

Whit this path the CS signal is correctly asserted and deasserted arround
memory access.

This was tested by:
* booting linux on Sabrelite Qemu emulator.
* booting xvisor on Sabrelite Qemu emultor.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/ssi/imx_spi.c | 33 ++---
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
index e4e395f..c2d293c 100644
--- a/hw/ssi/imx_spi.c
+++ b/hw/ssi/imx_spi.c
@@ -152,13 +152,20 @@ static bool imx_spi_is_multiple_master_burst(IMXSPIState 
*s)
 
 static void imx_spi_flush_txfifo(IMXSPIState *s)
 {
-uint32_t tx;
-uint32_t rx;
+uint32_t i;
 
 DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
 fifo32_num_used(>tx_fifo), fifo32_num_used(>rx_fifo));
 
+/* Activate the requested CS line */
+for (i = 0; i < 4; i++) {
+qemu_set_irq(s->cs_lines[i],
+ i == imx_spi_selected_channel(s) ? 0 : 1);
+}
+
 while (!fifo32_is_empty(>tx_fifo)) {
+uint32_t tx;
+uint32_t rx = 0;
 int tx_burst = 0;
 int index = 0;
 
@@ -178,8 +185,6 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 
 tx_burst = MIN(s->burst_length, 32);
 
-rx = 0;
-
 while (tx_burst) {
 uint8_t byte = tx & 0xff;
 
@@ -221,6 +226,13 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
 }
 
+/* Deselect all SS lines if transfert if completed */
+if (s->regs[ECSPI_STATREG] & ECSPI_STATREG_TC) {
+for (i = 0; i < 4; i++) {
+qemu_set_irq(s->cs_lines[i], 1);
+}
+}
+
 /* TODO: We should also use TDR and RDR bits */
 
 DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n",
@@ -230,6 +242,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
 static void imx_spi_reset(DeviceState *dev)
 {
 IMXSPIState *s = IMX_SPI(dev);
+uint32_t i;
 
 DPRINTF("\n");
 
@@ -243,6 +256,11 @@ static void imx_spi_reset(DeviceState *dev)
 imx_spi_update_irq(s);
 
 s->burst_length = 0;
+
+/* Disable all CS lines */
+for (i = 0; i < 4; i++) {
+   qemu_set_irq(s->cs_lines[i], 1);
+}
 }
 
 static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
@@ -359,15 +377,8 @@ static void imx_spi_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 
 if (imx_spi_channel_is_master(s)) {
-int i;
-
 /* We are in master mode */
 
-for (i = 0; i < 4; i++) {
-qemu_set_irq(s->cs_lines[i],
- i == imx_spi_selected_channel(s) ? 0 : 1);
-}
-
 if ((value & change_mask & ECSPI_CONREG_SMC) &&
 !fifo32_is_empty(>tx_fifo)) {
 /* SMC bit is set and TX FIFO has some slots filled in */
-- 
2.9.3




[Qemu-devel] [PATCH v2 14/16] hw/arm/virt-acpi-build: Don't incorrectly claim architectural timer to be edge-triggered

2017-01-02 Thread Andrew Jones
This is the ACPI equivalent to "hw/arm/virt: Don't incorrectly claim
architectural timer to be edge-triggered" which fixes the DT for
machine types 2.9 and later.

Signed-off-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c| 20 ++--
 include/hw/acpi/acpi-defs.h |  1 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index aa800d2a9657..b5e17a680d51 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -535,25 +535,33 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 
 /* GTDT */
 static void
-build_gtdt(GArray *table_data, BIOSLinker *linker)
+build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
+VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
 int gtdt_start = table_data->len;
 AcpiGenericTimerTable *gtdt;
+uint32_t irqflags;
+
+if (vmc->claim_edge_triggered_timers) {
+irqflags = ACPI_GTDT_INTERRUPT_MODE_EDGE;
+} else {
+irqflags = ACPI_GTDT_INTERRUPT_MODE_LEVEL;
+}
 
 gtdt = acpi_data_push(table_data, sizeof *gtdt);
 /* The interrupt values are the same with the device tree when adding 16 */
 gtdt->secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_S_EL1_IRQ + 16);
-gtdt->secure_el1_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
+gtdt->secure_el1_flags = cpu_to_le32(irqflags);
 
 gtdt->non_secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL1_IRQ + 16);
-gtdt->non_secure_el1_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE |
+gtdt->non_secure_el1_flags = cpu_to_le32(irqflags |
  ACPI_GTDT_CAP_ALWAYS_ON);
 
 gtdt->virtual_timer_interrupt = cpu_to_le32(ARCH_TIMER_VIRT_IRQ + 16);
-gtdt->virtual_timer_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
+gtdt->virtual_timer_flags = cpu_to_le32(irqflags);
 
 gtdt->non_secure_el2_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL2_IRQ + 16);
-gtdt->non_secure_el2_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
+gtdt->non_secure_el2_flags = cpu_to_le32(irqflags);
 
 build_header(linker, table_data,
  (void *)(table_data->data + gtdt_start), "GTDT",
@@ -736,7 +744,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 build_madt(tables_blob, tables->linker, vms);
 
 acpi_add_table(table_offsets, tables_blob);
-build_gtdt(tables_blob, tables->linker);
+build_gtdt(tables_blob, tables->linker, vms);
 
 acpi_add_table(table_offsets, tables_blob);
 build_mcfg(tables_blob, tables->linker, vms);
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index d15b7e5cd39a..d43ec005cbb7 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -428,6 +428,7 @@ typedef struct AcpiMadtGenericTranslator 
AcpiMadtGenericTranslator;
 /*
  * Generic Timer Description Table (GTDT)
  */
+#define ACPI_GTDT_INTERRUPT_MODE_LEVEL(0 << 0)
 #define ACPI_GTDT_INTERRUPT_MODE_EDGE (1 << 0)
 #define ACPI_GTDT_CAP_ALWAYS_ON   (1 << 2)
 
-- 
2.9.3




Re: [Qemu-devel] [kvm-unit-tests PATCH 0/2] run_tests: support concurrent test execution

2017-01-02 Thread Radim Krčmář
2017-01-02 18:07+0100, Paolo Bonzini:
> On 01/01/2017 11:34, Peter Xu wrote:
>> run_tests.sh is getting slower. Maybe it's time to let it run faster.
>> An obvious issue is that, we were running the tests sequentially in
>> the past.
>> 
>> This series provides another new "-j" parameter. "-j 8" means we run
>> the tests on 8 task queues. That'll fasten the script a lot. A very
>> quick test of mine shows 3x speed boost with 8 task queues.
>> 
>> Most of the changes are in scripts/tash.bash of patch 2, which
>> implemented the main logic for task managements. Please see commit
>> message for more information.
>> 
>> I did a quick "make standalone" test to make sure this series won't
>> break it. However I am not sure whether it'll break other thing that I
>> don't know...
> 
> Would it work if run_tests.sh wrote a Makefile for all the tests (with
> phony targets only), and then simply ran "make -f Makefile.tmp -jN"?

We would need to change for_each_unittest to print the command line
instead of running it and add a executable wrapper for run() from
scripts/runtime.bash to have something to pass those arguments to.
After that, we could generate a Makefile.

I think we can do the queue with ~3 lines of bash and the Makefile would
complicate it more.

Btw. I just leaned that xargs provides a simpler, but sufficient,
queueing functionality, e.g.

  echo "echo a\0 (sleep 1; echo b)\0 echo c\0 sleep 1\0 echo d" |
xargs -0 -L 1 -P 2 sh -c



[Qemu-devel] [PATCH v2 13/16] hw/arm/virt: remove VirtGuestInfo

2017-01-02 Thread Andrew Jones
by moving VirtGuestInfo.fw_cfg to VirtMachineState. This is the
mach-virt equivalent of "pc: Move PcGuestInfo.fw_cfg to
PCMachineState" and "pc: Eliminate PcGuestInfo struct" combined.

Signed-off-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c |  7 +++
 hw/arm/virt.c| 16 +++-
 include/hw/arm/virt.h|  6 +-
 3 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 0b9c2c0d0a3b..aa800d2a9657 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -825,11 +825,10 @@ static const VMStateDescription vmstate_virt_acpi_build = 
{
 
 void virt_acpi_setup(VirtMachineState *vms)
 {
-VirtGuestInfo *guest_info = >acpi_guest_info;
 AcpiBuildTables tables;
 AcpiBuildState *build_state;
 
-if (!guest_info->fw_cfg) {
+if (!vms->fw_cfg) {
 trace_virt_acpi_setup();
 return;
 }
@@ -854,8 +853,8 @@ void virt_acpi_setup(VirtMachineState *vms)
 acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
   "etc/table-loader", 0);
 
-fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
-tables.tcpalog->data, acpi_data_len(tables.tcpalog));
+fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
+acpi_data_len(tables.tcpalog));
 
 build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
   ACPI_BUILD_RSDP_FILE, 0);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 909d87fbff57..709da403a6fc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -913,7 +913,7 @@ static void create_flash(const VirtMachineState *vms,
 }
 }
 
-static void create_fw_cfg(const VirtMachineState *vms, AddressSpace *as)
+static FWCfgState *create_fw_cfg(const VirtMachineState *vms, AddressSpace *as)
 {
 hwaddr base = vms->memmap[VIRT_FW_CFG].base;
 hwaddr size = vms->memmap[VIRT_FW_CFG].size;
@@ -930,6 +930,7 @@ static void create_fw_cfg(const VirtMachineState *vms, 
AddressSpace *as)
 qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
  2, base, 2, size);
 g_free(nodename);
+return fw_cfg;
 }
 
 static void create_pcie_irq_map(const VirtMachineState *vms,
@@ -1157,12 +1158,11 @@ static void *machvirt_dtb(const struct arm_boot_info 
*binfo, int *fdt_size)
 
 static void virt_build_smbios(VirtMachineState *vms)
 {
-FWCfgState *fw_cfg = vms->acpi_guest_info.fw_cfg;
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
 const char *product = "QEMU Virtual Machine";
 
-if (!fw_cfg) {
+if (!vms->fw_cfg) {
 return;
 }
 
@@ -1177,9 +1177,9 @@ static void virt_build_smbios(VirtMachineState *vms)
   _anchor, _anchor_len);
 
 if (smbios_anchor) {
-fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-tables",
+fw_cfg_add_file(vms->fw_cfg, "etc/smbios/smbios-tables",
 smbios_tables, smbios_tables_len);
-fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor",
+fw_cfg_add_file(vms->fw_cfg, "etc/smbios/smbios-anchor",
 smbios_anchor, smbios_anchor_len);
 }
 }
@@ -1204,7 +1204,6 @@ static void machvirt_init(MachineState *machine)
 int n, virt_max_cpus;
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 const char *cpu_model = machine->cpu_model;
-VirtGuestInfo *guest_info = >acpi_guest_info;
 char **cpustr;
 ObjectClass *oc;
 const char *typename;
@@ -1412,10 +1411,9 @@ static void machvirt_init(MachineState *machine)
  */
 create_virtio_devices(vms, pic);
 
-create_fw_cfg(vms, _space_memory);
-rom_set_fw(fw_cfg_find());
+vms->fw_cfg = create_fw_cfg(vms, _space_memory);
+rom_set_fw(vms->fw_cfg);
 
-guest_info->fw_cfg = fw_cfg_find();
 vms->machine_done.notify = virt_machine_done;
 qemu_add_machine_init_done_notifier(>machine_done);
 
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 23f11776a557..8f67794d4e65 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -79,10 +79,6 @@ typedef struct MemMapEntry {
 hwaddr size;
 } MemMapEntry;
 
-typedef struct VirtGuestInfo {
-FWCfgState *fw_cfg;
-} VirtGuestInfo;
-
 typedef struct {
 MachineClass parent;
 bool disallow_affinity_adjustment;
@@ -93,8 +89,8 @@ typedef struct {
 
 typedef struct {
 MachineState parent;
-VirtGuestInfo acpi_guest_info;
 Notifier machine_done;
+FWCfgState *fw_cfg;
 bool secure;
 bool highmem;
 bool virt;
-- 
2.9.3




[Qemu-devel] [PATCH v2 12/16] hw/arm/virt-acpi-build: don't save VirtGuestInfo on AcpiBuildState

2017-01-02 Thread Andrew Jones
We can get to VirtMachineState without the need for saving a pointer
on AcpiBuildState. This is the mach-virt equivalent to "acpi: Don't save
PcGuestInfo on AcpiBuildState"

Signed-off-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index e34167030dd1..0b9c2c0d0a3b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -707,7 +707,6 @@ struct AcpiBuildState {
 MemoryRegion *linker_mr;
 /* Is table patched? */
 bool patched;
-VirtGuestInfo *guest_info;
 } AcpiBuildState;
 
 static
@@ -791,8 +790,7 @@ static void virt_acpi_build_update(void *build_opaque)
 
 acpi_build_tables_init();
 
-virt_acpi_build(container_of(build_state->guest_info,
- VirtMachineState, acpi_guest_info), );
+virt_acpi_build(VIRT_MACHINE(qdev_get_machine()), );
 
 acpi_ram_update(build_state->table_mr, tables.table_data);
 acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
@@ -842,7 +840,6 @@ void virt_acpi_setup(VirtMachineState *vms)
 }
 
 build_state = g_malloc0(sizeof *build_state);
-build_state->guest_info = guest_info;
 
 acpi_build_tables_init();
 virt_acpi_build(vms, );
-- 
2.9.3




[Qemu-devel] [PATCH v2 11/16] hw/arm/virt-acpi-build: remove redundant members from VirtGuestInfo

2017-01-02 Thread Andrew Jones
Now that we pass VirtMachineState, and guest-info is just part of
that state, we can remove all the redundant members and access
the VirtMachineState directly.

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c | 72 +---
 hw/arm/virt.c|  6 
 include/hw/arm/virt.h|  6 
 3 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 0c36ee83d065..e34167030dd1 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -384,7 +384,7 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned 
rsdt_tbl_offset)
 }
 
 static void
-build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_iort(GArray *table_data, BIOSLinker *linker)
 {
 int iort_start = table_data->len;
 AcpiIortIdMapping *idmap;
@@ -439,11 +439,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 }
 
 static void
-build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
 AcpiSerialPortConsoleRedirection *spcr;
-const MemMapEntry *uart_memmap = _info->memmap[VIRT_UART];
-int irq = guest_info->irqmap[VIRT_UART] + ARM_SPI_BASE;
+const MemMapEntry *uart_memmap = >memmap[VIRT_UART];
+int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
 
 spcr = acpi_data_push(table_data, sizeof(*spcr));
 
@@ -472,16 +472,16 @@ build_spcr(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 }
 
 static void
-build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
 AcpiSystemResourceAffinityTable *srat;
 AcpiSratProcessorGiccAffinity *core;
 AcpiSratMemoryAffinity *numamem;
 int i, j, srat_start;
 uint64_t mem_base;
-uint32_t *cpu_node = g_malloc0(guest_info->smp_cpus * sizeof(uint32_t));
+uint32_t *cpu_node = g_malloc0(vms->smp_cpus * sizeof(uint32_t));
 
-for (i = 0; i < guest_info->smp_cpus; i++) {
+for (i = 0; i < vms->smp_cpus; i++) {
 j = numa_get_node_for_cpu(i);
 if (j < nb_numa_nodes) {
 cpu_node[i] = j;
@@ -492,7 +492,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 srat = acpi_data_push(table_data, sizeof(*srat));
 srat->reserved1 = cpu_to_le32(1);
 
-for (i = 0; i < guest_info->smp_cpus; ++i) {
+for (i = 0; i < vms->smp_cpus; ++i) {
 core = acpi_data_push(table_data, sizeof(*core));
 core->type = ACPI_SRAT_PROCESSOR_GICC;
 core->length = sizeof(*core);
@@ -502,7 +502,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 }
 g_free(cpu_node);
 
-mem_base = guest_info->memmap[VIRT_MEM].base;
+mem_base = vms->memmap[VIRT_MEM].base;
 for (i = 0; i < nb_numa_nodes; ++i) {
 numamem = acpi_data_push(table_data, sizeof(*numamem));
 build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
@@ -515,10 +515,10 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 }
 
 static void
-build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
 AcpiTableMcfg *mcfg;
-const MemMapEntry *memmap = guest_info->memmap;
+const MemMapEntry *memmap = vms->memmap;
 int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
 
 mcfg = acpi_data_push(table_data, len);
@@ -562,11 +562,12 @@ build_gtdt(GArray *table_data, BIOSLinker *linker)
 
 /* MADT */
 static void
-build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
+VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
 int madt_start = table_data->len;
-const MemMapEntry *memmap = guest_info->memmap;
-const int *irqmap = guest_info->irqmap;
+const MemMapEntry *memmap = vms->memmap;
+const int *irqmap = vms->irqmap;
 AcpiMultipleApicTable *madt;
 AcpiMadtGenericDistributor *gicd;
 AcpiMadtGenericMsiFrame *gic_msi;
@@ -578,16 +579,16 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
 gicd->length = sizeof(*gicd);
 gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
-gicd->version = guest_info->gic_version;
+gicd->version = vms->gic_version;
 
-for (i = 0; i < guest_info->smp_cpus; i++) {
+for (i = 0; i < vms->smp_cpus; i++) {
 AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
sizeof(*gicc));
  

Re: [Qemu-devel] [kvm-unit-tests PATCH 2/2] run_tests: allow run tests in parallel

2017-01-02 Thread Radim Krčmář
2017-01-01 18:34+0800, Peter Xu:
> run_task.sh is getting slow. This patch is trying to make it faster by
> running the tests concurrently.
> 
> First of all, we provide a new parameter "-j" for the run_tests.sh,
> which can be used to specify how many run queues we want for the tests.
> When "-j" is not provided, we'll keep the old behavior.
> 
> When the tests are running concurrently, we will use seperate log file
> for each test case (currently located in logs/ dir, with name
> test.TESTNAME.log), to avoid test logs messing up with each other.
> 
> A quick test on my laptop (x86 with 4 cores and 2 threads, so 8
> processors) shows 3x improvement on overall test time:
> 
>|-+---|
>| command | time used |
>|-+---|
>| run_test.sh | 75s   |
>| run_test.sh -j8 | 27s   |
>|-+---|
> 
> Signed-off-by: Peter Xu 
> ---
> diff --git a/scripts/functions.bash b/scripts/functions.bash
> @@ -1,7 +1,18 @@
> +source scripts/global.bash
> +source scripts/task.bash
> +
>  function run_task()
>  {
> - RUNTIME_log_file=$ut_default_log_file
> - "$@"
> + local testname="$2"
> +
> + if ut_in_parallel; then
> + RUNTIME_log_file="${ut_log_dir}/test.${testname}.log"

No need for the "test." prefix.

I would do this change regardless of ut_in_parallel.  Having output of
all tests in one file just wasted time when most usecases were to find a
specific failed test.

> + # run in background
> + task_enqueue "$@"

Couldn't the queue be much simpler ...

> + else
> + RUNTIME_log_file=$ut_default_log_file
> + "$@"
> + fi
>  }
>  
>  function for_each_unittest()
> @@ -51,5 +62,10 @@ function for_each_unittest()
>   fi
>   done

... like this:

  while [ "`jobs | wc -l`" -gt $ut_run_queues ]; do
wait
  done
  run_task "$cmd" "$testname" "$groups" "$smp" "$kernel" "$opts" "$arch" 
"$check" "$accel" "$timeout" &

?

(default $ut_run_queues would be 1)

>  run_task "$cmd" "$testname" "$groups" "$smp" "$kernel" "$opts" "$arch" 
> "$check" "$accel" "$timeout"
> +
> + if ut_in_parallel; then
> + task_wait_all
> + fi
> +
>   exec {fd}<&-
>  }



[Qemu-devel] [PATCH v2 08/16] hw/arm/virt: remove include/hw/arm/virt-acpi-build.h

2017-01-02 Thread Andrew Jones
include/hw/arm/virt-acpi-build.h is only used for VirtGuestInfo,
which doesn't even necessarily have to be ACPI specific. Move
VirtGuestInfo to include/hw/arm/virt.h, allowing us to remove
include/hw/arm/virt-acpi-build.h, and to prepare for even more
code motion.

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 MAINTAINERS  |  2 --
 hw/arm/virt-acpi-build.c |  2 +-
 hw/arm/virt.c|  1 -
 include/hw/arm/virt-acpi-build.h | 39 ---
 include/hw/arm/virt.h| 14 +-
 5 files changed, 14 insertions(+), 44 deletions(-)
 delete mode 100644 include/hw/arm/virt-acpi-build.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4a605791fc98..465b9f0f8440 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -508,7 +508,6 @@ M: Shannon Zhao 
 L: qemu-...@nongnu.org
 S: Maintained
 F: hw/arm/virt-acpi-build.c
-F: include/hw/arm/virt-acpi-build.h
 
 STM32F205
 M: Alistair Francis 
@@ -885,7 +884,6 @@ F: hw/acpi/*
 F: hw/smbios/*
 F: hw/i386/acpi-build.[hc]
 F: hw/arm/virt-acpi-build.c
-F: include/hw/arm/virt-acpi-build.h
 
 ppc4xx
 M: Alexander Graf 
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index a6c6180f4bce..dbd359063781 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -29,7 +29,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
-#include "hw/arm/virt-acpi-build.h"
 #include "qemu/bitmap.h"
 #include "trace.h"
 #include "qom/cpu.h"
@@ -43,6 +42,7 @@
 #include "hw/acpi/aml-build.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
+#include "hw/arm/virt.h"
 #include "sysemu/numa.h"
 #include "kvm_arm.h"
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d242980869bc..e51c1668e16e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -48,7 +48,6 @@
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
 #include "hw/pci-host/gpex.h"
-#include "hw/arm/virt-acpi-build.h"
 #include "hw/arm/sysbus-fdt.h"
 #include "hw/platform-bus.h"
 #include "hw/arm/fdt.h"
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
deleted file mode 100644
index 925c4347381c..
--- a/include/hw/arm/virt-acpi-build.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
- *
- * Author: Shannon Zhao 
- *
- * 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 QEMU_VIRT_ACPI_BUILD_H
-#define QEMU_VIRT_ACPI_BUILD_H
-
-#include "qemu-common.h"
-#include "hw/arm/virt.h"
-#include "qemu/notify.h"
-
-typedef struct VirtGuestInfo {
-int smp_cpus;
-FWCfgState *fw_cfg;
-const MemMapEntry *memmap;
-const int *irqmap;
-bool use_highmem;
-int gic_version;
-bool no_its;
-} VirtGuestInfo;
-
-void virt_acpi_setup(VirtGuestInfo *guest_info);
-
-#endif
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index b805b7622834..248ba6f755a3 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -32,6 +32,7 @@
 
 #include "qemu-common.h"
 #include "exec/hwaddr.h"
+#include "qemu/notify.h"
 
 #define NUM_GICV2M_SPIS   64
 #define NUM_VIRTIO_TRANSPORTS 32
@@ -76,5 +77,16 @@ typedef struct MemMapEntry {
 hwaddr size;
 } MemMapEntry;
 
+typedef struct VirtGuestInfo {
+int smp_cpus;
+FWCfgState *fw_cfg;
+const MemMapEntry *memmap;
+const int *irqmap;
+bool use_highmem;
+int gic_version;
+bool no_its;
+} VirtGuestInfo;
 
-#endif
+void virt_acpi_setup(VirtGuestInfo *guest_info);
+
+#endif /* QEMU_ARM_VIRT_H */
-- 
2.9.3




[Qemu-devel] [PATCH v2 10/16] hw/arm/virt: pass VirtMachineState instead of VirtGuestInfo

2017-01-02 Thread Andrew Jones
Only two functions take VirtGuestInfo parameters. Now that guest-info
is part of VirtMachineState, and VirtMachineState is defined in the
virt header, pass that instead.

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c | 3 ++-
 hw/arm/virt.c| 8 
 include/hw/arm/virt.h| 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index dbd359063781..0c36ee83d065 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -823,8 +823,9 @@ static const VMStateDescription vmstate_virt_acpi_build = {
 },
 };
 
-void virt_acpi_setup(VirtGuestInfo *guest_info)
+void virt_acpi_setup(VirtMachineState *vms)
 {
+VirtGuestInfo *guest_info = >acpi_guest_info;
 AcpiBuildTables tables;
 AcpiBuildState *build_state;
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 51cb094d80f7..51f4d8c78c19 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1155,9 +1155,9 @@ static void *machvirt_dtb(const struct arm_boot_info 
*binfo, int *fdt_size)
 return board->fdt;
 }
 
-static void virt_build_smbios(VirtGuestInfo *guest_info)
+static void virt_build_smbios(VirtMachineState *vms)
 {
-FWCfgState *fw_cfg = guest_info->fw_cfg;
+FWCfgState *fw_cfg = vms->acpi_guest_info.fw_cfg;
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
 const char *product = "QEMU Virtual Machine";
@@ -1190,8 +1190,8 @@ void virt_machine_done(Notifier *notifier, void *data)
 VirtMachineState *vms = container_of(notifier, VirtMachineState,
  machine_done);
 
-virt_acpi_setup(>acpi_guest_info);
-virt_build_smbios(>acpi_guest_info);
+virt_acpi_setup(vms);
+virt_build_smbios(vms);
 }
 
 static void machvirt_init(MachineState *machine)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 59ce353f5e71..8ac2d8585e0d 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -126,6 +126,6 @@ typedef struct {
 OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
 
 
-void virt_acpi_setup(VirtGuestInfo *guest_info);
+void virt_acpi_setup(VirtMachineState *vms);
 
 #endif /* QEMU_ARM_VIRT_H */
-- 
2.9.3




[Qemu-devel] [PATCH v2 09/16] hw/arm/virt: move VirtMachineState/Class to virt.h

2017-01-02 Thread Andrew Jones
In preparation to share more Virt machine state than just guest-info
with other mach-virt source files, move the State and Class structures
to virt.h

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt.c | 52 +++
 include/hw/arm/virt.h | 39 ++
 2 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e51c1668e16e..51cb094d80f7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -41,7 +41,6 @@
 #include "sysemu/numa.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
-#include "hw/boards.h"
 #include "hw/compat.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
@@ -58,50 +57,6 @@
 #include "qapi/visitor.h"
 #include "standard-headers/linux/input.h"
 
-/* Number of external interrupt lines to configure the GIC with */
-#define NUM_IRQS 256
-
-#define PLATFORM_BUS_NUM_IRQS 64
-
-static ARMPlatformBusSystemParams platform_bus_params;
-
-typedef struct {
-MachineClass parent;
-bool disallow_affinity_adjustment;
-bool no_its;
-bool no_pmu;
-bool claim_edge_triggered_timers;
-} VirtMachineClass;
-
-typedef struct {
-MachineState parent;
-VirtGuestInfo acpi_guest_info;
-Notifier machine_done;
-bool secure;
-bool highmem;
-bool virt;
-int32_t gic_version;
-struct arm_boot_info bootinfo;
-const MemMapEntry *memmap;
-const int *irqmap;
-int smp_cpus;
-void *fdt;
-int fdt_size;
-uint32_t clock_phandle;
-uint32_t gic_phandle;
-uint32_t msi_phandle;
-int psci_conduit;
-} VirtMachineState;
-
-#define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
-#define VIRT_MACHINE(obj) \
-OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
-#define VIRT_MACHINE_GET_CLASS(obj) \
-OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_VIRT_MACHINE)
-#define VIRT_MACHINE_CLASS(klass) \
-OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
-
-
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
 static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
 void *data) \
@@ -131,6 +86,13 @@ typedef struct {
 DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
 
 
+/* Number of external interrupt lines to configure the GIC with */
+#define NUM_IRQS 256
+
+#define PLATFORM_BUS_NUM_IRQS 64
+
+static ARMPlatformBusSystemParams platform_bus_params;
+
 /* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
  * RAM can go up to the 256GB mark, leaving 256GB of the physical
  * address space unallocated and free for future use between 256G and 512G.
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 248ba6f755a3..59ce353f5e71 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -33,6 +33,8 @@
 #include "qemu-common.h"
 #include "exec/hwaddr.h"
 #include "qemu/notify.h"
+#include "hw/boards.h"
+#include "hw/arm/arm.h"
 
 #define NUM_GICV2M_SPIS   64
 #define NUM_VIRTIO_TRANSPORTS 32
@@ -87,6 +89,43 @@ typedef struct VirtGuestInfo {
 bool no_its;
 } VirtGuestInfo;
 
+typedef struct {
+MachineClass parent;
+bool disallow_affinity_adjustment;
+bool no_its;
+bool no_pmu;
+bool claim_edge_triggered_timers;
+} VirtMachineClass;
+
+typedef struct {
+MachineState parent;
+VirtGuestInfo acpi_guest_info;
+Notifier machine_done;
+bool secure;
+bool highmem;
+bool virt;
+int32_t gic_version;
+struct arm_boot_info bootinfo;
+const MemMapEntry *memmap;
+const int *irqmap;
+int smp_cpus;
+void *fdt;
+int fdt_size;
+uint32_t clock_phandle;
+uint32_t gic_phandle;
+uint32_t msi_phandle;
+int psci_conduit;
+} VirtMachineState;
+
+#define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
+#define VIRT_MACHINE(obj) \
+OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
+#define VIRT_MACHINE_GET_CLASS(obj) \
+OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_VIRT_MACHINE)
+#define VIRT_MACHINE_CLASS(klass) \
+OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
+
+
 void virt_acpi_setup(VirtGuestInfo *guest_info);
 
 #endif /* QEMU_ARM_VIRT_H */
-- 
2.9.3




[Qemu-devel] [PATCH v2 16/16] hw/arm/virt-acpi-build: madt: add vgic maint irq

2017-01-02 Thread Andrew Jones
When virtualization is enabled and we have a v3 gic, then we add
the vgic maintenance interrupt to the DT. This patch is the ACPI
equivalent.

Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 7c00ee683f44..971ee4885c43 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -607,6 +607,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 if (arm_feature(>env, ARM_FEATURE_PMU)) {
 gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
 }
+if (vms->virt && vms->gic_version == 3) {
+gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GICV3_MAINT_IRQ));
+}
 }
 
 if (vms->gic_version == 3) {
-- 
2.9.3




[Qemu-devel] [PATCH v2 07/16] hw/arm/virt: eliminate struct VirtGuestInfoState

2017-01-02 Thread Andrew Jones
Instead of allocating a new struct just for VirtGuestInfo and the
machine_done Notifier, place them inside VirtMachineState. This
is the mach-virt equivalent of "pc: Eliminate struct
PcGuestInfoState"

Suggested-by: Eduardo Habkost 
Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt.c| 20 +++-
 include/hw/arm/virt-acpi-build.h |  6 --
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 67c0abb30b5b..d242980869bc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -76,6 +76,8 @@ typedef struct {
 
 typedef struct {
 MachineState parent;
+VirtGuestInfo acpi_guest_info;
+Notifier machine_done;
 bool secure;
 bool highmem;
 bool virt;
@@ -1222,12 +1224,13 @@ static void virt_build_smbios(VirtGuestInfo *guest_info)
 }
 
 static
-void virt_guest_info_machine_done(Notifier *notifier, void *data)
+void virt_machine_done(Notifier *notifier, void *data)
 {
-VirtGuestInfoState *guest_info_state = container_of(notifier,
-  VirtGuestInfoState, 
machine_done);
-virt_acpi_setup(_info_state->info);
-virt_build_smbios(_info_state->info);
+VirtMachineState *vms = container_of(notifier, VirtMachineState,
+ machine_done);
+
+virt_acpi_setup(>acpi_guest_info);
+virt_build_smbios(>acpi_guest_info);
 }
 
 static void machvirt_init(MachineState *machine)
@@ -1240,8 +1243,7 @@ static void machvirt_init(MachineState *machine)
 int n, virt_max_cpus;
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 const char *cpu_model = machine->cpu_model;
-VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
-VirtGuestInfo *guest_info = _info_state->info;
+VirtGuestInfo *guest_info = >acpi_guest_info;
 char **cpustr;
 ObjectClass *oc;
 const char *typename;
@@ -1459,8 +1461,8 @@ static void machvirt_init(MachineState *machine)
 guest_info->use_highmem = vms->highmem;
 guest_info->gic_version = vms->gic_version;
 guest_info->no_its = vmc->no_its;
-guest_info_state->machine_done.notify = virt_guest_info_machine_done;
-qemu_add_machine_init_done_notifier(_info_state->machine_done);
+vms->machine_done.notify = virt_machine_done;
+qemu_add_machine_init_done_notifier(>machine_done);
 
 vms->bootinfo.ram_size = machine->ram_size;
 vms->bootinfo.kernel_filename = machine->kernel_filename;
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index 2bcd22265cfa..925c4347381c 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -34,12 +34,6 @@ typedef struct VirtGuestInfo {
 bool no_its;
 } VirtGuestInfo;
 
-
-typedef struct VirtGuestInfoState {
-VirtGuestInfo info;
-Notifier machine_done;
-} VirtGuestInfoState;
-
 void virt_acpi_setup(VirtGuestInfo *guest_info);
 
 #endif
-- 
2.9.3




[Qemu-devel] [PATCH v2 15/16] hw/arm/virt-acpi-build: use SMC if booting in EL2

2017-01-02 Thread Andrew Jones
Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index b5e17a680d51..7c00ee683f44 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -643,16 +643,16 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 }
 
 /* FADT */
-static void
-build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
+static void build_fadt(GArray *table_data, BIOSLinker *linker,
+   VirtMachineState *vms, unsigned dsdt_tbl_offset)
 {
 AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
 unsigned dsdt_entry_offset = (char *)>dsdt - table_data->data;
+uint16_t use_hvc = vms->virt ? 0 : ACPI_FADT_ARM_PSCI_USE_HVC;
 
-/* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
+/* Hardware Reduced = 1 and use PSCI 0.2+ */
 fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
-fadt->arm_boot_flags = cpu_to_le16(ACPI_FADT_ARM_PSCI_COMPLIANT |
-   ACPI_FADT_ARM_PSCI_USE_HVC);
+fadt->arm_boot_flags = cpu_to_le16(ACPI_FADT_ARM_PSCI_COMPLIANT | use_hvc);
 
 /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
 fadt->minor_revision = 0x1;
@@ -738,7 +738,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 
 /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
 acpi_add_table(table_offsets, tables_blob);
-build_fadt(tables_blob, tables->linker, dsdt);
+build_fadt(tables_blob, tables->linker, vms, dsdt);
 
 acpi_add_table(table_offsets, tables_blob);
 build_madt(tables_blob, tables->linker, vms);
-- 
2.9.3




[Qemu-devel] [PATCH v2 02/16] hw/arm/virt-acpi-build: name GIC CPU Interface Structure appropriately

2017-01-02 Thread Andrew Jones
Also move the enabled flag definition from mach-virt code to
acpi common.

Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c | 8 
 include/hw/acpi/acpi-defs.h  | 9 ++---
 include/hw/arm/virt-acpi-build.h | 2 --
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index f4b43562287a..0ed406cdd89c 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -581,11 +581,11 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 gicd->version = guest_info->gic_version;
 
 for (i = 0; i < guest_info->smp_cpus; i++) {
-AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
- sizeof *gicc);
+AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
+   sizeof(*gicc));
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
 
-gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
+gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
 gicc->length = sizeof(*gicc);
 if (guest_info->gic_version == 2) {
 gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
@@ -593,7 +593,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 gicc->cpu_interface_number = cpu_to_le32(i);
 gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
 gicc->uid = cpu_to_le32(i);
-gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
+gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
 
 if (arm_feature(>env, ARM_FEATURE_PMU)) {
 gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 154f3b82f6dc..510f23c93183 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -290,7 +290,7 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
 #define ACPI_APIC_XRUPT_SOURCE   8
 #define ACPI_APIC_LOCAL_X2APIC   9
 #define ACPI_APIC_LOCAL_X2APIC_NMI  10
-#define ACPI_APIC_GENERIC_INTERRUPT 11
+#define ACPI_APIC_GENERIC_CPU_INTERFACE 11
 #define ACPI_APIC_GENERIC_DISTRIBUTOR   12
 #define ACPI_APIC_GENERIC_MSI_FRAME 13
 #define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
@@ -361,7 +361,7 @@ struct AcpiMadtLocalX2ApicNmi {
 } QEMU_PACKED;
 typedef struct AcpiMadtLocalX2ApicNmi AcpiMadtLocalX2ApicNmi;
 
-struct AcpiMadtGenericInterrupt {
+struct AcpiMadtGenericCpuInterface {
 ACPI_SUB_HEADER_DEF
 uint16_t reserved;
 uint32_t cpu_interface_number;
@@ -378,7 +378,10 @@ struct AcpiMadtGenericInterrupt {
 uint64_t arm_mpidr;
 } QEMU_PACKED;
 
-typedef struct AcpiMadtGenericInterrupt AcpiMadtGenericInterrupt;
+typedef struct AcpiMadtGenericCpuInterface AcpiMadtGenericCpuInterface;
+
+/* GICC CPU Interface Flags */
+#define ACPI_MADT_GICC_ENABLED 1
 
 struct AcpiMadtGenericDistributor {
 ACPI_SUB_HEADER_DEF
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index f5ec749b8fea..2bcd22265cfa 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -24,8 +24,6 @@
 #include "hw/arm/virt.h"
 #include "qemu/notify.h"
 
-#define ACPI_GICC_ENABLED 1
-
 typedef struct VirtGuestInfo {
 int smp_cpus;
 FWCfgState *fw_cfg;
-- 
2.9.3




[Qemu-devel] [PATCH v2 04/16] hw/arm/virt-acpi-build: fadt: improve flag naming

2017-01-02 Thread Andrew Jones
Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c| 4 ++--
 include/hw/acpi/acpi-defs.h | 6 ++
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index b6b64296f119..a6c6180f4bce 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -642,8 +642,8 @@ build_fadt(GArray *table_data, BIOSLinker *linker, unsigned 
dsdt_tbl_offset)
 
 /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
 fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
-fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |
-   (1 << ACPI_FADT_ARM_PSCI_USE_HVC));
+fadt->arm_boot_flags = cpu_to_le16(ACPI_FADT_ARM_PSCI_COMPLIANT |
+   ACPI_FADT_ARM_PSCI_USE_HVC);
 
 /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
 fadt->minor_revision = 0x1;
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 8fe0996e15fb..d15b7e5cd39a 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -191,10 +191,8 @@ struct AcpiFadtDescriptorRev5_1 {
 
 typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
 
-enum {
-ACPI_FADT_ARM_USE_PSCI_G_0_2 = 0,
-ACPI_FADT_ARM_PSCI_USE_HVC = 1,
-};
+#define ACPI_FADT_ARM_PSCI_COMPLIANT  (1 << 0)
+#define ACPI_FADT_ARM_PSCI_USE_HVC(1 << 1)
 
 /*
  * Serial Port Console Redirection Table (SPCR), Rev. 1.02
-- 
2.9.3




[Qemu-devel] [PATCH v2 06/16] hw/arm/virt: use VirtMachineState.gic_version

2017-01-02 Thread Andrew Jones
machvirt_init may need to probe for the gic version. If so, then
make sure the result is written to VirtMachineState. With the
state up to date, use it instead of a local variable. This is a
cleanup that prepares for VirtMachineState to be passed to functions
even outside hw/arm/virt.c

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt.c | 35 +--
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d451bc4f6b9b..67c0abb30b5b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -319,7 +319,7 @@ static void fdt_add_psci_node(const VirtMachineState *vms)
 qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
 }
 
-static void fdt_add_timer_nodes(const VirtMachineState *vms, int gictype)
+static void fdt_add_timer_nodes(const VirtMachineState *vms)
 {
 /* On real hardware these interrupts are level-triggered.
  * On KVM they were edge-triggered before host kernel version 4.4,
@@ -347,7 +347,7 @@ static void fdt_add_timer_nodes(const VirtMachineState 
*vms, int gictype)
 irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
 }
 
-if (gictype == 2) {
+if (vms->gic_version == 2) {
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
  GIC_FDT_IRQ_PPI_CPU_WIDTH,
  (1 << vms->smp_cpus) - 1);
@@ -462,7 +462,7 @@ static void fdt_add_v2m_gic_node(VirtMachineState *vms)
 qemu_fdt_setprop_cell(vms->fdt, "/intc/v2m", "phandle", vms->msi_phandle);
 }
 
-static void fdt_add_gic_node(VirtMachineState *vms, int type)
+static void fdt_add_gic_node(VirtMachineState *vms)
 {
 vms->gic_phandle = qemu_fdt_alloc_phandle(vms->fdt);
 qemu_fdt_setprop_cell(vms->fdt, "/", "interrupt-parent", vms->gic_phandle);
@@ -473,7 +473,7 @@ static void fdt_add_gic_node(VirtMachineState *vms, int 
type)
 qemu_fdt_setprop_cell(vms->fdt, "/intc", "#address-cells", 0x2);
 qemu_fdt_setprop_cell(vms->fdt, "/intc", "#size-cells", 0x2);
 qemu_fdt_setprop(vms->fdt, "/intc", "ranges", NULL, 0);
-if (type == 3) {
+if (vms->gic_version == 3) {
 qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
 "arm,gic-v3");
 qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
@@ -500,7 +500,7 @@ static void fdt_add_gic_node(VirtMachineState *vms, int 
type)
 qemu_fdt_setprop_cell(vms->fdt, "/intc", "phandle", vms->gic_phandle);
 }
 
-static void fdt_add_pmu_nodes(const VirtMachineState *vms, int gictype)
+static void fdt_add_pmu_nodes(const VirtMachineState *vms)
 {
 CPUState *cpu;
 ARMCPU *armcpu;
@@ -514,7 +514,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms, 
int gictype)
 }
 }
 
-if (gictype == 2) {
+if (vms->gic_version == 2) {
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
  GIC_FDT_IRQ_PPI_CPU_WIDTH,
  (1 << vms->smp_cpus) - 1);
@@ -570,14 +570,14 @@ static void create_v2m(VirtMachineState *vms, qemu_irq 
*pic)
 fdt_add_v2m_gic_node(vms);
 }
 
-static void create_gic(VirtMachineState *vms, qemu_irq *pic, int type)
+static void create_gic(VirtMachineState *vms, qemu_irq *pic)
 {
 /* We create a standalone GIC */
 VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
 DeviceState *gicdev;
 SysBusDevice *gicbusdev;
 const char *gictype;
-int i;
+int type = vms->gic_version, i;
 
 gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
 
@@ -641,7 +641,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq 
*pic, int type)
 pic[i] = qdev_get_gpio_in(gicdev, i);
 }
 
-fdt_add_gic_node(vms, type);
+fdt_add_gic_node(vms);
 
 if (type == 3 && !vmc->no_its) {
 create_its(vms, gicdev);
@@ -1237,7 +1237,6 @@ static void machvirt_init(MachineState *machine)
 qemu_irq pic[NUM_IRQS];
 MemoryRegion *sysmem = get_system_memory();
 MemoryRegion *secure_sysmem = NULL;
-int gic_version = vms->gic_version;
 int n, virt_max_cpus;
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 const char *cpu_model = machine->cpu_model;
@@ -1258,14 +1257,14 @@ static void machvirt_init(MachineState *machine)
 /* We can probe only here because during property set
  * KVM is not available yet
  */
-if (!gic_version) {
+if (!vms->gic_version) {
 if (!kvm_enabled()) {
 error_report("gic-version=host requires KVM");
 exit(1);
 }
 
-gic_version = kvm_arm_vgic_probe();
-if (!gic_version) {
+vms->gic_version = kvm_arm_vgic_probe();
+if (!vms->gic_version) {
 error_report("Unable to determine GIC version supported by host");
 exit(1);
 }
@@ -1300,7 +1299,7 @@ static void machvirt_init(MachineState 

[Qemu-devel] [PATCH v2 00/16] Remove VirtGuestInfo

2017-01-02 Thread Andrew Jones
v2:
 - all Igor's suggestions
 - added four mach-virt acpi cleanup patches
 - added the remaining two acpi patches needed to bring equivalence
   to Peter's DT changes

This series is based on Peter's qemu-arm gicv3-virt branch. It's
main goal (patches 07-13), which was suggested by Eduardo, is to
remove an unnecessary structure, VirtGuestInfo, which is a
maintenance burden, as it requires duplicating Virt machine state.
Additionally patches 05-06 do some mach-virt cleanups and patches
14-16 add the ACPI equivalents of the DT patches in Peter's
gicv3-virt branch. The first four patches are cleanups to mach-virt's
acpi code.

Patches available here
https://github.com/rhdrjones/qemu/commits/virt/remove-guest-info-v2

Andrew Jones (16):
  hw/arm/virt-acpi-build: add all missing cpu_to_le's
  hw/arm/virt-acpi-build: name GIC CPU Interface Structure appropriately
  hw/arm/virt-acpi-build: gtdt: improve flag naming
  hw/arm/virt-acpi-build: fadt: improve flag naming
  hw/arm/virt: parameter passing cleanups
  hw/arm/virt: use VirtMachineState.gic_version
  hw/arm/virt: eliminate struct VirtGuestInfoState
  hw/arm/virt: remove include/hw/arm/virt-acpi-build.h
  hw/arm/virt: move VirtMachineState/Class to virt.h
  hw/arm/virt: pass VirtMachineState instead of VirtGuestInfo
  hw/arm/virt-acpi-build: remove redundant members from VirtGuestInfo
  hw/arm/virt-acpi-build: don't save VirtGuestInfo on AcpiBuildState
  hw/arm/virt: remove VirtGuestInfo
  hw/arm/virt-acpi-build: Don't incorrectly claim architectural timer to
be edge-triggered
  hw/arm/virt-acpi-build: use SMC if booting in EL2
  hw/arm/virt-acpi-build: madt: add vgic maint irq

 MAINTAINERS  |   2 -
 hw/arm/virt-acpi-build.c | 145 +--
 hw/arm/virt.c| 141 +
 include/hw/acpi/acpi-defs.h  |  33 +++--
 include/hw/arm/virt-acpi-build.h |  47 -
 include/hw/arm/virt.h|  43 +++-
 6 files changed, 178 insertions(+), 233 deletions(-)
 delete mode 100644 include/hw/arm/virt-acpi-build.h

-- 
2.9.3




[Qemu-devel] [PATCH v2 05/16] hw/arm/virt: parameter passing cleanups

2017-01-02 Thread Andrew Jones
Some simple cleanups made possible by "hw/arm/virt: Merge
VirtBoardInfo and VirtMachineState"

Signed-off-by: Andrew Jones 
Reviewed-by: Igor Mammedov 
Acked-by: Michael S. Tsirkin 
---
 hw/arm/virt.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7eec50a82494..d451bc4f6b9b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -570,10 +570,10 @@ static void create_v2m(VirtMachineState *vms, qemu_irq 
*pic)
 fdt_add_v2m_gic_node(vms);
 }
 
-static void create_gic(VirtMachineState *vms, qemu_irq *pic, int type,
-   bool secure, bool no_its)
+static void create_gic(VirtMachineState *vms, qemu_irq *pic, int type)
 {
 /* We create a standalone GIC */
+VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
 DeviceState *gicdev;
 SysBusDevice *gicbusdev;
 const char *gictype;
@@ -589,7 +589,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq 
*pic, int type,
  */
 qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
 if (!kvm_irqchip_in_kernel()) {
-qdev_prop_set_bit(gicdev, "has-security-extensions", secure);
+qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
 }
 qdev_init_nofail(gicdev);
 gicbusdev = SYS_BUS_DEVICE(gicdev);
@@ -643,7 +643,7 @@ static void create_gic(VirtMachineState *vms, qemu_irq 
*pic, int type,
 
 fdt_add_gic_node(vms, type);
 
-if (type == 3 && !no_its) {
+if (type == 3 && !vmc->no_its) {
 create_its(vms, gicdev);
 } else if (type == 2) {
 create_v2m(vms, pic);
@@ -1005,8 +1005,7 @@ static void create_pcie_irq_map(const VirtMachineState 
*vms,
0x7   /* PCI irq */);
 }
 
-static void create_pcie(const VirtMachineState *vms, qemu_irq *pic,
-bool use_highmem)
+static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
 {
 hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
 hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
@@ -1049,7 +1048,7 @@ static void create_pcie(const VirtMachineState *vms, 
qemu_irq *pic,
  mmio_reg, base_mmio, size_mmio);
 memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
 
-if (use_highmem) {
+if (vms->highmem) {
 /* Map high MMIO space */
 MemoryRegion *high_mmio_alias = g_new0(MemoryRegion, 1);
 
@@ -1098,7 +1097,7 @@ static void create_pcie(const VirtMachineState *vms, 
qemu_irq *pic,
 qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
  2, base_ecam, 2, size_ecam);
 
-if (use_highmem) {
+if (vms->highmem) {
 qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "ranges",
  1, FDT_PCI_RANGE_IOPORT, 2, 0,
  2, base_pio, 2, size_pio,
@@ -1428,7 +1427,7 @@ static void machvirt_init(MachineState *machine)
 
 create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
-create_gic(vms, pic, gic_version, vms->secure, vmc->no_its);
+create_gic(vms, pic, gic_version);
 
 fdt_add_pmu_nodes(vms, gic_version);
 
@@ -1441,7 +1440,7 @@ static void machvirt_init(MachineState *machine)
 
 create_rtc(vms, pic);
 
-create_pcie(vms, pic, vms->highmem);
+create_pcie(vms, pic);
 
 create_gpio(vms, pic);
 
-- 
2.9.3




[Qemu-devel] [PATCH v2 03/16] hw/arm/virt-acpi-build: gtdt: improve flag naming

2017-01-02 Thread Andrew Jones
Also remove all unused flags.

Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c| 10 +-
 include/hw/acpi/acpi-defs.h | 17 ++---
 2 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 0ed406cdd89c..b6b64296f119 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -543,17 +543,17 @@ build_gtdt(GArray *table_data, BIOSLinker *linker)
 gtdt = acpi_data_push(table_data, sizeof *gtdt);
 /* The interrupt values are the same with the device tree when adding 16 */
 gtdt->secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_S_EL1_IRQ + 16);
-gtdt->secure_el1_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
+gtdt->secure_el1_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
 
 gtdt->non_secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL1_IRQ + 16);
-gtdt->non_secure_el1_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE |
- ACPI_GTDT_ALWAYS_ON);
+gtdt->non_secure_el1_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE |
+ ACPI_GTDT_CAP_ALWAYS_ON);
 
 gtdt->virtual_timer_interrupt = cpu_to_le32(ARCH_TIMER_VIRT_IRQ + 16);
-gtdt->virtual_timer_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
+gtdt->virtual_timer_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
 
 gtdt->non_secure_el2_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL2_IRQ + 16);
-gtdt->non_secure_el2_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
+gtdt->non_secure_el2_flags = cpu_to_le32(ACPI_GTDT_INTERRUPT_MODE_EDGE);
 
 build_header(linker, table_data,
  (void *)(table_data->data + gtdt_start), "GTDT",
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 510f23c93183..8fe0996e15fb 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -430,21 +430,8 @@ typedef struct AcpiMadtGenericTranslator 
AcpiMadtGenericTranslator;
 /*
  * Generic Timer Description Table (GTDT)
  */
-
-#define ACPI_GTDT_INTERRUPT_MODE(1 << 0)
-#define ACPI_GTDT_INTERRUPT_POLARITY(1 << 1)
-#define ACPI_GTDT_ALWAYS_ON (1 << 2)
-
-/* Triggering */
-
-#define ACPI_LEVEL_SENSITIVE((uint8_t) 0x00)
-#define ACPI_EDGE_SENSITIVE ((uint8_t) 0x01)
-
-/* Polarity */
-
-#define ACPI_ACTIVE_HIGH((uint8_t) 0x00)
-#define ACPI_ACTIVE_LOW ((uint8_t) 0x01)
-#define ACPI_ACTIVE_BOTH((uint8_t) 0x02)
+#define ACPI_GTDT_INTERRUPT_MODE_EDGE (1 << 0)
+#define ACPI_GTDT_CAP_ALWAYS_ON   (1 << 2)
 
 struct AcpiGenericTimerTable {
 ACPI_TABLE_HEADER_DEF
-- 
2.9.3




[Qemu-devel] [PATCH v2 01/16] hw/arm/virt-acpi-build: add all missing cpu_to_le's

2017-01-02 Thread Andrew Jones
Signed-off-by: Andrew Jones 
---
 hw/arm/virt-acpi-build.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index d4160dfa7d34..f4b43562287a 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -542,17 +542,18 @@ build_gtdt(GArray *table_data, BIOSLinker *linker)
 
 gtdt = acpi_data_push(table_data, sizeof *gtdt);
 /* The interrupt values are the same with the device tree when adding 16 */
-gtdt->secure_el1_interrupt = ARCH_TIMER_S_EL1_IRQ + 16;
-gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
+gtdt->secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_S_EL1_IRQ + 16);
+gtdt->secure_el1_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
 
-gtdt->non_secure_el1_interrupt = ARCH_TIMER_NS_EL1_IRQ + 16;
-gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE | ACPI_GTDT_ALWAYS_ON;
+gtdt->non_secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL1_IRQ + 16);
+gtdt->non_secure_el1_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE |
+ ACPI_GTDT_ALWAYS_ON);
 
-gtdt->virtual_timer_interrupt = ARCH_TIMER_VIRT_IRQ + 16;
-gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
+gtdt->virtual_timer_interrupt = cpu_to_le32(ARCH_TIMER_VIRT_IRQ + 16);
+gtdt->virtual_timer_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
 
-gtdt->non_secure_el2_interrupt = ARCH_TIMER_NS_EL2_IRQ + 16;
-gtdt->non_secure_el2_flags = ACPI_EDGE_SENSITIVE;
+gtdt->non_secure_el2_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL2_IRQ + 16);
+gtdt->non_secure_el2_flags = cpu_to_le32(ACPI_EDGE_SENSITIVE);
 
 build_header(linker, table_data,
  (void *)(table_data->data + gtdt_start), "GTDT",
@@ -576,7 +577,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 gicd = acpi_data_push(table_data, sizeof *gicd);
 gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
 gicd->length = sizeof(*gicd);
-gicd->base_address = memmap[VIRT_GIC_DIST].base;
+gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
 gicd->version = guest_info->gic_version;
 
 for (i = 0; i < guest_info->smp_cpus; i++) {
@@ -587,11 +588,11 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtGuestInfo *guest_info)
 gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
 gicc->length = sizeof(*gicc);
 if (guest_info->gic_version == 2) {
-gicc->base_address = memmap[VIRT_GIC_CPU].base;
+gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
 }
-gicc->cpu_interface_number = i;
-gicc->arm_mpidr = armcpu->mp_affinity;
-gicc->uid = i;
+gicc->cpu_interface_number = cpu_to_le32(i);
+gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
+gicc->uid = cpu_to_le32(i);
 gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
 
 if (arm_feature(>env, ARM_FEATURE_PMU)) {
-- 
2.9.3




[Qemu-devel] [Bug 925405] Re: VNC server does not work with Mac Screen Sharing

2017-01-02 Thread Rui Carmo
Well, I understand that since they do their own encoding (hence the need
for a different protocol number for their stuff to talk to each other),
but I don't think that's the whole thing, since I don't get any updates
from the server, and the VNC spec (IIRC) allowed for negotiating a
common version and encodings.

Regardless, would it be feasible to fix this from a user perspective?

(and Happy New Year!)

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

Title:
  VNC server does not work with Mac Screen Sharing

Status in QEMU:
  Incomplete
Status in Ubuntu:
  Invalid

Bug description:
  When connecting to a QEMU instance from a Mac using any VNC settings
  on the QEMU CLI and any target arch (ARM, Intel, etc.), the connection
  is attempted but the negotiation never finishes.

  I've verified this when building QEMU from source (1.0 and HEAD) on
  Ubuntu, Fedora and Debian or when using Ubuntu (Oneiric) and Debian
  (Lenny) packages.

  It does not matter whether I specify authentication (or anything else)
  on QEMU's side, the behavior is always the same - I see the connection
  being established using netstat and tcpdump, but QEMU does not seem to
  send back any pixmap data after the connection setup.

  Best guess as to why this happens is that the VNC negotiation on QEMU
  does not like the protocol version and VNC encoding sent by the Mac's
  built-in VNC client, or that its negotiation logic is subtly broken. I
  appreciate that it's not meant to be a full VNC server, but it
  prevents me from using it remotely until a stable Mac build is
  feasible.

  Background info:

  Mac OS X includes a VNC client called Screen Sharing that you can
  invoke in two different ways:

  * At a terminal, by typing "open vnc://hostname:tcp_port"
  * From any URI-enabled field (such as the Safari URI field), where you can 
just type the URI as vnc://hostname:tcp_port

  Please do not confuse the enhanced VNC protocol Apple Remote Desktop
  uses with Screen Sharing - they are not mutually exclusive, but they
  are not incompatible either, since what Apple does is to negotiate
  extra pixmap encoding and authentication options - I use Screen
  Sharing to access many VNC servers such as vnc4server, tightvncserver,
  vino, etc. without any issues whatsoever, so the issue I'm reporting
  is not an issue with Apple's implementation.

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



Re: [Qemu-devel] [Bug 925405] Re: VNC server does not work with Mac Screen Sharing

2017-01-02 Thread François Revol

On 01/01/2017 17:55, Rui Carmo wrote:

Hey there. Will git tip from September do? At that time I built QEMU on
Ubuntu 16.04.1, pointed my Mac (10.10) at it again and had the same
experience (had to use a third-party client)

Considering I opened this four years ago, I'm kind of surprised it's
still a talking topic. Was kind of expecting more people to report it,
but then again Launchpad is a bit off the beaten path these days and
most people just sigh and fetch a third party client.

It's just that it seems like a trivial thing to fix overall, so I
thought it worthwhile to chime in - Happy New Year!




For what it's worth, it's a bug in Apple's client which despite them 
claiming to "use the industry standard VNC" (whatever that means) 
clearly violates the VNC specs by replying with a boggus protocol 
version number.


I told them 5 years ago but it's not like they care about respecting 
standards...


François.



[Qemu-devel] [PATCH] mttcg: Add missing tb_lock/unlock() in cpu_exec_step()

2017-01-02 Thread Pranith Kumar
The recent patch enabling lock assertions uncovered the missing lock
acquisition in cpu_exec_step(). This patch adds them.

CC: Richard Henderson 
CC: Alex Bennée 
Signed-off-by: Pranith Kumar 
---
 cpu-exec.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/cpu-exec.c b/cpu-exec.c
index aa8318d864..ef328087be 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -234,14 +234,18 @@ static void cpu_exec_step(CPUState *cpu)
 uint32_t flags;
 
 cpu_get_tb_cpu_state(env, , _base, );
+tb_lock();
 tb = tb_gen_code(cpu, pc, cs_base, flags,
  1 | CF_NOCACHE | CF_IGNORE_ICOUNT);
 tb->orig_tb = NULL;
+tb_unlock();
 /* execute the generated code */
 trace_exec_tb_nocache(tb, pc);
 cpu_tb_exec(cpu, tb);
+tb_lock();
 tb_phys_invalidate(tb, -1);
 tb_free(tb);
+tb_unlock();
 }
 
 void cpu_exec_step_atomic(CPUState *cpu)
-- 
2.11.0




Re: [Qemu-devel] [PATCH v3 2/3] vus: Introduce vhost-user-scsi host device

2017-01-02 Thread Felipe Franciosi

> On 2 Jan 2017, at 10:25, Paolo Bonzini  wrote:
> 
> 
> 
> On 21/12/2016 23:17, Felipe Franciosi wrote:
>> To use it, one must configure Qemu with --enable-vhost-user-scsi and
>> start Qemu with a command line equivalent to:
>> 
>> qemu-system-x86_64 \
>>   -chardev socket,id=vus0,path=/tmp/vus.sock \
>>   -device vhost-user-scsi-pci,chardev=vus0,bus=pci.0,addr=...
>> 
>> A separate commit presents a sample application linked with libiscsi to
>> provide a backend for vhost-user-scsi.
> 
> Please place CONFIG_VHOST_USER_SCSI=$(CONFIG_POSIX) symbol in
> default-configs/ (so that it is enabled by default on non-Windows hosts)
> instead of having the configure option.  Otherwise, the patches look good!

Thanks, will do that and send a v4.

Do you want any entries on MAINTAINERS for this code or are you happy to take 
care of it under hw/scsi/* ?

Felipe

> 
> Paolo




Re: [Qemu-devel] [PATCH for-2.9 17/30] aspeed/smc: handle SPI flash Command mode

2017-01-02 Thread mar.krzeminski



W dniu 02.01.2017 o 19:02, Cédric Le Goater pisze:

On 01/02/2017 06:33 PM, mar.krzeminski wrote:

Hello Cedric,

W dniu 02.01.2017 o 16:56, Cédric Le Goater pisze:

Hello Marcin,

On 12/05/2016 04:33 PM, mar.krzeminski wrote:

W dniu 05.12.2016 o 15:07, Cédric Le Goater pisze:

On 12/04/2016 05:31 PM, mar.krzeminski wrote:

Hi Cedric,

Since there is no public datasheet user guide for SMC I would ask some question
regarding HW itself because I got impression that you are implementing in this
model a part functionality that is done by Bootrom.

W dniu 29.11.2016 o 16:43, Cédric Le Goater pisze:

The Aspeed SMC controllers have a mode (Command mode) in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.

However, accesses are restricted to the segment window assigned the
the flash module by the controller. This window is defined by the
Segment Address Register.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Andrew Jeffery 
---
   hw/ssi/aspeed_smc.c | 174 

   1 file changed, 162 insertions(+), 12 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 72a44150b0a1..eec087199a22 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -69,6 +69,7 @@
   #define R_CTRL0   (0x10 / 4)
   #define   CTRL_CMD_SHIFT   16
   #define   CTRL_CMD_MASK0xff
+#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
   #define   CTRL_CE_STOP_ACTIVE  (1 << 2)
   #define   CTRL_CMD_MODE_MASK   0x3
   #define CTRL_READMODE  0x0
@@ -135,6 +136,16 @@
   #define ASPEED_SOC_SPI_FLASH_BASE   0x3000
   #define ASPEED_SOC_SPI2_FLASH_BASE  0x3800
   +/* Flash opcodes. */
+#define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
+#define SPI_OP_WRDI   0x04/* Write disable */
+#define SPI_OP_RDSR   0x05/* Read status register */
+#define SPI_OP_WREN   0x06/* Write enable */

Are you sure that the controller is aware af all above commands (especially 
WD/WE and RDS)?

HW is aware of SPI_OP_READ which is the default command for the
"normal" read mode. For other modes, fast and write, the command
op is configured in the CEx Control Register.

These ops are used in the model :

   * SPI_OP_READ_FAST, for dummies
   * SPI_OP_EN4B, might be useless if we expect software to send
 this command before using this mode.
   * SPI_OP_WREN, same comment.

The rest I should remove as it is unused.

I think only SPI_OP_READ should stay in the model, rest goes to guest.

Well, we will need at least one 'EN4B' command to be sent for the qemu
flash model to work. If the underlying m25p80 object does not know
about the address width, the expected number of bytes will be wrong and
the result bogus.

Hmm, most of the flash I know by default use 3byte address mode.
What flash are you connecting to model.

chips like n25q256a, mx25l25635e, w25q256. all are > 32MB.


Do you have same on HW?

No but it is difficult to know what the controller is doing
in that mode without spying on the bus.


Maybe aspeed support can help?
Or some clue in the doc.
More generally have you tested this feature in real HW?

Anyhow, after some experiments, I think you are right and
I should  get rid of these command OP in the next version.

MHO it is possible that controller send WREN command,
but I would be really surprised if it send EN4B.


What about the dummy cycles ? the linux driver now has
support for it and it would be nice to get some support
in qemu also.

Target is still 2.9, but I am quite loaded now. From the other hand,
in current Qemu you can have it working with easy update in the
feature. Just send byte every dummy clock.

Thanks,
Marcin


Thanks,

C.


Same remark for the WREN, if the m25p80 object is not write enabled,
modifying the flash content won't work.

Same as above.

Thanks,
Marcin

Thanks,

C.


+
+/* Used for Macronix and Winbond flashes. */
+#define SPI_OP_EN4B   0xb7/* Enter 4-byte mode */
+#define SPI_OP_EX4B   0xe9/* Exit 4-byte mode */
+

Same as above but I think 4byte address mode bit changes onlu nymber of bytes
that is sent after instruction.


   /*
* Default segments mapping addresses and size for each slave per
* controller. These can be changed when board is initialized with the
@@ -357,6 +368,98 @@ static inline bool aspeed_smc_is_writable(const 
AspeedSMCFlash *fl)
   return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
   }
   +static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
+{
+AspeedSMCState *s = fl->controller;
+int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
+
+/* This is the default value for read mode. In other modes, the
+ * command should be defined */
+if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
+cmd = 

Re: [Qemu-devel] [PATCH for-2.9 17/30] aspeed/smc: handle SPI flash Command mode

2017-01-02 Thread Cédric Le Goater
On 01/02/2017 06:33 PM, mar.krzeminski wrote:
> Hello Cedric,
> 
> W dniu 02.01.2017 o 16:56, Cédric Le Goater pisze:
>> Hello Marcin,
>>
>> On 12/05/2016 04:33 PM, mar.krzeminski wrote:
>>>
>>> W dniu 05.12.2016 o 15:07, Cédric Le Goater pisze:
 On 12/04/2016 05:31 PM, mar.krzeminski wrote:
> Hi Cedric,
>
> Since there is no public datasheet user guide for SMC I would ask some 
> question
> regarding HW itself because I got impression that you are implementing in 
> this
> model a part functionality that is done by Bootrom.
>
> W dniu 29.11.2016 o 16:43, Cédric Le Goater pisze:
>> The Aspeed SMC controllers have a mode (Command mode) in which
>> accesses to the flash content are no different than doing MMIOs. The
>> controller generates all the necessary commands to load (or store)
>> data in memory.
>>
>> However, accesses are restricted to the segment window assigned the
>> the flash module by the controller. This window is defined by the
>> Segment Address Register.
>>
>> Signed-off-by: Cédric Le Goater 
>> Reviewed-by: Andrew Jeffery 
>> ---
>>   hw/ssi/aspeed_smc.c | 174 
>> 
>>   1 file changed, 162 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
>> index 72a44150b0a1..eec087199a22 100644
>> --- a/hw/ssi/aspeed_smc.c
>> +++ b/hw/ssi/aspeed_smc.c
>> @@ -69,6 +69,7 @@
>>   #define R_CTRL0   (0x10 / 4)
>>   #define   CTRL_CMD_SHIFT   16
>>   #define   CTRL_CMD_MASK0xff
>> +#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
>>   #define   CTRL_CE_STOP_ACTIVE  (1 << 2)
>>   #define   CTRL_CMD_MODE_MASK   0x3
>>   #define CTRL_READMODE  0x0
>> @@ -135,6 +136,16 @@
>>   #define ASPEED_SOC_SPI_FLASH_BASE   0x3000
>>   #define ASPEED_SOC_SPI2_FLASH_BASE  0x3800
>>   +/* Flash opcodes. */
>> +#define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
>> +#define SPI_OP_WRDI   0x04/* Write disable */
>> +#define SPI_OP_RDSR   0x05/* Read status register */
>> +#define SPI_OP_WREN   0x06/* Write enable */
> Are you sure that the controller is aware af all above commands 
> (especially WD/WE and RDS)?
 HW is aware of SPI_OP_READ which is the default command for the
 "normal" read mode. For other modes, fast and write, the command
 op is configured in the CEx Control Register.

 These ops are used in the model :

   * SPI_OP_READ_FAST, for dummies
   * SPI_OP_EN4B, might be useless if we expect software to send
 this command before using this mode.
   * SPI_OP_WREN, same comment.

 The rest I should remove as it is unused.
>>> I think only SPI_OP_READ should stay in the model, rest goes to guest.
>> Well, we will need at least one 'EN4B' command to be sent for the qemu
>> flash model to work. If the underlying m25p80 object does not know
>> about the address width, the expected number of bytes will be wrong and
>> the result bogus.
> Hmm, most of the flash I know by default use 3byte address mode.
> What flash are you connecting to model.

chips like n25q256a, mx25l25635e, w25q256. all are > 32MB.

> Do you have same on HW?

No but it is difficult to know what the controller is doing 
in that mode without spying on the bus. 

Anyhow, after some experiments, I think you are right and 
I should  get rid of these command OP in the next version. 

What about the dummy cycles ? the linux driver now has 
support for it and it would be nice to get some support
in qemu also.

Thanks,

C.  

>>
>> Same remark for the WREN, if the m25p80 object is not write enabled,
>> modifying the flash content won't work.
> Same as above.
> 
> Thanks,
> Marcin
>>
>> Thanks,
>>
>> C.
>>
>> +
>> +/* Used for Macronix and Winbond flashes. */
>> +#define SPI_OP_EN4B   0xb7/* Enter 4-byte mode */
>> +#define SPI_OP_EX4B   0xe9/* Exit 4-byte mode */
>> +
> Same as above but I think 4byte address mode bit changes onlu nymber of 
> bytes
> that is sent after instruction.
>
>>   /*
>>* Default segments mapping addresses and size for each slave per
>>* controller. These can be changed when board is initialized with the
>> @@ -357,6 +368,98 @@ static inline bool aspeed_smc_is_writable(const 
>> AspeedSMCFlash *fl)
>>   return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
>>   }
>>   +static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
>> +{
>> +AspeedSMCState *s = fl->controller;
>> +int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & 
>> CTRL_CMD_MASK;
>> +
>> +/* This is the default value for read mode. In other modes, the
>> + 

Re: [Qemu-devel] [PATCH for-2.9 17/30] aspeed/smc: handle SPI flash Command mode

2017-01-02 Thread mar.krzeminski

Hello Cedric,

W dniu 02.01.2017 o 16:56, Cédric Le Goater pisze:

Hello Marcin,

On 12/05/2016 04:33 PM, mar.krzeminski wrote:


W dniu 05.12.2016 o 15:07, Cédric Le Goater pisze:

On 12/04/2016 05:31 PM, mar.krzeminski wrote:

Hi Cedric,

Since there is no public datasheet user guide for SMC I would ask some question
regarding HW itself because I got impression that you are implementing in this
model a part functionality that is done by Bootrom.

W dniu 29.11.2016 o 16:43, Cédric Le Goater pisze:

The Aspeed SMC controllers have a mode (Command mode) in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.

However, accesses are restricted to the segment window assigned the
the flash module by the controller. This window is defined by the
Segment Address Register.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Andrew Jeffery 
---
  hw/ssi/aspeed_smc.c | 174 
  1 file changed, 162 insertions(+), 12 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 72a44150b0a1..eec087199a22 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -69,6 +69,7 @@
  #define R_CTRL0   (0x10 / 4)
  #define   CTRL_CMD_SHIFT   16
  #define   CTRL_CMD_MASK0xff
+#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
  #define   CTRL_CE_STOP_ACTIVE  (1 << 2)
  #define   CTRL_CMD_MODE_MASK   0x3
  #define CTRL_READMODE  0x0
@@ -135,6 +136,16 @@
  #define ASPEED_SOC_SPI_FLASH_BASE   0x3000
  #define ASPEED_SOC_SPI2_FLASH_BASE  0x3800
  
+/* Flash opcodes. */

+#define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
+#define SPI_OP_WRDI   0x04/* Write disable */
+#define SPI_OP_RDSR   0x05/* Read status register */
+#define SPI_OP_WREN   0x06/* Write enable */

Are you sure that the controller is aware af all above commands (especially 
WD/WE and RDS)?

HW is aware of SPI_OP_READ which is the default command for the
"normal" read mode. For other modes, fast and write, the command
op is configured in the CEx Control Register.

These ops are used in the model :

  * SPI_OP_READ_FAST, for dummies
  * SPI_OP_EN4B, might be useless if we expect software to send
this command before using this mode.
  * SPI_OP_WREN, same comment.

The rest I should remove as it is unused.

I think only SPI_OP_READ should stay in the model, rest goes to guest.

Well, we will need at least one 'EN4B' command to be sent for the qemu
flash model to work. If the underlying m25p80 object does not know
about the address width, the expected number of bytes will be wrong and
the result bogus.

Hmm, most of the flash I know by default use 3byte address mode.
What flash are you connecting to model. Do you have same on HW?


Same remark for the WREN, if the m25p80 object is not write enabled,
modifying the flash content won't work.

Same as above.

Thanks,
Marcin


Thanks,

C.


+
+/* Used for Macronix and Winbond flashes. */
+#define SPI_OP_EN4B   0xb7/* Enter 4-byte mode */
+#define SPI_OP_EX4B   0xe9/* Exit 4-byte mode */
+

Same as above but I think 4byte address mode bit changes onlu nymber of bytes
that is sent after instruction.


  /*
   * Default segments mapping addresses and size for each slave per
   * controller. These can be changed when board is initialized with the
@@ -357,6 +368,98 @@ static inline bool aspeed_smc_is_writable(const 
AspeedSMCFlash *fl)
  return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
  }
  
+static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)

+{
+AspeedSMCState *s = fl->controller;
+int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
+
+/* This is the default value for read mode. In other modes, the
+ * command should be defined */
+if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
+cmd = SPI_OP_READ;
+}
+
+if (!cmd) {

cmd == 0 => NOP command for some flash (eg. mx66l1g45g).

So I should use another default value, OxFF ?

I believe this check is not needed at all because m25p80c will tell if it has
unsupported instruction and HW should accept all register values, isn't it?

+qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
+  __func__, aspeed_smc_flash_mode(fl));
+}
+
+return cmd;
+}
+
+static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
+{
+AspeedSMCState *s = fl->controller;
+
+if (s->ctrl->segments == aspeed_segments_spi) {
+return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
+} else {
+return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
+}
+}
+
+static void aspeed_smc_flash_select(const AspeedSMCFlash *fl)
+{
+AspeedSMCState *s = fl->controller;
+
+s->regs[s->r_ctrl0 + fl->id] &= 

Re: [Qemu-devel] [kvm-unit-tests PATCH 0/2] run_tests: support concurrent test execution

2017-01-02 Thread Paolo Bonzini


On 01/01/2017 11:34, Peter Xu wrote:
> run_tests.sh is getting slower. Maybe it's time to let it run faster.
> An obvious issue is that, we were running the tests sequentially in
> the past.
> 
> This series provides another new "-j" parameter. "-j 8" means we run
> the tests on 8 task queues. That'll fasten the script a lot. A very
> quick test of mine shows 3x speed boost with 8 task queues.
> 
> Most of the changes are in scripts/tash.bash of patch 2, which
> implemented the main logic for task managements. Please see commit
> message for more information.
> 
> I did a quick "make standalone" test to make sure this series won't
> break it. However I am not sure whether it'll break other thing that I
> don't know...

Would it work if run_tests.sh wrote a Makefile for all the tests (with
phony targets only), and then simply ran "make -f Makefile.tmp -jN"?

Thanks,

Paolo



Re: [Qemu-devel] [PATCH] pc: fix crash in rtc_set_memory() if initial cpu is marked as hotplugged

2017-01-02 Thread Paolo Bonzini


On 30/12/2016 15:33, Igor Mammedov wrote:
> 'hotplugged' propperty is meant to be used on migration side when migrating
> source with hotplugged devices.
> However though it not exacly correct usage of 'hotplugged' property
> it's possible to set generic hotplugged property for CPU using
>  -cpu foo,hotplugged=on
> or
>  -global foo.hotplugged=on
> 
> in this case qemu crashes with following backtrace:
> 
> ...
> 
> because pc_cpu_plug() assumes that hotplugged CPU could appear only after
> rtc/fw_cfg are initialized.
> Fix crash by replacing assumption with explicit checks of rtc/fw_cfg
> and updating them only if they were initialized.
> 
> Signed-off-by: Igor Mammedov 
> Reported-by: Eduardo Habkost 
> ---
>  hw/i386/pc.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index f3d7ad4..7b7e126 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1810,8 +1810,10 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>  
>  /* increment the number of CPUs */
>  pcms->boot_cpus++;
> -if (dev->hotplugged) {
> +if (pcms->rtc) {
>  rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus);
> +}
> +if (pcms->fw_cfg) {
>  fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
>  }
>  
> 

Looks good - adding qemu-stable too.

Paolo



Re: [Qemu-devel] [PATCH for-2.9 17/30] aspeed/smc: handle SPI flash Command mode

2017-01-02 Thread Cédric Le Goater
Hello Marcin,

On 12/05/2016 04:33 PM, mar.krzeminski wrote:
> 
> 
> W dniu 05.12.2016 o 15:07, Cédric Le Goater pisze:
>> On 12/04/2016 05:31 PM, mar.krzeminski wrote:
>>> Hi Cedric,
>>>
>>> Since there is no public datasheet user guide for SMC I would ask some 
>>> question
>>> regarding HW itself because I got impression that you are implementing in 
>>> this
>>> model a part functionality that is done by Bootrom.
>>>
>>> W dniu 29.11.2016 o 16:43, Cédric Le Goater pisze:
 The Aspeed SMC controllers have a mode (Command mode) in which
 accesses to the flash content are no different than doing MMIOs. The
 controller generates all the necessary commands to load (or store)
 data in memory.

 However, accesses are restricted to the segment window assigned the
 the flash module by the controller. This window is defined by the
 Segment Address Register.

 Signed-off-by: Cédric Le Goater 
 Reviewed-by: Andrew Jeffery 
 ---
  hw/ssi/aspeed_smc.c | 174 
 
  1 file changed, 162 insertions(+), 12 deletions(-)

 diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
 index 72a44150b0a1..eec087199a22 100644
 --- a/hw/ssi/aspeed_smc.c
 +++ b/hw/ssi/aspeed_smc.c
 @@ -69,6 +69,7 @@
  #define R_CTRL0   (0x10 / 4)
  #define   CTRL_CMD_SHIFT   16
  #define   CTRL_CMD_MASK0xff
 +#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
  #define   CTRL_CE_STOP_ACTIVE  (1 << 2)
  #define   CTRL_CMD_MODE_MASK   0x3
  #define CTRL_READMODE  0x0
 @@ -135,6 +136,16 @@
  #define ASPEED_SOC_SPI_FLASH_BASE   0x3000
  #define ASPEED_SOC_SPI2_FLASH_BASE  0x3800
  
 +/* Flash opcodes. */
 +#define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
 +#define SPI_OP_WRDI   0x04/* Write disable */
 +#define SPI_OP_RDSR   0x05/* Read status register */
 +#define SPI_OP_WREN   0x06/* Write enable */
>>> Are you sure that the controller is aware af all above commands (especially 
>>> WD/WE and RDS)?
>> HW is aware of SPI_OP_READ which is the default command for the 
>> "normal" read mode. For other modes, fast and write, the command 
>> op is configured in the CEx Control Register. 
>>
>> These ops are used in the model :
>>
>>  * SPI_OP_READ_FAST, for dummies
>>  * SPI_OP_EN4B, might be useless if we expect software to send
>>this command before using this mode.
>>  * SPI_OP_WREN, same comment.
>>
>> The rest I should remove as it is unused.
> I think only SPI_OP_READ should stay in the model, rest goes to guest.

Well, we will need at least one 'EN4B' command to be sent for the qemu 
flash model to work. If the underlying m25p80 object does not know 
about the address width, the expected number of bytes will be wrong and
the result bogus. 

Same remark for the WREN, if the m25p80 object is not write enabled, 
modifying the flash content won't work.

Thanks,

C. 

>>
 +
 +/* Used for Macronix and Winbond flashes. */
 +#define SPI_OP_EN4B   0xb7/* Enter 4-byte mode */
 +#define SPI_OP_EX4B   0xe9/* Exit 4-byte mode */
 +
>>> Same as above but I think 4byte address mode bit changes onlu nymber of 
>>> bytes
>>> that is sent after instruction.
>>>
  /*
   * Default segments mapping addresses and size for each slave per
   * controller. These can be changed when board is initialized with the
 @@ -357,6 +368,98 @@ static inline bool aspeed_smc_is_writable(const 
 AspeedSMCFlash *fl)
  return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
  }
  
 +static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
 +{
 +AspeedSMCState *s = fl->controller;
 +int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & 
 CTRL_CMD_MASK;
 +
 +/* This is the default value for read mode. In other modes, the
 + * command should be defined */
 +if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
 +cmd = SPI_OP_READ;
 +}
 +
 +if (!cmd) {
>>> cmd == 0 => NOP command for some flash (eg. mx66l1g45g).
>> So I should use another default value, OxFF ? 
> I believe this check is not needed at all because m25p80c will tell if it has
> unsupported instruction and HW should accept all register values, isn't it?
>>
 +qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode 
 %d\n",
 +  __func__, aspeed_smc_flash_mode(fl));
 +}
 +
 +return cmd;
 +}
 +
 +static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
 +{
 +AspeedSMCState *s = fl->controller;
 +
 +if (s->ctrl->segments == aspeed_segments_spi) {
 +return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
 +

[Qemu-devel] [PATCH 2/3] reuse user_creatable_add_opts() instead of user_creatable_add() in monitor

2017-01-02 Thread Igor Mammedov
Simplify code by dropping ~57LOC by merging user_creatable_add()
into user_creatable_add_opts() and using the later from monutor.
Along with it allocate opts_visitor_new() once in user_creatable_add_opts().

As result we have one less API func and a more readable/simple
user_creatable_add_opts() vs user_creatable_add().

Signed-off-by: Igor Mammedov 
---
 include/qom/object_interfaces.h | 17 --
 hmp.c   |  5 +--
 qom/object_interfaces.c | 71 ++---
 3 files changed, 18 insertions(+), 75 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 8b17f4d..fdd7603 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -76,23 +76,6 @@ void user_creatable_complete(Object *obj, Error **errp);
 bool user_creatable_can_be_deleted(UserCreatable *uc, Error **errp);
 
 /**
- * user_creatable_add:
- * @qdict: the object definition
- * @v: the visitor
- * @errp: if an error occurs, a pointer to an area to store the error
- *
- * Create an instance of the user creatable object whose type
- * is defined in @qdict by the 'qom-type' field, placing it
- * in the object composition tree with name provided by the
- * 'id' field. The remaining fields in @qdict are used to
- * initialize the object properties.
- *
- * Returns: the newly created object or NULL on error
- */
-Object *user_creatable_add(const QDict *qdict,
-   Visitor *v, Error **errp);
-
-/**
  * user_creatable_add_type:
  * @type: the object type name
  * @id: the unique ID for the object
diff --git a/hmp.c b/hmp.c
index b869617..e7bead5 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1808,7 +1808,6 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
 QemuOpts *opts;
-Visitor *v;
 Object *obj = NULL;
 
 opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, );
@@ -1817,9 +1816,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 return;
 }
 
-v = opts_visitor_new(opts);
-obj = user_creatable_add(qdict, v, );
-visit_free(v);
+obj = user_creatable_add_opts(opts, );
 qemu_opts_del(opts);
 
 if (err) {
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 4b880d0..9b4155a 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -34,57 +34,6 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error 
**errp)
 }
 }
 
-
-Object *user_creatable_add(const QDict *qdict,
-   Visitor *v, Error **errp)
-{
-char *type = NULL;
-char *id = NULL;
-Object *obj = NULL;
-Error *local_err = NULL;
-QDict *pdict;
-
-pdict = qdict_clone_shallow(qdict);
-
-visit_start_struct(v, NULL, NULL, 0, _err);
-if (local_err) {
-goto out;
-}
-
-qdict_del(pdict, "qom-type");
-visit_type_str(v, "qom-type", , _err);
-if (local_err) {
-goto out_visit;
-}
-
-qdict_del(pdict, "id");
-visit_type_str(v, "id", , _err);
-if (local_err) {
-goto out_visit;
-}
-visit_check_struct(v, _err);
-if (local_err) {
-goto out_visit;
-}
-
-obj = user_creatable_add_type(type, id, pdict, v, _err);
-
-out_visit:
-visit_end_struct(v, NULL);
-
-out:
-QDECREF(pdict);
-g_free(id);
-g_free(type);
-if (local_err) {
-error_propagate(errp, local_err);
-object_unref(obj);
-return NULL;
-}
-return obj;
-}
-
-
 Object *user_creatable_add_type(const char *type, const char *id,
 const QDict *qdict,
 Visitor *v, Error **errp)
@@ -157,13 +106,27 @@ Object *user_creatable_add_opts(QemuOpts *opts, Error 
**errp)
 {
 Visitor *v;
 QDict *pdict;
-Object *obj = NULL;
+Object *obj;
+const char *id = qemu_opts_id(opts);
+const char *type = qemu_opt_get(opts, "qom-type");
+
+if (!type) {
+error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
+return NULL;
+}
+if (!id) {
+error_setg(errp, QERR_MISSING_PARAMETER, "id");
+return NULL;
+}
 
-v = opts_visitor_new(opts);
 pdict = qemu_opts_to_qdict(opts, NULL);
+qdict_del(pdict, "qom-type");
+qdict_del(pdict, "id");
 
-obj = user_creatable_add(pdict, v, errp);
+v = opts_visitor_new(opts);
+obj = user_creatable_add_type(type, id, pdict, v, errp);
 visit_free(v);
+
 QDECREF(pdict);
 return obj;
 }
-- 
2.7.4




[Qemu-devel] [PATCH 0/3] fix query-memdev not repporting IDs of memory backends

2017-01-02 Thread Igor Mammedov
Series is a couple of preparratory cleanups which simplify fix
and a fix itself.

Before fix HMP 'info memdevs' for CLI:
qemu-system-x86_64 -object memory-backend-ram,id=mem0,size=1G
outputs:

  memory backend: 0
size:  1073741824
merge: true
dump: true
prealloc: false
policy: default
host nodes: 128

after fix:

  memory backend: mem0
size:  1073741824
merge: true
dump: true
prealloc: false
policy: default
host nodes: 128

it should help to avoid remembering hotplugged IDs as they
could be queried back via HMP/QMP interface.

CC: ehabk...@redhat.com
CC: arm...@redhat.com
CC: dgilb...@redhat.com
CC: ebl...@redhat.com
CC: afaer...@suse.de

Igor Mammedov (3):
  cleanup: remove not used header
  reuse user_creatable_add_opts() instead of user_creatable_add() in
monitor
  fix qmp/hmp query-memdev not repporting IDs of memory backends

 include/qom/object_interfaces.h | 19 +-
 include/sysemu/hostmem.h|  1 +
 backends/hostmem.c  | 26 ++
 docs/qmp-commands.txt   |  1 +
 hmp.c   | 10 ++
 numa.c  |  3 ++
 qapi-schema.json|  3 ++
 qom/object_interfaces.c | 78 -
 8 files changed, 59 insertions(+), 82 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH 1/3] cleanup: remove not used header

2017-01-02 Thread Igor Mammedov
Signed-off-by: Igor Mammedov 
---
 qom/object_interfaces.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index ded4d84..4b880d0 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -3,7 +3,6 @@
 #include "qom/object_interfaces.h"
 #include "qemu/module.h"
 #include "qapi-visit.h"
-#include "qapi/qobject-output-visitor.h"
 #include "qapi/opts-visitor.h"
 
 void user_creatable_complete(Object *obj, Error **errp)
-- 
2.7.4




[Qemu-devel] [PATCH 3/3] fix qmp/hmp query-memdev not repporting IDs of memory backends

2017-01-02 Thread Igor Mammedov
Do it by adding 'id' property to hostmem backends and fetch it
in query-memdev from object directly.

Signed-off-by: Igor Mammedov 
---
 include/qom/object_interfaces.h |  2 +-
 include/sysemu/hostmem.h|  1 +
 backends/hostmem.c  | 26 ++
 docs/qmp-commands.txt   |  1 +
 hmp.c   |  5 +
 numa.c  |  3 +++
 qapi-schema.json|  3 +++
 qom/object_interfaces.c |  6 +-
 8 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index fdd7603..06cccd9 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -90,7 +90,7 @@ bool user_creatable_can_be_deleted(UserCreatable *uc, Error 
**errp);
  * Returns: the newly created object or NULL on error
  */
 Object *user_creatable_add_type(const char *type, const char *id,
-const QDict *qdict,
+QDict *qdict,
 Visitor *v, Error **errp);
 
 /**
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 678232a..ecae0cf 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -52,6 +52,7 @@ struct HostMemoryBackend {
 Object parent;
 
 /* protected */
+char *id;
 uint64_t size;
 bool merge, dump;
 bool prealloc, force_prealloc, is_mapped;
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 4256d24..7f5de70 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -348,6 +348,24 @@ host_memory_backend_can_be_deleted(UserCreatable *uc, 
Error **errp)
 }
 }
 
+static char *get_id(Object *o, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+return g_strdup(backend->id);
+}
+
+static void set_id(Object *o, const char *str, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+if (backend->id) {
+error_setg(errp, "cannot change property value");
+return;
+}
+backend->id = g_strdup(str);
+}
+
 static void
 host_memory_backend_class_init(ObjectClass *oc, void *data)
 {
@@ -377,6 +395,13 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
 HostMemPolicy_lookup,
 host_memory_backend_get_policy,
 host_memory_backend_set_policy, _abort);
+object_class_property_add_str(oc, "id", get_id, set_id, _abort);
+}
+
+static void host_memory_backend_finalize(Object *o)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(o);
+g_free(backend->id);
 }
 
 static const TypeInfo host_memory_backend_info = {
@@ -387,6 +412,7 @@ static const TypeInfo host_memory_backend_info = {
 .class_init = host_memory_backend_class_init,
 .instance_size = sizeof(HostMemoryBackend),
 .instance_init = host_memory_backend_init,
+.instance_finalize = host_memory_backend_finalize,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_USER_CREATABLE },
 { }
diff --git a/docs/qmp-commands.txt b/docs/qmp-commands.txt
index abf210a..18db4cd 100644
--- a/docs/qmp-commands.txt
+++ b/docs/qmp-commands.txt
@@ -3529,6 +3529,7 @@ Example (1):
  "policy": "bind"
},
{
+ "id": "mem1",
  "size": 536870912,
  "merge": false,
  "dump": true,
diff --git a/hmp.c b/hmp.c
index e7bead5..8522efe 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2078,13 +2078,11 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
 MemdevList *m = memdev_list;
 Visitor *v;
 char *str;
-int i = 0;
-
 
 while (m) {
 v = string_output_visitor_new(false, );
 visit_type_uint16List(v, NULL, >value->host_nodes, NULL);
-monitor_printf(mon, "memory backend: %d\n", i);
+monitor_printf(mon, "memory backend: %s\n", m->value->id);
 monitor_printf(mon, "  size:  %" PRId64 "\n", m->value->size);
 monitor_printf(mon, "  merge: %s\n",
m->value->merge ? "true" : "false");
@@ -2100,7 +2098,6 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
 g_free(str);
 visit_free(v);
 m = m->next;
-i++;
 }
 
 monitor_printf(mon, "\n");
diff --git a/numa.c b/numa.c
index 9c09e45..f5fc7da 100644
--- a/numa.c
+++ b/numa.c
@@ -518,6 +518,9 @@ static int query_memdev(Object *obj, void *opaque)
 
 m->value = g_malloc0(sizeof(*m->value));
 
+m->value->id = object_property_get_str(obj, "id", NULL);
+m->value->has_id = !!m->value->id;
+
 m->value->size = object_property_get_int(obj, "size",
  _abort);
 m->value->merge = object_property_get_bool(obj, "merge",
diff --git a/qapi-schema.json b/qapi-schema.json
index a0d3b5d..88eb2b9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4453,6 +4453,8 @@
 #
 # Information about memory backend
 #
+# @id: #optional backend's ID if backend has 

Re: [Qemu-devel] [PATCH 02/54] char: use a const CharDriver

2017-01-02 Thread Marc-André Lureau


- Original Message -
> On 12/12/2016 04:42 PM, Marc-André Lureau wrote:
> > No need to allocate & copy fileds, let's use static const struct
> 
> s/fileds/fields/
> 

ok

> > instead.
> > 
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  backends/baum.c   |   8 +++-
> >  backends/msmouse.c|   7 +++-
> >  backends/testdev.c|   7 +++-
> >  qemu-char.c   | 100
> >  --
> >  spice-qemu-char.c |  14 +--
> >  ui/console.c  |   9 +++--
> >  include/sysemu/char.h |  19 +-
> >  7 files changed, 90 insertions(+), 74 deletions(-)
> > 
> 
> > +++ b/backends/baum.c
> > @@ -686,8 +686,12 @@ fail_handle:
> >  
> >  static void register_types(void)
> >  {
> > -register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL,
> > - chr_baum_init);
> > +static const CharDriver driver = {
> > +.kind = CHARDEV_BACKEND_KIND_BRAILLE,
> > +.parse = NULL, .create = chr_baum_init
> 
> Why did the "braille" string disappear?  Oh, I see... [1]
> 
> No need to specify .parse, since C99 initialization guarantees
> zero-assignment to any field omitted.
> 
> I kind of prefer one struct member per line when doing C99
> initialization, rather than bunching two in one line.
> 
> I also prefer a trailing comma, as then adding a new (non-zero) member
> initialization in a later patch is a one-line addition, rather than
> modifying an existing line to add a trailing comma.

ok fixed

> 
> 
> > +++ b/backends/msmouse.c
> > @@ -179,8 +179,11 @@ static CharDriverState *qemu_chr_open_msmouse(const
> > char *id,
> >  
> >  static void register_types(void)
> >  {
> > -register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL,
> > - qemu_chr_open_msmouse);
> > +static const CharDriver driver = {
> > +.kind = CHARDEV_BACKEND_KIND_MSMOUSE,
> > +.parse = NULL, .create = qemu_chr_open_msmouse
> 
> Looks like my comments are repeated throughout the patch.
> 
> 
> > -void register_char_driver(const char *name, ChardevBackendKind kind,
> > -  CharDriverParse *parse, CharDriverCreate
> > *create)
> > +void register_char_driver(const CharDriver *driver)
> >  {
> > -CharDriver *s;
> > -
> > -s = g_malloc0(sizeof(*s));
> > -s->name = g_strdup(name);
> > -s->kind = kind;
> > -s->parse = parse;
> > -s->create = create;
> > -
> > -backends = g_slist_append(backends, s);
> > +backends = g_slist_append(backends, (void *)driver);
> 
> Might be worth a comment that this is casting away const (as my first
> reaction is "oh, you forgot that C allows automatic conversion of any
> pointer to void*")

ok (note: this going away the next patch)

> 
> >  }
> >  
> >  CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
> > @@ -4139,7 +4123,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts
> > *opts,
> >  fprintf(stderr, "Available chardev backend types:\n");
> >  for (i = backends; i; i = i->next) {
> >  cd = i->data;
> > -fprintf(stderr, "%s\n", cd->name);
> > +fprintf(stderr, "%s\n", ChardevBackendKind_lookup[cd->kind]);
> 
> ...[1] Your series is already long, so don't feel like you have to do
> this, but: if I were working on it, I might have done the elimination of
> cd->name, the name parameter, and the use of ChardevBackendKind_lookup[]
> in one patch (getting rid of JUST the "braille" parameter and friends at
> the call sites), and then the const'ification of the remaining
> parameters in the second patch.

The series is pretty long already (second version even longer), I don't see 
much need to split this patch

> 
> > +++ b/include/sysemu/char.h
> 
> Laszlo's suggestion of the git order file would have promoted this part
> of the patch first :)
> 

done

thanks



Re: [Qemu-devel] [PATCH 04/54] char: move callbacks in CharDriver

2017-01-02 Thread Marc-André Lureau
hi

- Original Message -
> On 12/12/2016 04:42 PM, Marc-André Lureau wrote:
> > This makes the code more declarative, and avoids to duplicate the
> 
> s/to duplicate/duplicating/

ok

> 
> > information on all instances.
> > 
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  backends/baum.c   |  13 +-
> >  backends/msmouse.c|  13 +-
> >  backends/testdev.c|  10 +-
> >  gdbstub.c |   7 +-
> >  hw/bt/hci-csr.c   |   8 +-
> >  qemu-char.c   | 427
> >  +++---
> >  spice-qemu-char.c |  36 +++--
> >  ui/console.c  |  26 +--
> >  ui/gtk.c  |  11 +-
> >  include/sysemu/char.h |  46 +++---
> 
> Again, seeing the .h changes first makes a huge difference on code
> review.  I'm manually reformatting:
> 
> >  10 files changed, 370 insertions(+), 227 deletions(-)
> 
> > diff --git a/include/sysemu/char.h b/include/sysemu/char.h
> > index c8750ede21..09e40ef9b8 100644
> > --- a/include/sysemu/char.h
> > +++ b/include/sysemu/char.h
> > @@ -85,24 +85,11 @@ typedef struct CharBackend {
> >  int fe_open;
> >  } CharBackend;
> >
> > +typedef struct CharDriver CharDriver;
> > +
> >  struct CharDriverState {
> > +const CharDriver *driver;
> >  QemuMutex chr_write_lock;
> > -int (*chr_write)(struct CharDriverState *s, const uint8_t *buf,
> int len);
> 
> So all the callbacks are moved into the CharDriver struct...
> 
> > @@ -125,7 +112,8 @@ struct CharDriverState {
> >   *
> >   * Returns: a newly allocated CharDriverState, or NULL on error.
> >   */
> > -CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp);
> > +CharDriverState *qemu_chr_alloc(const CharDriver *driver,
> > +ChardevCommon *backend, Error **errp);
> 
> ...and all the entry points are now passed that struct as a new parameter.
> 
> >
> >  /**
> >   * @qemu_chr_new_from_opts:
> > @@ -473,15 +461,33 @@ void qemu_chr_set_feature(CharDriverState *chr,
> >CharDriverFeature feature);
> >  QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
> >
> > -typedef struct CharDriver {
> > +struct CharDriver {
> 
> ...the struct already existed, but is now more useful.
> 
> Looks worthwhile. I suspect the rest of the patch is mechanical.
> 
> > @@ -688,7 +686,10 @@ static void register_types(void)
> >  {
> >  static const CharDriver driver = {
> >  .kind = CHARDEV_BACKEND_KIND_BRAILLE,
> > -.parse = NULL, .create = chr_baum_init
> > +.parse = NULL, .create = chr_baum_init,
> 
> And now you see why I asked for trailing commas in 2/54 :)
> 
> > +.chr_write = baum_write,
> > +.chr_accept_input = baum_accept_input,
> > +.chr_free = baum_free,
> >  };
> >  
> 
> > +++ b/gdbstub.c
> > @@ -1730,6 +1730,10 @@ int gdbserver_start(const char *device)
> >  CharDriverState *chr = NULL;
> >  CharDriverState *mon_chr;
> >  ChardevCommon common = { 0 };
> > +static const CharDriver driver = {
> > +.kind = -1,
> > +.chr_write = gdb_monitor_write
> 
> Trailing comma.
> 
> Interesting that this is a new use of CharDriver with an out-of-range
> .kind. But I think your code in 3/54 was careful to explicitly handle a
> .kind that does not map to one of the public types, so that you are able
> to use this as an internal-only driver.

and kind is removed is later patches "char: remove class kind field"

> 
> 
> >  
> > +static const CharDriver null_driver = {
> > +.kind = CHARDEV_BACKEND_KIND_NULL, .create = qemu_chr_open_null,
> 
> One initializer per line is fine.
> 
> > +.chr_write = null_chr_write
> > +};
> > +
> 
> > 
> > @@ -864,14 +880,6 @@ static CharDriverState *qemu_chr_open_mux(const char
> > *id,
> >  
> >  chr->opaque = d;
> >  d->focus = -1;
> > -chr->chr_free = mux_chr_free;
> > -chr->chr_write = mux_chr_write;
> > -chr->chr_accept_input = mux_chr_accept_input;
> > -/* Frontend guest-open / -close notification is not support with muxes
> > */
> > -chr->chr_set_fe_open = NULL;
> > -if (drv->chr_add_watch) {
> > -chr->chr_add_watch = mux_chr_add_watch;
> > -}
> 
> Here, the callback was only conditionally registered...
> 
> > +static const CharDriver mux_driver = {
> > +.kind = CHARDEV_BACKEND_KIND_MUX,
> > +.parse = qemu_chr_parse_mux, .create = qemu_chr_open_mux,
> > +.chr_free = mux_chr_free,
> > +.chr_write = mux_chr_write,
> > +.chr_accept_input = mux_chr_accept_input,
> > +.chr_add_watch = mux_chr_add_watch,
> > +};
> 
> ...but here, it is always registered.  Is that an unintentional semantic
> change?
> 

mux_chr_add_watch() also checks if the underlying driver has chr_add_watch(). 
qemu_chr_fe_add_watch() returns 0 in both cases then.


> 
> > +#ifdef HAVE_CHARDEV_SERIAL
> > +static const CharDriver serial_driver = {
> > +.alias = "tty", .kind = 

Re: [Qemu-devel] [PATCH 05/54] char: fold single-user functions in caller

2017-01-02 Thread Marc-André Lureau


- Original Message -
> On 12/12/2016 04:42 PM, Marc-André Lureau wrote:
> > This shorten a bit the code.
> 
> Grammar:
> This shortens the code a bit.
> 
> > 
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  qemu-char.c | 97
> >  -
> >  1 file changed, 31 insertions(+), 66 deletions(-)
> > 
> 
> >  name = g_strdup_printf("chardev-udp-%s", chr->label);
> >  qio_channel_set_name(QIO_CHANNEL(sioc), name);
> >  g_free(name);
> >  
> > +s = g_new0(NetCharDriver, 1);
> > +s->ioc = QIO_CHANNEL(sioc);
> > +s->bufcnt = 0;
> > +s->bufptr = 0;
> > +chr->opaque = s;
> > +/* be isn't opened until we get a connection */
> > +*be_opened = false;
> 
> The assignments to 0 and false are redundant with the g_new0(), if you
> want to drop them for even more code reduction.
> 

thanks, done

> Reviewed-by: Eric Blake 
> 
> --
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 
> 



Re: [Qemu-devel] [PATCH 03/54] char: use a static array for backends

2017-01-02 Thread Marc-André Lureau
Hi

- Original Message -
> On 12/12/2016 04:42 PM, Marc-André Lureau wrote:
> > Number and kinds of backends is known at compile-time, use a fixed-sized
> > static array to simplify iterations & lookups.
> > 
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  qemu-char.c   | 101
> >  --
> >  include/sysemu/char.h |   1 +
> >  2 files changed, 58 insertions(+), 44 deletions(-)
> > 
> 
> > @@ -4121,9 +4121,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts
> > *opts,
> >  
> >  if (is_help_option(qemu_opt_get(opts, "backend"))) {
> >  fprintf(stderr, "Available chardev backend types:\n");
> > -for (i = backends; i; i = i->next) {
> > -cd = i->data;
> > -fprintf(stderr, "%s\n", ChardevBackendKind_lookup[cd->kind]);
> > +for (i = 0; i < ARRAY_SIZE(backends); i++) {
> > +cd = backends[i];
> > +if (cd) {
> > +fprintf(stderr, "%s\n",
> > ChardevBackendKind_lookup[cd->kind]);
> > +if (cd->alias) {
> > +fprintf(stderr, "%s\n", cd->alias);
> > +}
> > +}
> 
> Where did cd->alias come from?
> /me reads rest of patch
> Oh, you added it in the .h file. All the more reason to use patch
> ordering to list .h changes first, but may also be worth a mention in
> the commit message that you add an alias field to cover the cases where
> we previously registered a driver twice under two names.

ok

> 
> > 
> > -cd = i->data;
> > +cd = NULL;
> > +for (i = 0; i < ARRAY_SIZE(backends); i++) {
> > +const char *name = qemu_opt_get(opts, "backend");
> > +cd = backends[i];
> 
> Please hoist the computation of 'name' outside of the loop...
> 
> > -if (strcmp(ChardevBackendKind_lookup[cd->kind],
> > -   qemu_opt_get(opts, "backend")) == 0) {
> > +if (!cd) {
> > +continue;
> > +}
> > +if (g_str_equal(ChardevBackendKind_lookup[cd->kind], name) ||
> > +(cd->alias && g_str_equal(cd->alias, name))) {
> 
> Doesn't g_str_equal(NULL, "str") do the right thing without crashing?
> Therefore, no need to check if cd->alias is non-NULL.

No it doesnt, but g_strcmp0 does, let's switch to it.

> 
> >  break;
> >  }
> >  }
> > -if (i == NULL) {
> > +if (cd == NULL) {
> >  error_setg(errp, "chardev: backend \"%s\" not found",
> > qemu_opt_get(opts, "backend"));
> 
> ...and then reuse 'name' here as well, rather than making multiple
> repeated calls to qemu_opt_get().

ok

> 
> >  ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
> >  {
> >  ChardevBackendInfoList *backend_list = NULL;
> > -CharDriver *c = NULL;
> > -GSList *i = NULL;
> > +const CharDriver *c;
> > +int i;
> >  
> > -for (i = backends; i; i = i->next) {
> > -ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
> > -c = i->data;
> > -info->value = g_malloc0(sizeof(*info->value));
> > -info->value->name = g_strdup(ChardevBackendKind_lookup[c->kind]);
> > +for (i = 0; i < ARRAY_SIZE(backends); i++) {
> > +c = backends[i];
> > +if (!c) {
> > +continue;
> > +}
> >  
> > -info->next = backend_list;
> > -backend_list = info;
> > +backend_list = qmp_prepend_backend(backend_list, c,
> > +
> > ChardevBackendKind_lookup[c->kind]);
> > +if (c->alias) {
> > +backend_list = qmp_prepend_backend(backend_list, c, c->alias);
> 
> The help text now lists aliases immediately after the canonical name,
> while the QMP command now prepends aliases prior to the canonical name.
> It doesn't affect correctness, but should you try to make the two lists
> appear in the same order?  (Presumably by prepending the alias first,
> not second.)
> 

I don't think it matters. Furthermore, this code is temporary, the "char: get 
rid of CharDriver" patch will use the same function 
qmp_query_chardev_backends() to build the list with object_class_get_list() 
order.

> > @@ -4907,16 +4925,11 @@ static void register_types(void)
> >  { .kind = CHARDEV_BACKEND_KIND_STDIO,
> >.parse = qemu_chr_parse_stdio, .create = qemu_chr_open_stdio },
> >  #if defined HAVE_CHARDEV_SERIAL
> > -{ .kind = CHARDEV_BACKEND_KIND_SERIAL,
> > -  .parse = qemu_chr_parse_serial, .create =
> > qmp_chardev_open_serial },
> > -{ .kind = CHARDEV_BACKEND_KIND_SERIAL,
> > +{ .kind = CHARDEV_BACKEND_KIND_SERIAL, .alias = "tty",
> >.parse = qemu_chr_parse_serial, .create =
> >qmp_chardev_open_serial },
> 
> Wait. How did patch 2/54 work? Or did you temporarily break the 'tty'
> alias in that patch, and then fix it here?  All the more reason that my

No, it shouldn't break. There were 2 CharDrivers in case of alias 

Re: [Qemu-devel] [RFC PATCH] Fix pasting into serial console in GTK ui

2017-01-02 Thread Michal Suchánek
Hello,

On Fri, 23 Dec 2016 17:29:28 +0100
Paolo Bonzini  wrote:

> On 23/12/2016 16:12, Michal Suchanek wrote:
> > This copies the timer hack from ui/console.c kbd_send_chars to
> > ui/gtk.c gd_vc_in.
> > 
> > There is no fd-like object to peek repatedly so the paste data is
> > saved in a free-floating buffer only submitted to gtk_timeout_add.
> > Multiple pastes can potentially interleave if qemu blocks for long
> > or the user pastes fast.  
> 
> Do not use a timer, instead set chr->chr_accept_input in
> gd_vc_handler. The callback can do basically what you are doing in
> gd_vc_in_timer.  The buffer can be just a GString plus a "head"
> pointer, in VirtualConsole. Once the head catches up with the tail,
> you can free the GString.

How do you propose to use that callback? I did not find a
documentation for it. It takes no argument (except the chr object self)
so there is no way to pass in the buffer. It cannot be replaced -
it is set in non-ui code in multiple places and never in ui code.

Thanks

Michal



[Qemu-devel] [RESEND PATCH] target-arm/abi32: check for segfault in do_kernel_trap

2017-01-02 Thread Seraphime Kirkovski
Currently, the cmpxchg implementation tests whether the destination address
is readable:
  - if it is, we read the value and continue with the comparison
  - if isn't, i.e. access to addr would segfault, we assume that src != dest
rather than queuing a SIGSEGV.

The same problem exists in the case where src == dest: the code doesn't
check whether put_user_u32 succeeds.

This fixes both problems by sending a SIGSEGV when the destination address
is inaccessible.

Signed-off-by: Seraphime Kirkovski 
---
 linux-user/main.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 75b199f..376b0c3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -503,6 +503,7 @@ do_kernel_trap(CPUARMState *env)
 uint32_t addr;
 uint32_t cpsr;
 uint32_t val;
+target_siginfo_t info;
 
 switch (env->regs[15]) {
 case 0x0fa0: /* __kernel_memory_barrier */
@@ -516,13 +517,16 @@ do_kernel_trap(CPUARMState *env)
 start_exclusive();
 cpsr = cpsr_read(env);
 addr = env->regs[2];
-/* FIXME: This should SEGV if the access fails.  */
-if (get_user_u32(val, addr))
-val = ~env->regs[0];
+if (get_user_u32(val, addr)) {
+env->exception.vaddress = addr;
+goto segv;
+}
 if (val == env->regs[0]) {
 val = env->regs[1];
-/* FIXME: Check for segfaults.  */
-put_user_u32(val, addr);
+if (put_user_u32(val, addr)) {
+env->exception.vaddress = addr;
+goto segv;
+}
 env->regs[0] = 0;
 cpsr |= CPSR_C;
 } else {
@@ -551,6 +555,16 @@ do_kernel_trap(CPUARMState *env)
 env->regs[15] = addr;
 
 return 0;
+
+segv:
+end_exclusive();
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env->exception.vaddress;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+return 0;
 }
 
 void cpu_loop(CPUARMState *env)
-- 
2.10.2




  1   2   >